Độ phân giải ADC, ENOB và nhiễu: ADC 12 bit của ESP32 dùng được bao nhiêu bit, khi nào đủ

Độ phân giải ADC và LSB, nhiễu, số bit hiệu dụng ENOB và bit không nhiễu, ADC 12 bit ESP32 thực tế dùng được bao nhiêu bit, lấy trung bình tăng bit, khi nào cần ADS1115, HX711; có code đo nhiễu.

Độ phân giải ADC (số bit) cho biết bộ chuyển đổi chia dải đo thành bao nhiêu mức, nhưng không cho biết bao nhiêu bit thật sự dùng được: nhiễu, sai số tuyến tính, điện áp tham chiếu lấy mất một phần. Bài này giải thích LSB, độ phân giải, số bit hiệu dụng (ENOB), bit không nhiễu, vì sao ADC 12 bit của ESP32 thường chỉ dùng được khoảng 9–10 bit khi đọc từng mẫu, cách tăng bit bằng lấy trung bình, khi nào cần ADC ngoài, kèm chương trình ESP32 tự đo nhiễu ADC trên mạch của bạn.

1. Độ phân giải và LSB

Bảng độ phân giải ADC ở dải 3,3 V: 8 bit 256 mức 12,9 mV, 10 bit 1024 mức 3,22 mV, 12 bit 4096 mức 806 µV, 16 bit 50,4 µV, 24 bit 0,197 µV
Một bước (LSB) của ADC theo số bit, dải đo 3,3 V.

ADC N bit chia dải đo thành 2N mức. Một bước nhỏ nhất (LSB, bit có trọng số thấp nhất) bằng dải đo chia 2N: ADC 12 bit với dải 3,3 V có LSB khoảng 0,8 mV. Đây là độ phân giải, tức bước nhỏ nhất ADC có thể báo; độ chính xác (số đọc gần giá trị thật bao nhiêu) là chuyện khác, phụ thuộc điện áp tham chiếu, sai số độ lợi, sai số lệch không và độ phi tuyến.

2. Nhiễu: vì sao số đọc nhảy khi điện áp đứng yên

Biểu đồ phân bố 256 số đọc ADC của một điện áp không đổi: đọc từng mẫu trải rộng khoảng 20 LSB với lệch chuẩn 3,59 LSB; trung bình 16 mẫu hẹp lại với lệch chuẩn 0,95 LSB
Mô phỏng số đọc của một điện áp đứng yên có nhiễu.

Nhiễu đến từ chính bộ ADC, nguồn cấp, mạch số chạy bên cạnh (Wi-Fi, CPU), dây tín hiệu dài. Kết quả là số đọc của một điện áp không đổi vẫn trải ra một khoảng. Đo độ rộng đó bằng độ lệch chuẩn σ tính theo LSB, rồi suy ra:

  • Số bit hiệu dụng (effective resolution) = log2(2N / σ): bao nhiêu bit còn lại khi tính nhiễu theo giá trị hiệu dụng.
  • Số bit không nhiễu (noise-free) = log2(2N / (6,6 σ)): bao nhiêu bit hiện ổn định trên màn hình, không nhảy, vì hầu hết số đọc nằm trong khoảng ±3,3 σ.

Datasheet ADC còn dùng ENOB (Effective Number Of Bits) tính từ tỉ số tín hiệu trên nhiễu và méo khi đo sóng sin: ENOB = (SINAD − 1,76 dB) / 6,02. Ý nghĩa giống nhau: số bit của một ADC lý tưởng có cùng mức nhiễu.

3. ADC của ESP32 thực tế dùng được bao nhiêu bit

ADC SAR 12 bit trong ESP32 (dòng chip gốc) khá nhiễu, độ lệch chuẩn vài LSB tùy mạch, nên đọc từng mẫu thường chỉ còn khoảng 9–10 bit hiệu dụng, và số bit không nhiễu còn ít hơn. Ngoài nhiễu, ADC ESP32 còn phi tuyến ở hai đầu dải đo (gần 0 V và gần 3,1 V ở mức suy giảm 11 dB). Dùng analogReadMilliVolts() để thư viện áp hiệu chuẩn có sẵn trong chip, và giữ điện áp đo ở khoảng giữa dải. Cách đọc ADC, chọn cầu chia áp có ở bài đọc ADC trên ESP32 và đo điện áp pin 18650.

