Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home IoT & Smart Home

ESP32 ADC Accuracy: Fix Noise and Non-Linearity Issues

ESP32 ADC Accuracy: Fix Noise and Non-Linearity Issues

March 11, 2026 /Posted byJayesh Jain / 0

If you have worked with the ESP32’s built-in ADC (Analog-to-Digital Converter) for any serious measurement project, you have almost certainly hit the frustrating wall of ESP32 ADC accuracy problems — noisy readings, non-linear voltage curves, and results that simply do not match your multimeter. This troubleshooting guide explains exactly why the ESP32 ADC misbehaves, how to fix ESP32 ADC noise, and how to work around the non-linearity to get reliable analog readings for your Indian maker projects.

Table of Contents

  1. ESP32 ADC: What You Are Working With
  2. Root Causes of ESP32 ADC Noise
  3. The Non-Linearity Problem Explained
  4. Software Fixes: Oversampling and Filtering
  5. Hardware Fixes: Decoupling and External References
  6. ADC Calibration Using ESP32’s Built-in eFuse Data
  7. When to Use an External ADC (ADS1115)
  8. Frequently Asked Questions

ESP32 ADC: What You Are Working With

The ESP32 has two ADC units — ADC1 (8 channels on GPIO32–39) and ADC2 (10 channels on GPIO0–27, shared with Wi-Fi). The ADC is 12-bit, meaning it can theoretically resolve 4096 discrete values (0–4095) across its input voltage range. At face value, this sounds impressive, but the actual usable dynamic range is considerably less due to the issues we will cover.

Key ESP32 ADC specifications:

Parameter Value
Resolution 12-bit (0–4095)
Input range (11dB attenuation) 0–3.3V (0.15–2.45V usable)
Input range (0dB attenuation) 0–1.0V (more linear)
ADC2 with Wi-Fi Cannot be used (conflicts)
Typical noise ±10–30 LSB (raw)

Critical rule: Never use ADC2 pins (GPIO0, GPIO2, GPIO4, GPIO12–15, GPIO25–27) when Wi-Fi is active. ADC2 is shared with the Wi-Fi radio hardware and will give garbage readings or cause conflicts. Stick to ADC1 pins (GPIO32–39) for all analog measurements.

Root Causes of ESP32 ADC Noise

Understanding where the noise comes from is the first step to fixing it. ESP32 ADC noise has several sources:

1. Internal Switching Noise

The ESP32 chip is extremely active internally — two CPU cores running at 240 MHz, Wi-Fi radio, Bluetooth stack, and multiple peripherals. All of this switching activity induces noise on the internal power rails, which couples directly into the ADC’s reference voltage and sample-and-hold circuit.

2. Insufficient Decoupling on VDDA

The ESP32’s analog supply pin (VDDA) needs good decoupling capacitors very close to the chip. Many cheap ESP32 dev boards (especially no-name variants sold in India) skip or under-spec these capacitors, resulting in noisy ADC references.

3. Wi-Fi Radio Interference

When Wi-Fi is transmitting, it creates a burst of switching current that rings on the power supply. Even ADC1 readings taken during a Wi-Fi transmission burst will show spikes. This is why sensor reads often show random outliers.

4. High Source Impedance

The ESP32 ADC’s input impedance is low (around 100kΩ in active mode). If your sensor or voltage divider has a high output impedance, the ADC will not fully charge its sample capacitor in time, causing reading errors. Always buffer high-impedance sources with an op-amp or use a low source impedance (below 10kΩ recommended).

5. Floating Inputs

An unconnected ADC pin will read random values as it picks up electromagnetic interference. Always connect unused ADC pins to GND through a resistor, or pull them to a known voltage.

The Non-Linearity Problem Explained

This is the most commonly complained-about ESP32 ADC issue. Even with a perfectly clean, slowly varying DC voltage, the ESP32’s ADC does not produce a linear mapping from voltage to ADC count. The ADC value vs. voltage curve has S-shaped distortion, particularly at the low end (below 0.15V) and the high end (above 2.45V with 11dB attenuation).

A typical measurement with 11dB attenuation on a genuine board:

  • 0.00V → ADC reads ~0 (clipped, not linear)
  • 0.10V → ADC reads ~50 (should be ~124)
  • 1.00V → ADC reads ~1300 (fairly linear zone)
  • 2.00V → ADC reads ~2650 (fairly linear zone)
  • 2.45V → ADC reads ~3800 (non-linear again)
  • 3.30V → ADC reads ~4095 (clipped)

The usable linear range with 11dB attenuation is roughly 0.15V to 2.45V, giving you about 2.3V of actual dynamic range from a 12-bit ADC. Expressed in bits, this is effectively about 10.7 bits of linear resolution — not 12 bits.

LM35 Temperature Sensor

LM35 Temperature Sensor

A classic analog temperature sensor — its 10 mV/°C output sits right in the ESP32 ADC’s linear range and is a great test target for ADC accuracy improvements.

View on Zbotic

Software Fixes: Oversampling and Filtering

Software techniques are your first line of defence against ADC noise and they cost nothing to implement.

