Measure analog voltage on ESP32 with ADC
The ADC (Analog to Digital Converter) allows, as its name suggests, to convert an analog voltage into a binary value.
There are 2 12-bit ADCs on ESP32, ADC1 with 8 channels and ADC2 with 10 channels. Each ADC channel allows a measurement to be done on a pin.
ADC limitation on the ESP32
ADC is not a strong point of the ESP32 because it has many flaws. Prefer that the Arduino or use an external ADC if you want to make reliable measurements.
Warning
As strange as it sounds, the Arduino’s 10-bit (1024 values) ADC is more accurate and reliable than the 12-bit ESP32 (4096 values) ADC.
- The ESP32 ADC has several flaws:
-
-
ADC2 cannot be used with enabled WiFi since it is used internally by the WiFi driver. Since there is a good chance of using WiFi on a microcontroller designed to use it, only the ADC1 and its 8 channels can be used.
-
The ADC can only measure a voltage between 0 and 3.3V. You cannot directly measure analog voltages between 0 and 5V.
-
Non-linearity:
The ADC of the ESP32 is not very linear (the response curve of the ADC is not a linear straight line), especially at the ends of its use range (towards 0V and 3.3V)
Basically, this means that the ESP32 cannot distinguish a signal of 3.2V and 3.3V: the measured value will be the same (4095). Likewise, for small voltages, the ESP32 will not differentiate between a 0V and 0.2V signal.
Note
It is possible to calibrate the ADC to reduce this linearity flaw. An example is available here
-
-
The electrical noise of the ADC implies a slight fluctuation of the measurements:
Here too, it is possible to try to “correct” this defect by adding a capacitor at the output and with oversampling:
Usage
The basic use of the ESP32 ADC is the same as on the Arduino with the function
analogRead()
-
To read the voltage of the VP pin (GPIO36) of the ESP32:
pinMode(36, INPUT); //Il faut déclarer le pin en entrée analogRead(36);
Note
There are also more advanced functions.
-
To change the ADC resolution:
analogReadResolution (resolution) // Resolution between 9-12 bits
Project
We will test the ADC using a potentiometer (variable resistor).
Schematic
Try to write the program by yourself!
Solution
// Le potentiomètre est connecté au GPIO 36 (Pin VP)
const int potPin = 36;
// Valeur du potentiomètre
int potValue = 0;
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(potPin,INPUT_PULLUP);
}
void loop() {
// Mesure la valeur du potentiomètre
potValue = analogRead(potPin);
Serial.println(potValue);
delay(250);
}
When we turn the potentiometer, we get:
0
0
0
400
400
400
401
460
496
569
688
934
1232
1424
1461
1735
2300
2719
3007
3551
3859
3903
3903
4095
4095
4095
4095