4. Lấy trung bình để tăng số bit dùng được

Biểu đồ cột bit hiệu dụng và bit không nhiễu khi lấy trung bình 1, 4, 16, 64 mẫu: 10,2 và 7,4; 11,1 và 8,4; 12,1 và 9,4; 13,2 và 10,5 bit
Mỗi lần tăng số mẫu lên 4, nhiễu giảm một nửa, thêm khoảng 1 bit (mô phỏng).

Nếu nhiễu ngẫu nhiên, trung bình M mẫu giảm độ lệch chuẩn đi √M lần: 4 mẫu giảm một nửa (thêm 1 bit), 16 mẫu thêm 2 bit, 64 mẫu thêm 3 bit. Đổi lại, tốc độ lấy mẫu giảm M lần. Giới hạn:

  • Lấy trung bình không sửa được sai số hệ thống: phi tuyến, sai độ lợi, điện áp tham chiếu lệch vẫn còn nguyên.
  • Nhiễu có chu kỳ (từ nguồn xung, PWM, điện lưới) không giảm theo √M nếu thời gian lấy mẫu trùng nhịp với nhiễu; lọc chống chồng phổ trước ADC vẫn cần. Phần này có ở bài aliasing và bộ lọc chống chồng phổ cùng cụm chủ đề.
  • Tụ 100 nF từ chân ADC xuống GND đặt sát chip giảm nhiễu đáng kể với nguồn tín hiệu trở kháng cao như cầu chia áp.

5. ADC 12 bit có đủ không

Bảng ứng dụng: đo pin 18650, nhiệt độ NTC, biến trở đủ với ADC ESP32; đo dòng qua shunt nhỏ cần INA219 hoặc ADS1115; load cell cần HX711 24 bit; âm thanh chất lượng cao cần micro I2S
So yêu cầu của phép đo với số bit dùng được.

Cách tính nhanh: lấy dải đo chia cho thay đổi nhỏ nhất cần phân biệt, rồi lấy log2. Ví dụ đo 0–3,3 V cần phân biệt 5 mV: 3300 / 5 = 660 mức, khoảng 9,4 bit, ADC ESP32 đủ nếu lấy trung bình vài mẫu. Đo tín hiệu vài µV của load cell thì cần HX711 24 bit; đo điện áp chính xác hơn, vi sai, có khuếch đại thì dùng ADS1115 16 bit.

6. Chương trình ESP32 đo nhiễu ADC trên mạch của bạn

Nối GPIO34 vào điểm giữa cầu chia hai điện trở 10 kΩ từ 3V3 xuống GND, thêm tụ 100 nF từ GPIO34 xuống GND. Chương trình đọc 256 giá trị ở mỗi mức lấy trung bình 1, 4, 16, 64 mẫu, tính độ lệch chuẩn, khoảng min–max, số bit hiệu dụng, số bit không nhiễu theo công thức ở mục 2. Chỉ dùng gói esp32 cho Arduino IDE.

// PYWORLD.VN - Đo nhiễu ADC của ESP32 trên một điện áp đứng yên: độ lệch chuẩn (LSB), số bit hiệu dụng, số bit không nhiễu
// PYWORLD.VN - So sánh khi lấy trung bình 1, 4, 16, 64 mẫu; GPIO34 nối điểm giữa cầu chia 10k/10k từ 3V3, thêm tụ 100 nF xuống GND
// PYWORLD.VN - Bit hiệu dụng = log2(4096 / độ lệch chuẩn); bit không nhiễu = log2(4096 / (6,6 x độ lệch chuẩn))

#include <math.h>

const int CHAN_ADC = 34;
const int SO_DIEM = 256;            // số giá trị (đã lấy trung bình) dùng để tính thống kê
const int CAC_MUC_TB[] = {1, 4, 16, 64};
const float THANG = 4096.0f;        // ADC 12 bit