Technique 1: Oversampling and Averaging

Take multiple readings quickly and average them. This reduces random noise by a factor of √N, where N is the number of samples. Taking 16 samples effectively gives you about 1 extra bit of resolution (√16 = 4 times noise reduction).

// Average 64 samples for noise reduction
int readADCaveraged(int pin, int samples = 64) {
  long sum = 0;
  for (int i = 0; i < samples; i++) {
    sum += analogRead(pin);
    delayMicroseconds(100); // Small gap between samples
  }
  return sum / samples;
}

void setup() {
  Serial.begin(115200);
  // Use ADC1 pin only!
  analogSetAttenuation(ADC_11db); // 0–3.3V range
  analogSetWidth(12);             // 12-bit resolution
}

void loop() {
  int adcValue = readADCaveraged(34, 64); // GPIO34 = ADC1_CH6
  float voltage = adcValue * (3.3f / 4095.0f);
  Serial.printf("ADC: %d | Voltage: %.3f Vn", adcValue, voltage);
  delay(500);
}

Technique 2: Median Filtering

Median filtering removes spike outliers (like Wi-Fi noise bursts) better than simple averaging. Collect an odd number of samples, sort them, and take the middle value:

int compareInts(const void* a, const void* b) {
  return (*(int*)a - *(int*)b);
}

int readADCmedian(int pin, int samples = 15) {
  int buf[samples];
  for (int i = 0; i < samples; i++) {
    buf[i] = analogRead(pin);
    delayMicroseconds(200);
  }
  qsort(buf, samples, sizeof(int), compareInts);
  return buf[samples / 2]; // Return the middle value
}

Technique 3: Exponential Moving Average (EMA)

For slowly changing signals (temperature, pressure), an exponential moving average smooths readings continuously without buffering:

float emaValue = 0;
float alpha = 0.1f; // 0.05-0.2 is typical (lower = smoother)

void loop() {
  int raw = analogRead(34);
  emaValue = alpha * raw + (1.0f - alpha) * emaValue;
  Serial.println(emaValue);
  delay(50);
}

Hardware Fixes: Decoupling and External References

When software fixes are not enough, hardware improvements make a dramatic difference.

Fix 1: Add Decoupling Capacitors

Place a 100nF ceramic capacitor as close as possible to the ADC input pin (between the pin and GND). For very noisy environments, add a 10µF electrolytic in parallel. This forms a low-pass RC filter with your source impedance, cutting high-frequency noise before it enters the ADC.

Fix 2: Add an RC Low-Pass Filter on the Input

Add a 10kΩ resistor in series with the ADC input, followed by a 100nF capacitor to GND. This RC filter has a cutoff frequency of about 160 Hz, which is more than fast enough for most sensor readings (temperature, pressure, slow potentiometers) while completely eliminating MHz-range switching noise.

Fix 3: Read ADC When Wi-Fi is Quiet

Schedule your ADC reads during Wi-Fi idle windows using the WiFi.setSleep(WIFI_PS_MIN_MODEM) setting, or disable Wi-Fi briefly, take the reading, and reconnect. For applications that need both Wi-Fi and accurate ADC simultaneously, use an external ADC over SPI or I2C.

Fix 4: Use a Voltage Divider Within the Linear Range

If measuring voltages above 2.45V, design your voltage divider so that the maximum expected voltage maps to 2.0V at the ADC input (leaving headroom and staying in the linear zone). Use low-impedance resistors (1kΩ to 10kΩ range) for the divider.

ADC Calibration Using ESP32’s Built-in eFuse Data

Espressif provides an ADC Calibration API in the ESP-IDF framework (also available in Arduino via esp_adc_cal.h). Each ESP32 chip is factory-calibrated with coefficients stored in eFuse that correct for the non-linearity curve. Using this API dramatically improves accuracy:

#include <esp_adc_cal.h>
#include <driver/adc.h>

#define ADC_CHANNEL ADC1_CHANNEL_6 // GPIO34
#define ADC_ATTEN   ADC_ATTEN_DB_11

esp_adc_cal_characteristics_t adc_chars;

void setup() {
  Serial.begin(115200);
  adc1_config_width(ADC_WIDTH_BIT_12);
  adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN);

  // Characterise ADC using eFuse coefficients
  esp_adc_cal_characterize(
    ADC_UNIT_1,
    ADC_ATTEN,
    ADC_WIDTH_BIT_12,
    1100, // Default Vref (mV), ignored if eFuse available
    &adc_chars
  );
}

void loop() {
  // Average 64 samples
  uint32_t adc_reading = 0;
  for (int i = 0; i < 64; i++) {
    adc_reading += adc1_get_raw(ADC_CHANNEL);
  }
  adc_reading /= 64;

  // Convert to calibrated millivolts
  uint32_t voltage_mv = esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars);
  Serial.printf("Raw: %d | Voltage: %d mV (%.3f V)n",
                adc_reading, voltage_mv, voltage_mv / 1000.0f);
  delay(500);
}

