Lập trình ESP32 ADC – Đọc giá trị Analog với Arduino IDE

Bài viết này hướng dẫn cách đọc tín hiệu analog input với ESP32 bằng Arduino IDE. Việc đọc tín hiệu analog rất hữu ích cho việc đọc giá trị từ các biến trở như chiết áp (potentiometer) hoặc cảm biến analog.

Đọc tín hiệu analog input với ESP32 dễ dàng bằng việc sử dụng hàm analogRead(GPIO) với đối số là GPIO mà bạn muốn đọc. 

Bạn cũng có thể tham khảo các hướng dẫn khác về cách sử dụng chân analog với board ESP: 

Analog Inputs (ADC) 

Đọc một giá trị analog với ESP32 nghĩa là bạn có thể đo được các mức điện áp khác nhau giữa 0V và 3.3V. 
 
Điện áp đo được sẽ được gán cho giá trị từ 0 đến 4095, trong đó 0V tương ứng với 0 và 3,3V tương ứng với 4095.  

ADC phi tuyến tính

Theo lý tưởng, bạn sẽ mong muốn một biểu diễn theo đường tuyến tính khi sử dụng các chân ADC của ESP32. Tuy nhiên, điều đó sẽ không xảy ra. Bạn sẽ nhận được một đường biểu diễn như biểu đồ sau: 

Xem thêm thông tin về vấn đề này: Inconsistent values when using “analogRead()” #92

Đường biểu diễn trên cho thấy ESP32 không thể phân biệt 3.3V với 3.2V. Bạn sẽ nhận được cùng một giá trị cho cả hai điện áp là 4095. 
 
Điều tương tự cũng xảy ra đối với các giá trị điện áp rất thấp: từ 0V tới 0,1V, bạn sẽ nhận được cùng một giá trị: 0. Do đó bạn cần lưu ý điều này khi sử dụng các chân ESP32 ADC.

Có một thảo luận về chủ đề này trên GitHub

Hàm analogRead() 

Việc đọc analog input với ESP32 bằng Arduino IDE cũng đơn giản như cách sử dụng hàm analogRead(), với đối số là GPIO mà bạn muốn đọc:

AnalogRead(GPIO);

ESP32 hỗ trợ các phép đo ở 18 kênh (channel) khác nhau. Chỉ có 15 channel ở board DEVKIT V1 DOIT (phiên bản có 30 GPIO).

Hãy xem sơ đồ chân ra của board ESP32 và xác định vị trí các chân ADC. Chúng được đánh dấu bằng khung màu đỏ như hình bên dưới.

Tìm hiểu thêm về ESP32 GPIO: Tham khảo Chân Ra của ESP32: Chân GPIO nào nên dùng?

Các chân analog input này có độ phân giải 12 bit. Điều này có nghĩa là khi bạn đọc một analog input, phạm vi  của nó có thể thay đổi từ 0 đến 4095.

Lưu ý: Không thể sử dụng các chân ADC2 khi sử dụng Wi-Fi. Vì vậy, nếu bạn đang sử dụng Wi-Fi và gặp sự cố khi đọc giá trị từ ADC2 GPIO, hãy cân nhắc đến việc sử dụng ADC1 GPIO để thay thế, cách này có thể khắc phục được rắc rối. 

Một số hàm khác liên quan đến sử dụng ADC trong ESP32 

Đây là một số hàm nâng cao khác dùng điều khiển chân ADC có thể hữu dụng trong nhiều dự án. 

  • analogReadResolution(resolution): set số bit lấy mẫu (sample bits) và độ phân giải (resolution). Giá trị có thể từ 9 bit (0 – 511) đến 12 bit (0 – 4095). Mặc định độ phân giải là 12-bit.
  • analogSetWidth(width): set số bit lấy mẫu (sample bits) và độ phân giải (resolution). Giá trị có thể từ 9 bit (0 – 511) đến 12 bit (0 – 4095). Mặc định độ phân giải là 12-bit.
  • analogSetCycles(cycles): set số chu kỳ trên mỗi mẫu (cycle per sample). Mặc định là 8. Range: từ 1 đến 255.
  • analogSetSamples(samples): set số mẫu trong range (samples in the range). Mặc định là 1 sample. Nó có tác dụng làm tăng độ nhạy (sensitivity).
  • analogSetClockDiv(attenuation): set bộ chia (divider) cho clock của ADC. Mặc định là 1. Range: từ 1 đến 255.
  • analogSetAttenuation(attenuation): set độ suy hao (attenuation) input cho tất cả chân ADC. Mặc định là ADC_11db. Những giá trị khác là:
    • ADC_0db: set không có độ suy hao. ADC có thể đo lên đến gần 800 mV (Input 1V = giá trị đọc ADC là 1088).
    • ADC_2_5db: Điện áp input của ADC sẽ bị suy hao, mở rộng phạm vi đo lên xấp xỉ 1100 mV. (Input 1V = giá trị đọc ADC là 3722). 
    • ADC_6db: Điện áp đầu vào của ADC sẽ bị suy hao, mở rộng phạm vi đo lên xấp xỉ 1350 mV. (Input 1V = giá trị đọc ADC là 3033). 
    • ADC_11db: Điện áp đầu vào của ADC sẽ bị suy hao, mở rộng phạm vi đo lên xấp xỉ 2600 mV. (Input 1V = giá trị đọc ADC là 1575). 
  • analogSetPinAttenuation(pin, attenuation): set độ suy giảm (attenuation) input cho chân (pin). Mặc định là ADC_11db. Các giá trị attenuation khác tương tự như hàm trên.
  • adcAttachPin(pin): Gắn (attach) một chân vào ADC (đồng thời clear mọi chế độ analog khác đang mở). Trả về kết quả TRUE hoặc FALSE.
  • adcStart(pin), adcBusy(pin)resultadcEnd(pin): bắt đầu một quá trình chuyển đổi (convert) ADC trên bus của pin đã attach. Kiểm tra quá trình convert trên chân của ADC bus đang chạy (trả về TRUE hoặc FALSE). Nhận kết quả convert: trả về số nguyên (integer) 16 bit.

