Skip to content

Latest commit

 

History

History

FastAnalogRead

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

#458 FastAnalogRead

How to increase the Arduino ADC analog sampling rate.

Build

Notes

The ATmega328P features a 10-bit successive approximation ADC with 8-channel analog multiplexer (to support multiple analog pins).

Three registers control the behaviour of the ADC:

  • ADC MULTIPLEXER SELECT (ADMUX)
  • ADCSRA – ADC Control and Status Register A
  • ADCSRB – ADC Control and Status Register B

ADMUX ADCSRA ADCSRB

ADC Clock Frequency Recommendation

By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. A normal conversion takes 13 ADC clock cycles.

The ADC clock may be run faster than 200kHz to get a higher sample rate, but resolution will suffer.

The data sheet quotes a sampling rate of up to 76.9kSPS, or up to 15kSPS at maximum resolution. Given that 13 clock cycles are required for a normal sample, this implies a maximum ADC frequency of up to 1MHz, or 195kHz at maximum resolution.

Default ADC Clock Frequency

The ADC clock pre-scale is set with three bits of the ADCSRA register:

ADPS2 ADPS1 ADPS0 Division Factor
0 0 0 2
0 0 1 2
0 1 0 4
0 1 1 8
1 0 0 16
1 0 1 32
1 1 0 64
1 1 1 128

The initial ADPSx values are 000 i.e. pre-scale by 2. However the Arduino core adjusts the pre-scale factor during initialisation, see wiring.c. It picks that maximum pre-scale factor given the CPU frequency to keep the ADC clock within the 50kHz-200kHz band.

At 16MHz, the Arduino code sets a pre-scale of 128 (ADPSx = 111) i.e. 125kHz.

Increasing the Sampling Rate

The FastAnalogRead.ino sketch demonstrates how to adjust the ADC pre-scaler. In the example, it is set to 16 i.e. and ADC clock frequency of 1MHz, and reads a pot on analog pin A0.

Results from a sample run:

console

FastAnalogRead
Initial ADC Settings: ADMUX = 0b0, ADCSRA = 0b10000111, ADCSRB = 0b0
100 readings with analogRead and standard prescaler = 128:
ADMUX = 0b0, ADCSRA = 0b10000111, ADCSRB = 0b0
Duration = 11312us
Read = 258, min = 258, max = 260
100 readings with analogRead and prescaler = 16:
ADMUX = 0b1000000, ADCSRA = 0b10000100, ADCSRB = 0b0
Duration = 1556us
Read = 259, min = 258, max = 259
100 readings with analogRead and standard prescaler = 128:
ADMUX = 0b1000000, ADCSRA = 0b10000111, ADCSRB = 0b0
Duration = 11256us
Read = 425, min = 425, max = 427
100 readings with analogRead and prescaler = 16:
ADMUX = 0b1000000, ADCSRA = 0b10000100, ADCSRB = 0b0
Duration = 1572us
Read = 427, min = 425, max = 428
100 readings with analogRead and standard prescaler = 128:
ADMUX = 0b1000000, ADCSRA = 0b10000111, ADCSRB = 0b0
Duration = 11252us
Read = 541, min = 540, max = 542
100 readings with analogRead and prescaler = 16:
ADMUX = 0b1000000, ADCSRA = 0b10000100, ADCSRB = 0b0
Duration = 1576us
Read = 541, min = 540, max = 543

Bandwidth

The sampling rate directly constrains the bandwidth according to the Nyquist-Shannon Theorem.

Since one conversion takes 13 ADC clock cycles:

  • at default Arduino ADC frequency of 125kHz, the bandwidth is 4.8kHz
  • at the increased ADC frequency of 1MHz, the bandwidth is 38.5kHz

Construction

Breadboard

Schematic

Credits and References