Go Down

### Topic: accessing adc at faster rate (Read 5154 times)previous topic - next topic

##### May 07, 2011, 08:55 am
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.

#### AWOL

#1
##### May 07, 2011, 04:41 pm
Quote
What is the shortest period possible between two consecutive adc accesses using Arduino ?

Using vanilla Arduino, I think around 100 to 110 microseconds.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#2
##### May 08, 2011, 06:41 am
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
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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### AWOL

#3
##### May 09, 2011, 02:21 pmLast Edit: May 09, 2011, 02:26 pm by AWOL Reason: 1
Quote
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)

Quote
A normal conversion takes 13 ADC clock cycles.

On the Arduino, the ADC is clocked at 125kHz, so 13 cycles is 104us.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#4
##### May 09, 2011, 05:38 pm
Ah. I was thinking 13 clock cycles referred to the 16MHz clock.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#5
##### May 09, 2011, 05:38 pm
Still, plenty fast enough for 50 Hz. I think I misread OP and had 50 KHz on the brain.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### JimEli

#6
##### May 16, 2011, 04:50 pm
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11

#### igorreal

#7
##### Aug 10, 2011, 11:28 pmLast Edit: Aug 11, 2011, 12:01 am by Igor R Reason: 1
Hi,

I´ve just tinkering today with this... http://arduino.cc/forum/index.php/topic,68855.msg510474.html#msg510474 (Reply 23).  I´m sorry, it´s in spanish, but the code is C and a graph easy to understand....
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!!
Code: [Select]
`#define mysize 600unsigned 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;}`

#### igorreal

#8
##### Aug 12, 2011, 12:55 amLast Edit: Aug 12, 2011, 01:01 am by Igor R Reason: 1
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:

Code: [Select]
`#! /usr/bin/env pythonimport serialser = serial.Serial('/dev/ttyUSB0', 115200);while 1:    n=ser.read();    n=ord(n);    print n;`

ARDUINO:

Code: [Select]
`#define mysize 1200unsigned 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

Go Up