Pages: [1]   Go Down
Author Topic: accessing adc at faster rate  (Read 3204 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26626
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What is the shortest period possible between two consecutive adc accesses using Arduino ?
Using vanilla Arduino, I think around 100 to 110 microseconds.
Logged

"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.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27418
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26626
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: May 09, 2011, 07:26:34 am by AWOL » Logged

"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.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27418
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27418
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

USA
Offline Offline
Jr. Member
**
Karma: 4
Posts: 92
If you can't fix it with a hammer, it must be an electrical problem.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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....  smiley-grin
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:
#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;
}




smiley-wink
« Last Edit: August 10, 2011, 05:01:16 pm by Igor R » Logged


0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#! /usr/bin/env python

import serial


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

ARDUINO:

Code:
#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


smiley-wink
« Last Edit: August 11, 2011, 06:01:52 pm by Igor R » Logged


Pages: [1]   Go Up
Jump to: