3.2 ADC - Analog Input
Last updated
Last updated
Earlier, we introduced the PWM to output different voltage values like analog signal output. What if ESP32 needs to detect external analog input signals? This is the ADC that we will learn in this lesson. The ADC converts the analog signal into a digital signal for ESP32 to process.
Analog signals are continuous in time and amplitude, while digital signals are discrete in time and amplitude. Analog circuits are circuits that use and process analog signals; digital circuits are circuits that use and process digital signals.
Many sensors' output is analog. To interface it with MCU, we need to convert it into a digital signal.
ADC (Analog to Digital converter) is used to converts an analog signal into digital, so it can be processed by the microcontroller.
ADC is used in many IoT applications like Biometric applications, Sensor monitoring, Gas leakage detection, etc.
ADC (Analog to Digital Converter) is an analog-to-digital converter that can convert analog signals into digital signals. Since the microcontroller can only recognize binary numbers, external analog signals are often converted into digital signals through ADC first. A common way is to convert changing voltage into digital signals.
ESP32-S3 integrates two 12-bit SAR ADCs and supports measurements on 20 channels (analog-enabled pins), which can be used to read analog signals in the range 0-3.3V. It has a 12-bit ADC means it will give digital values in the range of 0 – 4096 (2^12). This is called resolution which indicates the number of discrete values it can produce over the range of analog values.
Here’s a list of the parts to you need to build the circuit:
ESP32-S3-N16R8
LED
330 - 1k Ohm resistor
Potentiometer
Breadboard
Jumper wires
Wire a potentiometer to your ESP32. The potentiometer middle pin should be connected to GPIO 9 and LED is connected to GPIO 13. You can use the following schematic diagram as a reference.
analogRead (pin)
This function is used to read analog values from a specified analog pin.
pin - number of the analog pin which we want to read
returns - digital value 0 – 4095
analogReference (type)
This function is used for configuring the reference voltage used for analog input.
Let’s write a program to read varying analog values generated by a potentiometer that is connected to the pin_9 analog channel ADC2_8. Display the digital value on the Serial monitor which we got from the ESP32 ADC.
We can use analogRead() to read the analog value passed in by the potentiometer, the range is 0 ~ 4023, and the parameter range we want to input to analogWrite() is 0 ~ 255, so we also need to convert the analog value range read into the output range, the code is as follows:
There are other more advanced functions to use with the ADC pins that can be useful in other projects After opening the esp32_hal_adc.h file, we can see all the control functions of ADC:
analogReadResolution(resolution): set the sample bits and resolution. It can be a value between 9 (0 – 511) and 12 bits (0 – 4095). Default is 12-bit resolution.
analogSetWidth(width): set the sample bits and resolution. It can be a value between 9 (0 – 511) and 12 bits (0 – 4095). Default is 12-bit resolution.
analogSetCycles(cycles): set the number of cycles per sample. Default is 8. Range: 1 to 255.
analogSetSamples(samples): set the number of samples in the range. Default is 1 sample. It has an effect of increasing sensitivity.
analogSetClockDiv(attenuation): set the divider for the ADC clock. Default is 1. Range: 1 to 255.
analogSetAttenuation(attenuation): sets the input attenuation for all ADC pins. Default is ADC_11db. Accepted values:
ADC_0db: sets no attenuation. ADC can measure up to approximately 800 mV (1V input = ADC reading of 1088).
ADC_2_5db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. (1V input = ADC reading of 3722).
ADC_6db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1350 mV. (1V input = ADC reading of 3033).
ADC_11db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 2600 mV. (1V input = ADC reading of 1575).
analogSetPinAttenuation(pin, attenuation): sets the input attenuation for the specified pin. The default is ADC_11db. Attenuation values are the same from previous function.
adcAttachPin(pin): Attach a pin to ADC (also clears any other analog mode that could be on). Returns TRUE or FALSE result.
adcStart(pin), adcBusy(pin) and resultadcEnd(pin): starts an ADC convertion on attached pin’s bus. Check if conversion on the pin’s ADC bus is currently running (returns TRUE or FALSE). Get the result of the conversion: returns 16-bit integer.
In this example you’ve learned how to read analog inputs using the ESP32-S3 with the PlatformIO IDE.
The ESP32-S3 has 20 ADC pins you can use to read analog inputs.
These pins have a resolution of 12 bits, which means you can get values from 0 to 4095.
To read a value, you simply use the analogRead() function.
The ESP32 ADC pins don’t have a linear behavior. You’ll probably won’t be able to distinguish between 0 and 0.1V, or between 3.2 and 3.3V. You need to keep that in mind when using the ADC pins.
Finally, if you want to learn more about other controllers, take a look at our Youtube channel: