Using an ESP32C3 to implement an ADC Hat for the Raspberry PI poses some challenges if we want to obtain great accuracy in the range of 1%.
First, we add a voltage divider at the input of each ADC channel (R1 and R4 in the schematic). A 0.01uF capacitor is connected to ADC1_0 to filter out the noise.
Jumper pads JP1, JP4 and JP7 provide means to configure the input attenuation as follows:
Direct input to ADC 0-2.5V | JP1-1-2 shorted | JP7-1-2 shorted |
0-24V input | JP1-2-3 shorted, JP4 shorted | JP7-1-2 shorted |
±12V input | JP1-2-3 shorted, JP4 shorted | JP7-2-3 shorted |
REF1.25V
A MAX6101 provides this 0.4% reference to bias the input of the ADC at half its full scale when the voltage divider is configured.
ADC Calibration
The ESP32 has its factory calibration data saved in eFuse memory. The esp_adc_cal_raw-to_voltage function converts the raw ADC value to mV using the factory calibration constants. The resulting values are pretty accurate. Since the 1.25V 0.4% reference is accessible on the terminal block, it can be used to check or recalibrate the ADC for maximum accuracy.
Voltage output calculations Unipolar Signals
When the divider is in use for positive signals, the output voltage is calculated as follows:
Equation 1: (esp_adc_cal_raw-to_voltage) x ( (R1+R4)/(R4) ) = Vin
The ADC input attenuation must be set to -11db.
A 12.8V input would be attenuated to 1.269 by the voltage divider.
esp_adc_cal_raw-to_voltage = 1.269V.
Following equation 1: (1.269) x ( (909K+100K)/100K ) = 12.80V
An 80mV input would be attenuated to 7.93mV by the voltage divider.
esp_adc_cal_raw-to_voltage = 7.93mV.
Following equation 1: (0.00793 ) x ( (909K+100K)/100K ) = 0.080V
The minimum step is 2500/4095 = 0.61mV (adc raw) or 6.158mV at the input to the resistor divider.
The maximum input is 24V. It would be attenuated to 2.38V.
As per equation 1: (2.38) x ( (909K+100K)/100K ) = 24.0V
Note the division ratio of R4 and R1 is 10.09.
Voltage output calculations Bipolar Signals
When the divider is in use for bipolar signals, the output voltage is calculated as follows:
Equation 1: (esp_adc_cal_raw-to_voltage – 1.25) x ( (R1+R4)/(R4) ) = Vin
The ADC input attenuation must be set to -11db.
A 12V input would be attenuated to 1.19 by the voltage divider and offset to 1.19 + 1.25 = 2.44V.
esp_adc_cal_raw-to_voltage = 2.44V.
Following equation 1: (2.44 -1.25) x ( (909K+100K)/100K ) = 12.0V
A -12V input would be attenuated to -1.19V by the voltage divider and offset to 0.06V.
esp_adc_cal_raw-to_voltage = 60 mV.
Following equation 1: (0.06 – 1.25) x ( (909K+100K)/100K ) = -12.0V
Noise and Sampling
With a Wi-Fi transmitter generating rf signals, it is to be expected that some noise will pollute the ADC inputs. For this reason, we recommend averaging the results over as many samples as possible. A 0.01uF capacitor at the input of each ADC channel further attenuates noise. Finally, we use a separate analog ground on the PCB to minimize noise.
The input voltage divider has the added benefit of filtering any high voltage spikes that may be present at input. To keep insulation in the range of a few hundred volts, the R1’s size is 0805 and the spacing for input traces is set to 0.6 mm. This minimizes the chance of outside noise disturbing the circuit.