float giaTri[SO_DIEM];

float docTrungBinh(int soMau) {
  uint32_t tong = 0;
  for (int i = 0; i < soMau; i++) {
    tong += analogRead(CHAN_ADC);
  }
  return (float)tong / soMau;
}

void doMotMuc(int soMau) {
  double tong = 0;
  for (int i = 0; i < SO_DIEM; i++) {
    giaTri[i] = docTrungBinh(soMau);
    tong += giaTri[i];
  }
  double tb = tong / SO_DIEM;
  double tongBp = 0;
  float nhoNhat = giaTri[0];
  float lonNhat = giaTri[0];
  for (int i = 0; i < SO_DIEM; i++) {
    tongBp += (giaTri[i] - tb) * (giaTri[i] - tb);
    nhoNhat = min(nhoNhat, giaTri[i]);
    lonNhat = max(lonNhat, giaTri[i]);
  }
  double doLech = sqrt(tongBp / (SO_DIEM - 1));
  if (doLech < 0.01) {
    doLech = 0.01;                  // tránh chia cho 0 khi mọi giá trị trùng nhau
  }
  double bitHieuDung = log2(THANG / doLech);
  double bitKhongNhieu = log2(THANG / (6.6 * doLech));
  Serial.printf("TB %2d mau: trung binh %7.1f | lech chuan %5.2f LSB | min-max %6.1f | %4.1f bit hieu dung | %4.1f bit khong nhieu\n",
                soMau, tb, doLech, lonNhat - nhoNhat, bitHieuDung, bitKhongNhieu);
}

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);
  analogSetPinAttenuation(CHAN_ADC, ADC_11db);   // dải đo khoảng 0..3,1 V
  delay(500);
  Serial.println("Do nhieu ADC tren GPIO34 (giu nguyen dien ap vao)");
}

void loop() {
  uint32_t mv = 0;
  for (int i = 0; i < 64; i++) {
    mv += analogReadMilliVolts(CHAN_ADC);
  }
  Serial.printf("Dien ap vao khoang %u mV\n", (unsigned)(mv / 64));
  for (int k = 0; k < 4; k++) {
    doMotMuc(CAC_MUC_TB[k]);
  }
  Serial.println();
  delay(5000);
}
Serial Monitor in điện áp vào khoảng 1650 mV và bốn dòng thống kê cho trung bình 1, 4, 16, 64 mẫu: lệch chuẩn 3,59, 1,86, 0,95, 0,43 LSB; bit hiệu dụng 10,2 đến 13,2
Dạng kết quả (số liệu mô phỏng; mạch thật cho số khác).

Dùng chương trình này để so sánh: tháo tụ 100 nF, cấp nguồn bằng cáp USB khác, bật Wi-Fi, chạy relay bên cạnh, rồi xem độ lệch chuẩn thay đổi thế nào. Đó là cách nhanh nhất để biết cải tiến mạch nào có tác dụng.

7. Lỗi hay gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
Số đọc nhảy vài chục LSBnguồn tín hiệu trở kháng cao, không có tụ, dây dàitụ 100 nF tại chân ADC, dây ngắn, lấy trung bình
Đọc sai ở gần 0 V hoặc gần 3,3 Vvùng phi tuyến của ADC ESP32chỉnh cầu chia để điện áp nằm giữa dải
Số đọc thay đổi khi bật Wi-Finhiễu nguồn khi phát sóng; ADC2 không dùng được khi bật Wi-Fidùng chân ADC1 (GPIO32–39), tụ nguồn tốt
Trung bình nhiều mẫu vẫn lệch giá trị thậtsai số hệ thống, không phải nhiễuhiệu chuẩn hai điểm với đồng hồ đo

8. Xem thêm

Tần số lấy mẫu cần bao nhiêu, xem bài định lý lấy mẫu Nyquist cùng cụm chủ đề.


Tin tức liên quan

Cảm biến gia tốc: cấu tạo MEMS răng lược, áp điện, cách chế tạo và đo góc nghiêng bằng ESP32
Cảm biến gia tốc: cấu tạo MEMS răng lược, áp điện, cách chế tạo và đo góc nghiêng bằng ESP32

