ESP32-C6 ADC reference

A quick article to post the relevant ADC information of ESP32-C6.

ESP32-C6 is a embedded micro-controller with a dual RISC-V cores running up to 160MHz and 20MHz. It's main selling point is that it's complete, it can talk Wifi (802.11ax), Bluetooth (BLE) and Zigbee (802.15.4). It's a direct competitor to ESP32-S3 (which is using a Tensilica Xtensa core running up to 240MHz) which doesn't do 802.15.14 networking.

The software is mainly open source (available in esp-idf repository) except for the low level network stack that's distributed as pre-compiled libraries.

The documentation for these processors is plentiful, although it is lacking in some domains that I consider as very important. So let's sort it out:

ADC

The ADC in ESP32-C6 is not documented correctly. It really need some love from Espressif, since it's a very useful feature and the lack of documentation gives headaches to developers and implementers.

It's using a 12 bits SAR architecture, where it's successively comparing a voltage with a reference voltage to check if the voltage is above or below the reference.

The reference voltage is set to ~1.1V.

Let's take an example how it would work with a input voltage of say 2.1V. In that case, the process is the following:

  1. When the ADC conversion starts, the input voltage is sampled, understand, a transistor close and a internal capacitor is charged by this voltage.
  2. The transistor then open to isolate the input voltage from the capacitor charge. It's assumed that the capacitor own leakage is minimal and ignored.
  3. The internal capacitor voltage is connected to a voltage comparator. If it's above, it'll give a 1 for this bit and below, it'll give a 0.
  4. Another transistor close to connect this capacitor on a voltage divider (typically 2 identical capacitors in parallel or resistors in series). The voltage across each is V/2
  5. The transistor opens and only half the voltage is reconnected to the comparator (see 3). This gives the second bit.
  6. The process repeats as many times as required to get the requested resolution.

This process is thus highly dependent on the homogeneity of the internal capacitors, the low leakage of current in the transistor and the reference voltage value. Since making a very stable reference values in silicon is hard, Espressif decided to use calibration to counteract the poor ADC linearity. You thus must use ADC calibration tables stored in fuses to get a meaningful answer. If you don't really care about the actual linearity (for example, if you are trying to detect if a value is above ~2.5V, you could set a threshold to ~2.4V and be done), you can skip this step.

Yet, there are many information that are completely missing in the ESP32-C6 datasheet.

What is the voltage range you can put on ADC pins ?

In ESP32-C6, you've 7 pins that offer ADC features (they call them ADC channels). Those are shared with LP core IO pins (which is a bit dumb, since LP core can not trigger ADC reading when in low power mode, Espressif connected the ADC's peripheral power to the HP core power domain). I guess this is due to the large consumption of the ADC peripheral and the desire to have the lowest possible consumption when in LP mode.

Anyway, the input voltage range on the ADC pin is limited by numerous features:

  1. The actual absolute maximum rating on the IO pad: -0.3V to 3.6V (described as VDD + 0.3 V). If you put more than 3.6V on the pad, the clamping diode will trigger and you can damage the chip. I haven't tried to put 5V here and I don't intend to.
  2. The maximum sampling rate is 100kSPS (kilo sampling per second)
  3. In addition to this limit, the ADC can divide the input voltage numerous time before actually converting it. They call this features attenuation and they express it in dB (which is not really convenient here).
  4. Thus the ESP32-C6 supports up to 3 attenuation step, so you have 4 possible converting scale
Attenuation Voltage divisor factor Input voltage range LSB step Uncertainty in measure (-8 to 12 LSB)
0dB 1.0x 0V ~ 1.0V +/-12mV -96mV ~ 144mV
2.5dB 1.33x 0V ~ 1.3V +/-12mV -96mV ~ 144mV
6dB 2.0x 0V ~ 1.9V +/-23mV -184mV ~ 276mV
12dB 3.98x 0V ~ 3.3V +/-40mV -320mV ~ 480mV

As you can see, the performance of the ADC is quite poor for any fast signal or its large sampling error makes it unsuitable for precise computation. However, you can decrease the uncertainty by multisampling the value and averaging. This is because part of the error is expected to be due to random, Gaussian noise with a zero average. Then, when sampling N times the same signal, the noise cancel out a bit. When averaging, its deviation decrease by N but the signal deviation is the same, thus the noise amplitude is reduced by √N.

In that case, this means that to lower the uncertainty in the measure to, say, only [ -1 LSB ~ 1.5 LSB ], the same signal must be sampled 8 * 8 = 64 times (8 comes from reducing from 8 LSB to 1 LSB).

This is only valid for the Gaussian part of the noise, but there's also a frequency part in the noise(1/f) that doesn't reduce with multisampling, so large multisampling factor will give diminishing results.

One has to decide the multisampling factor that's compatible with her expectation.

ADC input impedance

There's no mention of input impedance of the ADC. However, the datasheet states that:

  1. A 100nF capacitor is recommended on the input pad when using ADC
  2. The input leakage current is less than ~50nA

Since the input of an SAR ADC is mainly a capacitor, this means that we have to model a capacitor with unknown capacitance and a ESR than sinks 50nA of current at 3.3V, thus an resistive impedance of 66MΩ. The recommended 100nF capacitor must discharge into the internal capacitor while sampling, so we can estimate that the internal capacitor is at least an order of magnitude (10x) lower than the recommended capacitor, so around 10nF or less.

Hope it's helpful.

Previous Post

Related Posts