Static Tests of the Arduino Internal ADC.

Several people have asked about the DC accuracy of the Arduino ADC when used in my data logging applications at slow sample rates.

Here are my results of some "hobby level" measurements of the Arduino ADC.

One question is how important is the ADC clock rate.  I did measurents for an ADC clock rate of 125 kHz to 2MHz.

Another question is how much does Noise Reduction Mode help.  I did a series of measurements using this mode.

Noise Reduction Mode only reduced the mean absolute error slightly.

I do calibration to remove Offset Error and Gain Error.  Calibration is very important for good accuracy.

These tests depend on the Arduino voltage regulator providing a stable voltage during the tests.  The Arduino ADC reference voltage is Vcc for these tests.  This may not be realistic for practical applications

Integral Non-linearity (INL) is the main remaining source of error.

Here are my results for static (DC) tests of the internal ADC for three UNOs.

The Arduinos are powered by a high quality nine volt power supply.

These tests measure a DC level so do not include problems due to time jitter, S/H time, and other dynamic errors.
There are several studies of the dynamic behavior of the Arduino ADC that determine ENOB (Effective Number Of Bits).

I used a shield with a 12-bit MCP4921 DAC to generate voltage levels. This ADC has an output buffer so it provides a very low impedance source.

I measured the voltage of the DAC with a calibrated 18-bit MCP3422 ADC on the shield.

I used DAC levels from 20 to 4075 to avoid zero offset errors at low voltages and DAC buffer problems at high voltages.

Each series of measurements has 4056 data points.

This is a voltage range of about 0.023 to 4.972 volts.

I calibrated the Arduino ADC for each series of measurements with a linear fit of the form.

v = a + b*adcValue

Errors are the difference between the value measured with the 18-bit ADC and the calibrated value measured with the AVR ADC.

I also show the results for no calibration, the NoCal column, using the datasheet formula.

Vin = Vref*adcValue/1024


The rows in the tables tables are.

Min - minimum error in millivolts

Max - maximum error in millivolts

MAE - mean absolute error in millivolts


The columns in the tables are:

Ideal - results for a perfect 10-bit ADC for comparison.

NoCal - datasheet formula (5/1024)*adcValue with Noise Reduction Mode.

NR128 - Noise Reduction mode with Prescaler of 128 (ADC clock of 125 kHz).

PS128 - analogRead with Prescaler of 128 (ADC clock of 125 kHz).

PS64 - analogRead with Prescaler of 64 (ADC clock of 250 kHz).

PS32 - analogRead with Prescaler of 32 (ADC clock of 500 kHz).

PS16 - analogRead with Prescaler of 16 (ADC clock of 1 MHz).

PS8 - analogRead with Prescaler of 8 (ADC clock of 2 MHz).


Results for three UNO Arduinos

     First Arduino - Error Millivolts
      
     Ideal NoCal NR128 PS128  PS64  PS32  PS16    PS8
Min  -2.44 -2.43 -3.72 -4.01 -3.88 -4.53 -6.57 -27.18
Max   2.44 11.69  3.74  4.24  4.15  5.17  8.69  23.21
MAE   1.22  5.02  1.33  1.38  1.37  1.44  1.96   4.11

     Second Arduino - Error Millivolts

     Ideal NoCal NR128 PS128  PS64  PS32  PS16    PS8
Min  -2.44 -9.24 -4.87 -4.86 -5.05 -5.34 -6.52 -24.04
Max   2.44 11.62  3.95  4.64  4.69  5.71  8.41  21.29
MAE   1.22  5.33  1.41  1.43  1.44  1.53  2.02   4.05

     Third Arduino - Error Millivolts

     Ideal NoCal NR128 PS128  PS64  PS32  PS16    PS8
Min  -2.44 -7.88 -4.12 -4.40 -4.32 -4.41 -6.97 -26.93
Max   2.44 12.53  3.80  4.04  4.18  5.27  8.84  24.59
MAE   1.22  4.85  1.29  1.33  1.34  1.42  1.91   4.10


