Go Down

Topic: Sampling Rate (Read 1 time) previous topic - next topic

Hi!

Before I ask my question, I thought I'd first check my logic:
The arduino uno has a clock speed of 16 MHz, and going by atmel's claim that the 328 can execute 1 MIPS/MHz, that means the uno executes code at 16 MIPS.  Now, I would assume that if I were sampling an analog signal, the sampling rate would be 16 MHz.

Is it possible to pre-scale the clock so I could sample the signal at, say, 8 kHz?

ex- The for loop would sample the signal at 8 kHz until 100 samples have been added into the array:

for(int i = 0 ; i <100; i++){
    array = analogRead(A0);
}

I'm not even sure if I'm following the right logic.

Thanks!


CrossRoads

"Now, I would assume that if I were sampling an analog signal, the sampling rate would be 16 MHz."
If you read the atmega328 datasheet, you will see this is not possible.
The onboard ADC uses sample & hold capacitor that charges up, and is then converted to a digital value.
As the arduino code is written, the sampling rate maxes out at about 10 KHz.

You can write a while loop running at 0.125mS (125uS) for 8KHz sampling rate, maybe like this:
Code: [Select]

int analogArray[100]; // elements are indexed 0 to 99
unsigned long currentTime = micros();
for (x = 0; x<100; x=x+1){
while ( (micros() >= (x*125000UL) {
analogArray[x] = analogRead(A0);
analogArray[x] = analogRead(A0);  // read twice, ignore the first, allows for sample/hold settling
// guess would actually sit in here reading until the 125uS passed
} // end while
} // end for:next
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.

PaulS

Even if analogRead() executed in one clock cycle (it does not, by a long ways), at 8MHz, you'd have one clock cycle per read to deal with the returned value. What would you do with that one clock cycle?

sbright33

It can sample about, at least, 40khz.
Google arduino fastadc.
If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

jwatte

#4
Nov 22, 2011, 02:10 am Last Edit: Nov 22, 2011, 02:46 am by jwatte Reason: 1
Code: [Select]
[quote author=CrossRoads link=topic=79714.msg602336#msg602336 date=1321844912]
[code]
unsigned long currentTime = micros();
for (x = 0; x<100; x=x+1){
while ( (micros() >= (x*125000UL) {

[/quote]

That looks like an infinite loop to me. It also looks like it will sample at 8 Hz rather than 8 kHz.
I imagine what you really meant was to make the while() statement look like:

Code: [Select]

while (micros() - currentTime < (x + 1)*125UL) {
 ...
}


And, because micros() is a function, and you're doing 32-bit math, the loop itself probably has significant overhead. But at 16 MHz, you do 2,000 instructions per 8 kHz sample, so as you say, you'll probably be running the loop many times per sample (which isn't bad in itself).
[/code]

CrossRoads

I think the idea in general is conveyed, even if I did get the comparison backwards (typo, yeah, that's the ticket) and am off by a factor of 1000
(0.000125 = 0.125mS = 125uS, so somewhere along the line I picked up some extra 0's ...)
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.

Thanks all!  I would guess that the 125 µs would be subject to some tweaking as well to make up for the time lost when executing the while loop - but even 125 µs should be good enough.

Njay

In theory (and probably in practice too) you can achieve ~77 Ksps sampling rate on an AVR, with 8 bit precision. But to get there you need to forget about the Arduino ADC sw layer and program directly the ADC registers (not difficult), and also condition your signal appropriately.

robtillaart

Quote
But to get there you need to forget about the Arduino ADC sw layer and program directly the ADC registers (not difficult), and also condition your signal appropriately.


Can you show how?

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Magician

#9
Nov 26, 2011, 03:06 am Last Edit: Nov 26, 2011, 03:08 am by Magician Reason: 1
There is a project, with variable sampling rate. Upper limit 5.7 usec/sample or 175 kHz.
http://arduino.cc/forum/index.php/topic,63186.msg458799.html#msg458799
http://oscilloscopeexpress.blogspot.com/

WizenedEE


Quote
But to get there you need to forget about the Arduino ADC sw layer and program directly the ADC registers (not difficult), and also condition your signal appropriately.


Can you show how?


There's a fine example in arduino-00xx/hardware/arduino/cores/arduino/wiring_analog.c and the datasheet for the 328 is certainly helpful.

Go Up