This calibrated approach typically reduces voltage reading error from ±100–150mV to ±20–30mV, a 5x improvement without any additional hardware.

When to Use an External ADC (ADS1115)

For applications that need truly accurate analog readings — precision weighing, medical sensors, high-resolution audio — no amount of software tricks will make the ESP32’s internal ADC sufficient. In these cases, use an external ADC over I2C or SPI.

The ADS1115 (Texas Instruments) is the most popular choice:

  • 16-bit resolution (vs ESP32’s effective 10–11 bits)
  • Programmable gain amplifier (±256mV to ±6.144V ranges)
  • I2C interface (plug into any ESP32 I2C pins)
  • 4 single-ended or 2 differential inputs
  • Integrated voltage reference (no noise from ESP32 power rail)
Ai Thinker NodeMCU-32S ESP32 Development Board

Ai Thinker NodeMCU-32S ESP32 Development Board – IPEX Version

A quality ESP32 board with reliable power regulation — an important factor for better ADC performance. IPEX antenna for strong Wi-Fi to minimise radio interference on ADC.

View on Zbotic

BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module

BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module

An excellent example of a digital I2C sensor that avoids ESP32 ADC limitations entirely — provides precise pressure and temperature without any analog noise issues.

View on Zbotic

Frequently Asked Questions

Why does my ESP32 ADC reading fluctuate even with no signal connected?

A floating ADC input (nothing connected, or high impedance source) picks up electromagnetic noise from the environment and from the ESP32 itself. Always connect unused ADC pins to GND through a 10kΩ resistor. For connected sensors, use a bypass capacitor (100nF between the ADC pin and GND) to reduce noise pickup.

Can I use ADC2 if I disable Wi-Fi?

Yes. If you stop Wi-Fi (WiFi.disconnect(true); WiFi.mode(WIFI_OFF);), ADC2 becomes available and performs similarly to ADC1. However, as soon as you restart Wi-Fi, ADC2 readings will become unreliable. For applications needing both Wi-Fi and analog readings, use only ADC1 (GPIO32–39).

How much does oversampling actually improve accuracy?

Averaging N samples reduces random noise by √N. Taking 16 samples reduces noise by 4x, which is equivalent to gaining 2 extra bits of effective resolution. Taking 64 samples reduces noise by 8x (3 extra bits). Beyond 256 samples, gains diminish as you start hitting systematic (non-random) error sources that averaging cannot remove.

Is there a good Arduino library for ESP32 ADC calibration?

The esp_adc_cal.h library from Espressif is the standard approach and is included in the ESP32 Arduino board package. There is also the ESP32AnalogRead library on GitHub that wraps the calibration API with a simple getValue() and getMilliVolts() interface. Both are good choices for cleaner calibrated readings.

Why is pin GPIO34/35/36/39 recommended for ADC on ESP32?

GPIO34, 35, 36, and 39 are input-only pins connected to ADC1. Since they are input-only, they have no output driver transistors, which means less internal switching noise and better analog characteristics. They also cannot accidentally be configured as digital outputs, reducing the chance of damaging your sensor circuit.

Get Quality ESP32 Boards and Sensors from Zbotic

Better hardware makes a real difference for ADC accuracy. Shop genuine ESP32 development boards, sensors, and components at Zbotic with fast delivery across India.

Shop ESP32 and Sensor Modules at Zbotic

Tags: ADC Accuracy, Analog Reading, ESP32 ADC, ESP32 Troubleshooting, Noise Reduction
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Troubleshoot ESP32 WiFi Drops ...
blog troubleshoot esp32 wifi drops and reconnection issues 595355
blog esp32 usb hid emulate keyboard and mouse from microcontroller 595357
ESP32 USB HID: Emulate Keyboar...

Related posts

Svg%3E
Read more

IoT Home Insurance Sensor Kit: Leak, Smoke, and Motion

April 1, 2026 0
Table of Contents IoT and Home Insurance Water Leak Detection Smoke and Fire Detection Motion and Intrusion Sensing Building the... Continue reading
Svg%3E
Read more

IoT Pet Tracker: GPS Collar with Geofencing Alerts

April 1, 2026 0
Table of Contents Introduction and Overview Hardware Components Required GPS Module Integration with ESP32 Cloud Platform Setup Real-Time Tracking Dashboard... Continue reading
Svg%3E
Read more

IoT Aquaponics Controller: Fish and Plant Automation

April 1, 2026 0
Table of Contents The Water Monitoring Challenge in India Sensor Technologies for Water Building the Sensor Node Data Transmission and... Continue reading
Svg%3E
Read more

IoT Composting Monitor: Temperature and Moisture Tracking

April 1, 2026 0
Table of Contents Why Temperature Monitoring Matters Sensor Selection Guide Hardware Assembly and Wiring Firmware Development Cloud Data Logging Alert... Continue reading
Svg%3E
Read more

IoT Beehive Monitor: Weight, Temperature, and Humidity

April 1, 2026 0
Table of Contents Why Monitor Beehives Weight Measurement System Temperature and Humidity Sensing Building the Monitor Data Analysis for Bee... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now