Bạn có thể xem một video giải thích khá hay về cách sử dụng những hàm trên ở đây

Đọc giá trị analog từ chiết áp với ESP32. 

Chúng ta sẽ làm một ví dụ đơn giản đọc giá trị analog từ chiết áp (potentiometer). Ví dụ này cần những linh kiện sau:

Sơ đồ mạch 

Nối dây potentiometer với ESP32 của bạn. Chân ở giữa của potentiometer nên được nối với chân GPIO 34. Bạn có thể tham khảo theo sơ đồ bên dưới.

Code

Chúng ta sẽ sử dụng Arduino IDE để lập trình ESP32, nếu bạn chưa cài đặt ESP32 add-on hãy xem hướng dẫn này trước khi thực hiện tiếp:

Mở Arduino IDE  và copy đoạn code sau. 

// Potentiometer is connected to GPIO 34 (Analog ADC1_CH6) 
const int potPin = 34;

// variable for storing the potentiometer value
int potValue = 0;

void setup() {
  Serial.begin(115200);
  delay(1000);
}

void loop() {
  // Reading potentiometer value
  potValue = analogRead(potPin);
  Serial.println(potValue);
  delay(500);
}

Phân tích code trên: 

Nhìn chung đoạn code trên chỉ đơn giản là đọc các giá trị từ potentiometer và in ra Serial Monitor. Trong code, bạn bắt đầu với define GPIO mà potentionmeter được kết nối. Trong ví dụ này sử dụng GPIO 34. 

const int potPin = 34;

Trong hàm setup(), khởi tạo giao tiếp serial với baud rate là 115200.

Serial.begin(115200);

Trong vòng lặp loop(), sử dụng hàm analogRead() để đọc analog input từ potPin

PotValue = analogRead(potPin); 

Cuối cùng, in các giá trị đọc từ potentiometer ra Serial Monitor. 

Serial.println(potValue);

Tới đây, upload code cho ESP32. Kiểm tra xem đã chọn đúng board và cổng COM trong menu Tools. 

Kiểm tra Example

Sau khi upload code lên, nhấn nút reset trên ESP32, mở Serial Monitor với baud rate 115200. Xoay biến trở (potentiometer) và xem giá trị thay đổi.

Giá trị lớn nhất là 4095 và giá trị nhỏ nhất là 0. 

Video

Bạn có thể xem video hướng dẫn ở đây

Tổng kết

Trong bài viết này, bạn đã học cách đọc analog input bằng cách sử dụng ESP32 với Arduino IDE. Những điểm quan trọng bạn cần lưu ý:

  • Board mạch ESP32 DEVKIT V1 DOIT (phiên bản 30 chân) có 15 chân ADC mà bạn có thể sử dụng đọc analog input.
  • Các chân này có độ phân giải 12 bit, nghĩa là bạn có thể nhận các giá trị từ 0 đến 4095.
  • Để đọc một giá trị trong Arduino IDE, sử dụng hàm analogRead().
  • Các chân ADC của ESP32 cho giá trị không theo hàm tuyến tính. Có thể bạn sẽ không phân biệt được giữa 0V và 0.1V hoặc giữa 3,2V và 3,3V. Bạn cần lưu ý điều này khi sử dụng các chân ADC.

Hy vọng bài hướng dẫn này hữu ích với bạn. Nếu bạn muốn tìm hiểu thêm về ESP32, hãy thử đăng ký khóa học: Learn ESP32 with Arduino IDE.

Bạn cũng có thể tham khảo thêm nhiều hướng dẫn khác dưới đây: 

Icons made by Freepik from www.flaticon.com