Skip to content
Back to skills

Esp32 Adc And Sensors

ASecurity

Use when reading an analog sensor on an ESP32 - the reading is noisy, saturates, drifts, or returns nonsense once Wi-Fi connects. Covers ADC1 vs ADC2, attenuation, calibration, source impedance and averaging.

  • 16 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added November 7, 2026
ai-agents

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add Esmail-sarhadi/esp32-agent-skills --skill esp32-adc-and-sensors --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Esp32 Adc And Sensors?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Esp32 Adc And Sensors
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/esmail-sarhadi-esp32-adc-and-sensors/badge)](https://www.skillsdirectory.com/skills/esmail-sarhadi-esp32-adc-and-sensors)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: esp32-adc-and-sensors
description: Use when reading an analog sensor on an ESP32 - the reading is noisy, saturates, drifts, or returns nonsense once Wi-Fi connects. Covers ADC1 vs ADC2, attenuation, calibration, source impedance and averaging.
license: MIT
---

# Reading analog sensors on ESP32

The ESP32 ADC is the weakest peripheral on the chip. It is usable, but only if
you know which pin you are on and what the input looks like.

## Pin choice decides everything

- **ADC1** is `GPIO32`-`GPIO39`. It keeps working while Wi-Fi is active.
- **ADC2** is `GPIO0`, `2`, `4`, `12`-`15`, `25`-`27`. It is **unavailable
  while Wi-Fi is on**: `analogRead` returns 0 or garbage. This is not a bug and
  there is no workaround.
- `GPIO34`-`GPIO39` are input-only, which is fine for an analog input, but they
  have no internal pull-up. A floating input reads noise, not zero.

If the sketch reads an analog sensor and also joins a network, the sensor must
be on ADC1. Anything else is a design error, not a tuning problem.

## Attenuation sets the range

The ADC measures 0-1.1 V at 0 dB attenuation. To read a 3.3 V sensor you need
attenuation, and the top of that range is not linear:

| Setting | Rough input range | Notes |
|---|---|---|
| `ADC_0db` | 0 - 1.1 V | most linear |
| `ADC_2_5db` | 0 - 1.5 V | |
| `ADC_6db` | 0 - 2.2 V | |
| `ADC_11db` | 0 - 3.1 V | the top ~0.4 V is noticeably compressed |

A sensor that reads "always about 3.2 V" at `11db` may simply be above the
linear region. Scale the divider so the signal lands in the middle of the range
rather than at the top.

## Calibration

Raw `analogRead` values vary between chips because of the internal reference.
The Arduino core exposes `analogReadMilliVolts(pin)`, which applies the eFuse
calibration values for your specific chip. Use it:

```cpp
int raw = analogRead(PIN);                     // 0..4095
int mv  = analogReadMilliVolts(PIN);           // calibrated, in mV
```

`mv` is the number to put in the datasheet formula. `raw` is only useful for
comparisons against other readings on the same chip.

## Source impedance

The sample-and-hold capacitor needs the source to be stiff. A divider made of
two 100 kΩ resistors reads low and drifts, because the ADC loads it during the
sample window.

- Keep the divider under about 10 kΩ total.
- Add 100 nF from the ADC pin to ground: it supplies the sample charge and
  removes most of the noise.
- Long wires pick up noise; the capacitor is not optional there.

## Averaging, honestly

The ADC is noisy by design. Averaging N samples improves the reading by roughly
`sqrt(N)`:

```cpp
int readAverage(uint8_t pin, int samples = 16) {
  int32_t total = 0;
  for (int i = 0; i < samples; i++) total += analogReadMilliVolts(pin);
  return total / samples;
}
```

Do not average across a change you care about: 16 samples at full speed is fast,
but 16 samples with a delay between them will smear a step response.

## Rules for the agent

- Before writing analog code, check the pin against the ADC1 list. If it is on
  ADC2 and the sketch uses Wi-Fi, say so and move the sensor.
- Use `analogReadMilliVolts` when the value feeds a formula. `analogRead` alone
  is not a voltage.
- Never "fix" a noisy reading by raising the resolution. The noise is in the
  analog front end; averaging and a capacitor are the fixes.

Files in this skill

  • LICENSE.txt857 B
  • SKILL.md3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.