Cảm biến gia tốc hoạt động thế nào: mô hình khối lượng – lò xo, MEMS răng lược điện dung vi sai, chế tạo vi cơ bề mặt, áp điện, servo, đo góc nghiêng và đọc MPU-6050 bằng ESP32.

Đồ án ESP32, Arduino cho sinh viên: chọn đề tài, linh kiện, nguồn, hộp và lỗi hay gặp khi bảo vệ
Đồ án ESP32, Arduino cho sinh viên: chọn đề tài, linh kiện, nguồn, hộp và lỗi hay gặp khi bảo vệ

Làm đồ án ESP32, Arduino cho sinh viên: dựng sơ đồ khối, gợi ý đề tài theo độ khó, chọn linh kiện, kế hoạch theo tuần, nguồn, hộp và các lỗi hay gặp khi bảo vệ.

Cảm biến ánh sáng: quang trở, photodiode, BH1750 – cấu tạo, nguyên lý, chế tạo và đo lux bằng ESP32
Cảm biến ánh sáng: quang trở, photodiode, BH1750 – cấu tạo, nguyên lý, chế tạo và đo lux bằng ESP32

Cảm biến ánh sáng hoạt động thế nào: độ rọi và lux, quang trở CdS, photodiode, phototransistor, cảm biến số BH1750, cách chế tạo và đo lux bằng BH1750, quang trở với ESP32.

Scratch là gì? Bắt đầu với ScratchJr và Scratch cho học sinh lớp 4–5
Scratch là gì? Bắt đầu với ScratchJr và Scratch cho học sinh lớp 4–5

Scratch là gì, khác ScratchJr thế nào, cách dùng trên trình duyệt hoặc cài trên máy, năm vùng màn hình làm việc, chương trình đầu tiên và năm bài tập cho học sinh lớp 4–5.

Chuẩn rung: hiệu chuẩn gia tốc kế bằng giao thoa laser và so sánh theo ISO 16063, đáp ứng tần số
Chuẩn rung: hiệu chuẩn gia tốc kế bằng giao thoa laser và so sánh theo ISO 16063, đáp ứng tần số

Hiệu chuẩn gia tốc kế theo ISO 16063: dịch chuyển, vận tốc, gia tốc theo tần số, phương pháp giao thoa laser và so sánh lưng tựa lưng, đọc đáp ứng tần số và chuỗi liên kết chuẩn rung.

Đầu nối JST XH2.54, PH2.0, SM và dây RCY: phân biệt bằng bước chân, chọn loại, nối dây và cực tính
Đầu nối JST XH2.54, PH2.0, SM và dây RCY: phân biệt bằng bước chân, chọn loại, nối dây và cực tính

Phân biệt đầu nối JST XH 2,5 mm, PH 2,0 mm, ZH, SH, SM và RCY bằng bước chân; dòng mỗi chân, cấu tạo, chân số 1, nối dây không cần kìm bấm và đo cực tính trước khi cắm pin.

LittleFS trên ESP32: lưu file trong flash, ghi log CSV xoay vòng và phục vụ trang web qua Wi-Fi
LittleFS trên ESP32: lưu file trong flash, ghi log CSV xoay vòng và phục vụ trang web qua Wi-Fi

LittleFS nằm ở đâu trong flash ESP32, khác Preferences và thẻ nhớ thế nào, đọc ghi file, ghi log CSV xoay vòng để flash bền, phục vụ trang web và file log từ LittleFS.

I2C là gì: START, STOP, địa chỉ, ACK và cách đọc ghi thanh ghi trên ESP32
I2C là gì: START, STOP, địa chỉ, ACK và cách đọc ghi thanh ghi trên ESP32

Giải thích giao tiếp I2C ở mức từng bit: hai dây SDA, SCL, điện trở kéo lên, START, địa chỉ, ACK, STOP. Kèm hai chương trình ESP32: tự tạo tín hiệu I2C bằng GPIO và đọc ghi thanh ghi bằng Wire.


Bình luận
Đã thêm vào giỏ hàng