Fast analogRead 10/12 bit ADC for the Arduino Zero and Uno

Published: 17 December 2015
Last updated: 18 October 2022


This fast ADC library is built as part of the Oscilloscope base library for the Arduino. The standard analogRead() function takes about 112us for the AVR and 425us for the SAMD21, this is very slow. The new function analogReadFast() takes just 21us. The resolution will not be reduced significantly.
Here is a 2kHz sine wave measured with analogReadFast, shown in Excel:

Fast 10-bit ADC for the ArduinoFast 10-bit ADC for the Arduino

analogReadFast at the AVR

The library is compatible with Arduino boards that use the AVR chips: Arduino Uno, Nano, Mega, Leonardo, etc.
The analogReadFast function is much faster than the original analogRead: 20us instead of 112us.

analogReadFast at the SAMD21

The library is compatible with Arduino boards that use the SAMD21: Arduino Zero, SAM 15x15, etc. 
The analogReadFast function is much faster than the original analogRead: 21us instead of 435us.
The resolution for analogReadFast must be set with analogReadResolution(10) or analogReadResolution(12), just as with analogRead.

Library download

Download the library at GitHub.

Input buffer required

The analog inputs of the SAMD21 require buffer opamps, else the ADC values are very noisy. This is because successive approximation ADCs do switch capacitances at the input during the conversion. In order to have a stable conversion, it is mandatory to use a low impedance circuit to drive their input.
The necessity of a buffer opamp depends on the required accuracy. For Arduino chips with 10bit ADCs, an input buffer is not always necessary.
Note that there are also ADCs with a buffer built in.

Input buffer for successive approximation Arduino ADCInput buffer for successive approximation Arduino ADC

A simple RC filter at the input of a 10bit ADC sometimes works fine without an extra buffer. But for a 12bit ADC (SAMD21) it can be problematic. 
RX / CX is to prevent instability of the opamp, this is not always necessary.

Test program

The testprogram can be downloaded at GitHub

  • AnalogRead is tested with 6 variations: slow / fast, 10 / 12bit, with / without ravg filter.
  • For each test, 100 test values are stored in their own buffer.
  • For these buffers, the RunningAverage library is used, because it has a handy standardDeviation function.
  • AnalogReadFast is quite noisy, so we need filtering. In the test program we create the filter with the RunningAverage library.
  • To do the ADC measurements at full speed, printing to the serial moniotor is done at the end.
  • The values can be copied directly to Excel. That makes it easy to do accuracy and noise tests. 
  • The noise is tested on the SAM15x15 board with extra capacitors at the power supplies: 10uF at 3.3VA and 47uF at 3.3VD.
  • The ADC input voltage is 0.1V, created with a resistor divider of 10Ω and 330Ω to 3.3V.

Arduino noise measurement analogRead and analogReadFast 10/12bit with or without filterArduino noise measurement analogRead and analogReadFast 10/12bit with or without filter

In this figure, we can see that the running average size n=16 reduces the standard deviation from 1.3 to 0.25 for analogReadFast 12bit:

Arduino analogReadFast standard deviation vs size nArduino analogReadFast standard deviation vs size n

Standard deviation / noise with 10/12bit analogRead() and analogReadFast()

analogRead 10bit SD = 0.5
analogReadFast 10bit SD = 0.5
analogRead 12bit SD = 1.5
analogReadFast 12bit SD = 1.3
analogReadFast 12bit with ravg(16) SD = 0.25

Note: It is remarkeable that the noise with analogReadFast is smaller than with the slow analogRead.

This is what ATMEL says about the ADC: For optimum performance, the ADC clock should not exceed 200 kHz. However, frequencies up to 1 MHz do not reduce the ADC resolution significantly.



ADC info: bandwidth, sampling rate, Nyquist etc.

© 2023 AvdWeb. All rights reserved.