Essential ESP32 ADC Basics: Analog-to-Digital Converter Explained

by AKP in Circuits > Arduino

150 Views, 0 Favorites, 0 Comments

Essential ESP32 ADC Basics: Analog-to-Digital Converter Explained

esp32-basics-adc.jpg

This article, part of our ESP32 Basics series, illustrates the process of reading analog values with the ESP32 using the Arduino IDE.

The ability to read analog values is particularly valuable when working with a diverse range of sensors and variable components. Examples include trimpots, joysticks, sliders, and force-sensitive resistors, among others.

ESP32 ADC Pins

ESP32-ADC-Pins.png

The ESP32 is equipped with two 12-bit SAR (Successive Approximation Register) ADCs: ADC1 and ADC2. These ADCs support measurements on a total of 18 channels, referred to as analog-enabled pins. ADC1 can be accessed via eight GPIOs, specifically GPIOs 32 to 39, while ADC2 is available on ten GPIOs: GPIOs 0, 2, 4, and 12 to 15, as well as GPIOs 25 to 27.

However, it’s important to note that the DEVKIT V1 DOIT board, which has 30 GPIOs, only provides 15 ADC channels, as depicted in the figure below.The ESP32 is equipped with two 12-bit SAR (Successive Approximation Register) ADCs: ADC1 and ADC2. These ADCs support measurements on a total of 18 channels, referred to as analog-enabled pins. ADC1 can be accessed via eight GPIOs, specifically GPIOs 32 to 39, while ADC2 is available on ten GPIOs: GPIOs 0, 2, 4, and 12 to 15, as well as GPIOs 25 to 27.

However, it’s important to note that the DEVKIT V1 DOIT board, which has 30 GPIOs, only provides 15 ADC channels, as depicted in the figure below.

The ADC integrated into the ESP32 features a 12-bit resolution, allowing it to detect 4096 discrete analog levels. In simpler terms, it converts input voltages ranging from 0 to 3.3V (the operating voltage) into integer values ranging from 0 to 4095. Consequently, this results in a resolution of 3.3 volts divided by 4096 units, which equals 0.0008 volts (0.8 mV) per unit.

Additionally, the ADC resolution and channel range can be adjusted programmatically to meet specific requirements.

Limitations of the ESP32’s ADC

While the ESP32 offers many capabilities, it’s important to be aware of certain limitations when it comes to its ADC functionality. Here are some key points to consider:

Unusable When WiFi Is Enabled

When Wi-Fi is enabled on the ESP32, the ADC2 pins become unavailable for use. Given the high likelihood of Wi-Fi usage in microcontroller applications, it restricts the ADC functionality to ADC1 only.

ADC Input Range

The ADC on the ESP32 can measure voltages within the range of 0 to 3.3V. It is not capable of directly measuring analog voltages between 0V and 5V. This limitation should be taken into account when designing your circuits.

ADC Accuracy

ESP32-ADC-Nonlinearity.jpg

While one might expect linear behavior from the ADC, the ADC converters on the ESP32 are inherently non-linear. This means that the measured values may not follow a straight line as expected. Detailed information and discussions about this non-linearity can be found on platforms like GitHub.

The graph below illustrates the non-linearities at the lower and upper ends of the input voltage range.

As a result, the ESP32 cannot distinguish between voltages very close to each other. For instance, it cannot differentiate between 3.2V and 3.3V; the measured value will be the same (4095). Similarly, it cannot distinguish between 0V and 0.13V signals; the measured value will be the same (0).

Electrical Noise

ESP32-ADC-Electrical-Noise.jpg

The ADC of the ESP32 is susceptible to electrical noise, which can introduce slight fluctuations in measurements. To mitigate this, techniques such as adding a capacitor at the output and oversampling can be employed to improve accuracy and reduce noise.

It’s essential to consider these limitations when working with the ESP32’s ADC to ensure accurate and reliable measurements.

The AnalogRead() Function

Obtaining analog values from a GPIO pin is a simple process. In the Arduino IDE, you can utilize the analogRead() function, which takes the GPIO pin number you wish to read as an argument.

To read an analog value from a GPIO pin, use the following syntax:

analogRead(GPIO);

Reading a Potentiometer

Wiring-Potentiometer-to-ESP32-ADC.jpg

To demonstrate how to utilize the ADC on the ESP32, we will present a simple example that involves reading an analog value from a potentiometer.

Hardware Setup

Let’s set up a basic circuit using a potentiometer for this example.

Begin by inserting the potentiometer into your breadboard. Connect the middle pin of the potentiometer to GPIO 34 on your ESP32. Then, connect one of the outer pins of the potentiometer (it doesn’t matter which one) to the 3V3 pin of the ESP32, and connect the other outer pin to the ground.

Example Code

ESP32-ADC-Output.jpg

Upload the following code to your ESP32. This code reads the potentiometer’s value and prints the results to the Serial Monitor.

// 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.print("Analog value: ");
Serial.println(potValue);
delay(500);
}

Once you have uploaded the sketch, open the Serial Monitor with a baud rate of 115200 and press the EN button on the ESP32.

You should observe a value between 0 and 4095, depending on the current position of the potentiometer’s knob, being displayed in the Serial Monitor. Try rotating the knob on the potentiometer to observe how the values change.Once you have uploaded the sketch, open the Serial Monitor with a baud rate of 115200 and press the EN button on the ESP32.

You should observe a value between 0 and 4095, depending on the current position of the potentiometer’s knob, being displayed in the Serial Monitor. Try rotating the knob on the potentiometer to observe how the values change.

See Full Article Here