ESP32 ADC
### What is an ADC? **_Analog-to-Digital Conversion (ADC)_** **is the process of converting an analog voltage signal into a digital value that can be processed by a microcontroller. The ESP32's ADC allows it to interface with various analog sensors, converting their continuous signals into digital v

#What is an ADC?
Analog-to-Digital Conversion (ADC) is the process of converting an analog voltage signal into a digital value that can be processed by a microcontroller. The ESP32's ADC allows it to interface with various analog sensors, converting their continuous signals into digital values ranging from 0 to a specified resolution (e.g., 12-bit resolution gives a range of 0 to 4095).
Imagine you have a dimmer switch at home that lets you control the brightness of a light bulb. When you twist the knob, you’re adjusting how much electricity flows to the bulb, making it brighter or dimmer. Now, what if you wanted to tell a computer exactly how bright the light is? This is where something called an Analog-to-Digital Converter (ADC) comes in.
In simple terms, an ADC is like a translator for your computer or microcontroller (like the ESP32). It takes an analog signal—something that can have any value within a range, like the voltage coming from your dimmer switch—and converts it into a digital number that the computer can understand.
For example, let’s say you have a sensor that measures temperature, and it outputs a varying voltage based on the temperature it senses. The ADC in the ESP32 reads this voltage and converts it into a number between 0 and 4095. The exact number depends on how high or low the voltage is, giving your ESP32 a way to understand and process the temperature data.
#Introduction to ADC on ESP32
The ESP32 is equipped with two ADCs: ADC1 and ADC2, each having multiple channels. These ADCs can read analog voltages on the GPIO pins and convert them into a digital value ranging from 0 to 4095, corresponding to the input voltage (typically 0 to 3.3V). However, the ADC2 is shared with other peripherals like Wi-Fi, so it’s generally recommended to use ADC1 to avoid conflicts.
#Hardware and Requirements
- ESP32 Development Board
- Potentiometer (e.g., 10kΩ)
- Breadboard and Jumper Wires
- Power Supply or USB Cable
#Setting Up the Development Environment
Before diving into the code, ensure that you have the Arduino IDE installed along with the ESP32 board package.
- Install the Arduino IDE: Download and install the Arduino IDE from here.
- Install the ESP32 Board Package:
- Open the Arduino IDE.
- Go to
File->Preferences. - In the "Additional Board Manager URLs" field, enter the following URL : arduino Copy code
https://dl.espressif.com/dl/package_esp32_index.json - Go to
Tools->Board->Boards Managerand search for "ESP32". - Install the "ESP32 by Espressif Systems" package.
#Understanding the ADC on ESP32
The ESP32 features multiple ADC channels, each capable of reading analog signals. Here are key points to understand:
- ADC Channels: The ESP32 has 18 ADC channels, divided between two ADC modules (ADC1 and ADC2). ADC1 is typically preferred for general use as ADC2 shares pins with Wi-Fi functions, potentially causing conflicts.
- Resolution: The default resolution is 12 bits, but it can be configured between 9 and 12 bits. A higher resolution gives more precise readings but increases the time required for conversion.
- Voltage Reference: The ESP32's ADC reads input voltages between 0 and 3.3V. The resolution divides this range into equal intervals.
#Reading Analog Values with ADC
Let’s start with a simple example where we read the value from a potentiometer connected to one of the ADC pins.
Wiring:
- Connect the middle pin of the potentiometer to GPIO 34 (ADC1 Channel 6).
- Connect one of the outer pins to 3.3V.
- Connect the other outer pin to GND.
// Sample Code is Written By OceanLabz.in
const int potPin = 34; // GPIO 34 (ADC1 Channel)
void setup() { Serial.begin(115200); // Initialize serial communication at 115200 baud }
void loop() { int potValue = analogRead(potPin); // Read the analog value Serial.println(potValue); // Print the value to the Serial Monitor delay(500); // Delay for stability }
Explanation:
analogRead(potPin): This function reads the analog value from GPIO 34.- The ADC converts the voltage from the potentiometer into a value between 0 and 4095.
- The value is printed to the Serial Monitor every 500 milliseconds.
#Scaling and Calibration
To convert the raw ADC readings into meaningful values (e.g., voltage), you may need to scale and calibrate the output.
Example: Converting the ADC value to voltage.
const float voltageMax = 3.3; // Maximum voltage const int adcMax = 4095; // Maximum ADC value (12-bit resolution)
void loop() { int potValue = analogRead(potPin); float voltage = (potValue * voltageMax) / adcMax; // Convert to voltage Serial.println(voltage); // Print the voltage delay(500); }
#Advanced ADC Applications
#Reading a Temperature Sensor
Analog temperature sensors like the LM35 provide a voltage output proportional to the temperature. You can use the ADC to read this voltage and convert it to a temperature value.
Example: Reading temperature from an LM35 sensor.
//
const int tempPin = 34; // GPIO 34 const float voltageRef = 3.3; // Reference voltage
void loop() { int adcValue = analogRead(tempPin); float voltage = (adcValue * voltageRef) / 4095.0; float temperatureC = voltage * 100.0; // LM35 gives 10mV/°C Serial.print("Temperature: "); Serial.print(temperatureC); Serial.println(" °C"); delay(1000); }
#Using Multiple ADC Channels
The ESP32 allows you to read from multiple ADC channels simultaneously. Here’s how you can monitor two analog sensors (e.g., a potentiometer and a photoresistor).
Wiring:
- Potentiometer middle pin to GPIO 34.
- Photoresistor (LDR) connected in series with a 10kΩ resistor between 3.3V and GND. The junction of the LDR and resistor connects to GPIO 35 (ADC1 Channel 7).
// Sample Code is Written By OceanLabz.in
void setup() { Serial.begin(115200); }
void loop() { int potValue = analogRead(34); // Read potentiometer int ldrValue = analogRead(35); // Read LDR
Serial.print("Potentiometer: "); Serial.print(potValue); Serial.print(" | LDR: "); Serial.println(ldrValue);
delay(500); }
Explanation:
analogRead(34)andanalogRead(35)are used to read from two different ADC channels.- The readings are printed side by side to the Serial Monitor.
#Troubleshooting and Tips
- Floating Inputs: Unused ADC pins can float, leading to unstable readings. To prevent this, connect unused ADC pins to ground through a pull-down resistor.
- ADC Accuracy: The ESP32’s ADC is not perfect and might have some non-linearity or noise. Consider averaging multiple readings for more stable results.
- Wi-Fi Interference: When using ADC2, avoid using Wi-Fi simultaneously, as it can cause ADC readings to be inaccurate.
#Other Functions
- analogReadResolution(resolution):
- Set the sample bits and resolution between 9 to 12 bits.
- Default is 12-bit resolution.
- analogSetWidth(width):
- Similar to analogReadResolution(), set sample bits and resolution.
- 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, affecting sensitivity.
- Default is 1 sample.
- analogSetClockDiv(attenuation):
- Set the divider for the ADC clock.
- Default is 1, range: 1 to 255.
- analogSetAttenuation(attenuation):
- Set input attenuation for all ADC pins.
- Default is ADC_11db.
- Accepted values:
- ADC_0db: No attenuation (measures up to approximately 800 mV).
- ADC_2_5db: Attenuated input, measuring up to approx. 1100 mV.
- ADC_6db: Attenuated input, measuring up to approx. 1350 mV.
- ADC_11db: Attenuated input, measuring up to approx. 2600 mV.
- analogSetPinAttenuation(pin, attenuation):
- Set the input attenuation for a specified pin.
- adcAttachPin(pin):
- Attach a pin to ADC, clearing any other analog mode.
- Returns TRUE or FALSE result.
- adcStart(pin), adcBusy(pin), and adcEnd(pin):
- Start an ADC conversion on the attached pin’s bus.
- Check if conversion on the pin’s ADC bus is running (returns TRUE or FALSE).
- Get the result of the conversion (returns a 16-bit integer).