esp32_adc
ADC1: eight channels of analog input on GPIO 32–39.
ADC1 only, and that is deliberate
Section titled “ADC1 only, and that is deliberate”ADC2 shares its SAR with the Wi-Fi radio and is unusable whenever the radio is up. An API that hands out ADC2 channels invites a bug that appears the day someone turns on networking and not before, which is the worst kind. This crate does not expose ADC2 at all. If it ever does, it must refuse while the radio is running.
Raw counts are not volts
Section titled “Raw counts are not volts”Every reading here is a raw SAR count. The ESP32’s ADC is not linear and its gain and offset vary per chip; Espressif burns per-chip calibration into eFuse for exactly that reason. Converting counts to millivolts without it is off by enough to matter — tens of millivolts, more at the ends of the range.
So this returns counts, and says so in the type. to_millivolts is
deliberately absent rather than approximate: a function that returns a
number in volts is trusted as volts.
Attenuation
Section titled “Attenuation”The input range is not 0–3.3 V by default. At 0 dB the ADC saturates around 1.1 V; the wider ranges trade accuracy for headroom. Picking the wrong one gives a reading pinned at full scale, which reads like a shorted input rather than a configuration mistake.
| Attenuation | Usable input, roughly |
|---|---|
| 0 dB | 0–1.1 V |
| 2.5 dB | 0–1.5 V |
| 6 dB | 0–2.2 V |
| 11 dB | 0–3.9 V, clipped by the 3.3 V supply |
Register facts
Section titled “Register facts”From esp-idf soc/sens_reg.h, DR_REG_SENS_BASE = 0x3FF48800:
| Register | Offset | Fields |
|---|---|---|
SAR_READ_CTRL |
0x00 |
SAR1_SAMPLE_BIT [17:16], SAR1_DIG_FORCE 27, SAR1_DATA_INV 28 |
SAR_ATTEN1 |
0x34 |
two bits per channel |
SAR_MEAS_START1 |
0x54 |
EN_PAD_FORCE 31, EN_PAD [30:19], START_FORCE 18, START_SAR 17, DONE_SAR 16 (RO), DATA_SAR [15:0] (RO) |
Structs
Section titled “Structs”struct Adc1 { /* private fields */ }ADC1, taken as a whole.
One instance: the channels share a SAR, a sample width and one set of control registers, so two owners would interleave conversions and read each other’s results.
PadDebug
Section titled “PadDebug”struct PadDebug { pub pad: u32, pub enable: u32, pub out: u32, pub input: u32, pub bit: u32,}What [Adc1::pad_debug] found. bit is this pad’s position in the three
RTC GPIO registers, so a caller can pick its pin out of them.
Implements: Clone, Copy, Debug
AdcError
Section titled “AdcError”enum AdcError { Timeout, NoPullOnThisPad,}Why a reading or a pad change failed.
Implements: Clone, Copy, Debug, Eq, From, PartialEq, StructuralPartialEq
Channel
Section titled “Channel”enum Channel { Gpio36, Gpio37, Gpio38, Gpio39, Gpio32, Gpio33, Gpio34, Gpio35,}An ADC1 channel, named by the GPIO it reads.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
enum Pull { None, Up, Down,}What the pad’s own resistor does.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq