accessing adc at faster rate

I want to take consecutive samples of voltage waveform @ 50 Hz.
What is the shortest period possible between two consecutive adc accesses using Arduino ?
Thanks.
--prasad

What is the shortest period possible between two consecutive adc accesses using Arduino ?

Using vanilla Arduino, I think around 100 to 110 microseconds.

See section 23 of the atmega datasheet:

"By default, the successive approximation circuitry requires an input clock frequency between 50
kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the
input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.
The ADC module contains a prescaler, which generates an acceptable ADC clock frequency
from any CPU frequency above 100 kHz. The prescaling is set by the ADPS bits in ADCSRA.
The prescaler starts counting from the moment the ADC is switched on by setting the ADEN bit
in ADCSRA. The prescaler keeps running for as long as the ADEN bit is set, and is continuously
reset when ADEN is low.
When initiating a single ended conversion by setting the ADSC bit in ADCSRA, the conversion
starts at the following rising edge of the ADC clock cycle.
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched
on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
When the bandgap reference voltage is used as input to the ADC, it will take a certain time for
the voltage to stabilize. If not stabilized, the first value read after the first conversion may be
wrong."

So should be much faster than 100us, more like 1-10uS.

So should be much faster than 100us, more like 1-10uS

That's quite a bit faster than the quoted absolute maximum of 76.9 kSPS (13us), or the 15 kSPS (66us) at ten bit resolution. (23.1 Features)

A normal conversion takes 13 ADC clock cycles.

On the Arduino, the ADC is clocked at 125kHz, so 13 cycles is 104us.

Ah. I was thinking 13 clock cycles referred to the 16MHz clock.

Still, plenty fast enough for 50 Hz. I think I misread OP and had 50 KHz on the brain.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11

Hi,

I´ve just tinkering today with this... Aumentar la frecuencia de muestreo (Solucionado) - #24 by system - Español - Arduino Forum (Reply 23). I´m sorry, it´s in spanish, but the code is C and a graph easy to understand.... :smiley:
It´s a 50 Hz signal (from a trafo connected to a 230V power supply plug).

It´s the first test to be sure that eveything was working as expected. I´m just working on it.
I also need a fastest serial routines to try to plot in real time...

This example achieve 35.6 kHz!! t_sample=28 us!!

#define mysize 600

unsigned long tStart;
unsigned long tEnd;
byte mydata[mysize];

void setup()
{
  Serial.begin(115200);
  
  //Prescaler
  //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
  //Configure to Prescaler=32
  bitWrite(ADCSRA,ADPS2,1);
  bitWrite(ADCSRA,ADPS1,0);
  bitWrite(ADCSRA,ADPS0,1);
  
  //Input A5
  ADMUX=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
}


void loop()
{

  tStart=micros();
  for (int i=0; i<mysize;i++)
  {
     mydata[i]=analogReadFast(); 
  }
  tEnd=micros();
  
  Serial.println("NEW ACQUISITION");
  Serial.print("tStart=");
  Serial.println(tStart);
  Serial.print("tEnd=");
  Serial.println(tEnd); 
  Serial.print("nPoints=");
  Serial.println(mysize);
  
  for (int i=0; i<mysize;i++)
  {
    Serial.println(mydata[i],DEC); 
  }
  
}

int analogReadFast()
{
	ADCSRA|=(1<<ADSC);
	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));
        return ADCH;
}

:wink:

I've been working a little more on this.
Now with the help of a small python script, I'm plotting in "real time" into KST with a frecuency of 11.7 kHz (85.02 us)!!! The ADC is in 8 bits mode.

The example is the signal acquired from a trafo connected to the AC:

PYTHON:

#! /usr/bin/env python

import serial


ser = serial.Serial('/dev/ttyUSB0', 115200);
while 1:
    n=ser.read();
    n=ord(n);
    print n;

ARDUINO:

#define mysize 1200

unsigned long tStart;
unsigned long tEnd;
byte mydata[mysize];

void setup()
{
  Serial.begin(115200);
  
  //Prescaler
  //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
  //Configure to Prescaler=32
  bitWrite(ADCSRA,ADPS2,1);
  bitWrite(ADCSRA,ADPS1,0);
  bitWrite(ADCSRA,ADPS0,1);
  
  //Entrada A5
  ADMUX=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
}


void loop()
{

  tStart=micros();
  
  //for (int i=0;i<mysize;i++)
  //frec=11761.938367443
  for (;;)
  {
    while (!(UCSR0A & (1 << UDRE0)));
    UDR0 = analogReadFast();
  }
  tEnd=micros();
  
  Serial.println("NEW ACQUISITION");
  Serial.print("tStart=");
  Serial.println(tStart);
  Serial.print("tEnd=");
  Serial.println(tEnd); 
  Serial.print("nPoints=");
  Serial.println(mysize);  
}

int analogReadFast()
{
	ADCSRA|=(1<<ADSC);
	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));
        return ADCH;
}

Original post (in Spanish) => http://arduino.cc/forum/index.php/topic,68855.30.html

:wink: