9. ADC
9.1 What is ADC
ADC stands for Analog-to-Digital Converter. It is a converter used to convert analog signals into digital signals. We know that analog signals are continuous, and their values can vary arbitrarily within a certain range, such as sound and light signals. Digital signals are discrete binary signals, such as the 0 and 1 data in a computer, and can only take a finite number of values.
The working principle of an ADC is to convert analog signals into discrete digital signals through sampling, and then through quantization, encoding, and other processing, finally obtaining the corresponding digital representation. The higher the ADC sampling frequency, the closer the obtained digital signal is to the original analog signal, that is, the higher the fidelity, but this requires more resources and computational power.
ADC is usually used to read analog signals from external analog sensors and convert them into digital signals for processing by embedded systems or computers, such as measuring physical quantities like temperature, humidity, and pressure.
9.2 Introduction to the ESP32S3 ADC
The ESP32-S3 integrates two 12-bit SAR ADCs, supporting a total of 20 analog channel inputs. It can measure analog signals from up to 20 pins as well as internal signals such as internal voltage. To achieve lower power consumption, the ULP coprocessor of the ESP32-S3 can also measure voltage in sleep mode. In this case, the CPU can be woken up by setting a threshold or other trigger methods.
The voltage range that the ADC can convert is determined by VREF. For the ESP32-S3, it is usually 0 to 3.3V, and the dev board is set to 3.3V. However, note that the maximum rated input voltage of the ESP32 may vary slightly. It is very important to check the specific information in the corresponding datasheet. It is usually recommended to use the Attenuation function or additional hardware such as a voltage divider to ensure the input voltage is within the specified range.
The ESP32-S3 also has a built-in temperature sensor that generates a voltage that varies with temperature. The internal ADC converts the sensor voltage into a digital value. The measurement range of the temperature sensor is –20 °C to 110 °C. The temperature sensor is suitable for monitoring changes in the chip's internal temperature, which will vary with the microcontroller's clock frequency or IO load. Generally, the chip's internal temperature is higher than the external temperature.
The pins that support ADC acquisition are as follows:
9.3 Basic Parameters of ADC
The basic parameters of an ADC usually include the following:
- Resolution: Refers to the number of bits in the ADC's digital output, also known as the quantization bits. For example, a 12-bit ADC has 4096 discrete digital outputs.
- Sampling rate: Refers to the maximum rate at which the ADC can sample. For the ESP32-S3, the maximum sampling rate is 2.5 MS/s.
- Input range: Refers to the voltage range of the input signal that the ADC can measure. For the ESP32-S3, the input range is 0-3.3V.
- Noise: Refers to the effect of resolution error and interference during ADC acquisition. The smaller the noise, the more accurate the ADC measurement result.
- Stability: Refers to the stability of the ADC output. An ADC with good stability has small output variations and more accurate measurement results.
9.4 ADC Usage Process
The process of using the ESP32's ADC (Analog-to-Digital Converter) function in MicroPython is as follows:
- Import the relevant modules and libraries
from machine import ADC- Initialize the ADC object
adc = ADC(machine.Pin(pin_number))Where pin_number is the pin number connected to the ESP32.
- Configure the ADC reference voltage and resolution (optional step)
# Set the reference voltage, default is 3.3V (using 11dB attenuation)
adc.atten(adc.ATTENUATION_11DB)
# Set the resolution, default is 12-bit (0-4095)
# adc.width(ADC.WIDTH_12BIT)2
3
4
5
6
You can use the atten() method to set the ADC's reference voltage, which defaults to 3.3V.
To read voltages above the reference voltage, use the atten keyword argument to apply input attenuation. Valid values (and approximate linear measurement ranges) are:
- ADC.ATTN_0DB: No attenuation (100mV-950mV)
- ADC.ATTN_2_5DB: 2.5dB attenuation (100mV-1250mV)
- ADC.ATTN_6DB: 6dB attenuation (150mV-1750mV)
- ADC.ATTN_11DB: 11dB attenuation (150mV-2450mV)
You can use the width() method to set the resolution of the ADC measurement result, which defaults to 12-bit (0-4095).
For compatibility, the ADC object also provides constants matching the supported ADC resolutions:
- ADC.WIDTH_9BIT = 9
- ADC.WIDTH_10BIT = 10
- ADC.WIDTH_11BIT = 11
- ADC.WIDTH_12BIT = 12
- Read the ADC value:
adc_value = adc.read()
b2
Use the read() method to read the current measurement value from the ADC. This method returns the raw ADC value according to the set resolution range, for example, 0-4095 for 12-bit resolution, representing the measurement result. 5. Turn off the ADC:
adc.deinit()When you no longer need to use the ADC, you can close the ADC by calling the deinit() method.
Note the following points:
- Depending on the specific hardware, only GPIO1 to GPIO20 support the ADC function.
- The range and precision of ADC measurement values depend on the reference voltage and resolution settings. You can make appropriate settings according to your needs.
- If you need to continuously read ADC values, you can use the read_timed() method to read ADC values at fixed intervals.
For other methods, please refer to the official MicroPython documentation:
http://www.86x.org/en/latet/esp32/quickref.html#adc-analog-to-digital-conversion
9.5 Hardware Connection and Preparation
This example uses GPIO1 as the ADC read pin to test the external voltage through GPIO1, and then uses the onboard serial port 0 to print out the value read by the ADC and convert it to the actual voltage for display.
9.6 ADC Verification
import time
from machine import Pin, ADC
adc_in = Pin(1, Pin.IN)
# Create an ADC object on the GPIO1 pin
adc = ADC(adc_in)
# Configure the attenuator, set the measurement range to 3.3V
adc.atten(ADC.ATTN_11DB)
while True:
print(f'adc:{adc.read()}')
time.sleep(0.1)2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
We can right-click in the shell console and select Show Plotter. It can visualize the numbers output in the shell, so that we can see the ADC's graphical changes: