Pages: [1]   Go Down
Author Topic: Sampling Rate  (Read 1155 times)
0 Members and 1 Guest are viewing this topic.
Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!

Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 438
Posts: 23725
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

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

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46063
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Edison Member
*
Karma: 6
Posts: leet
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It can sample about, at least, 40khz.
Google arduino fastadc.
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
God Member
*****
Karma: 3
Posts: 813
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
[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:
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]
« Last Edit: November 21, 2011, 08:46:27 pm by jwatte » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 438
Posts: 23725
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

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

Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 169
Posts: 12447
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Logged

Rob Tillaart

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

Montreal
Online Online
Edison Member
*
Karma: 23
Posts: 2486
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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/
« Last Edit: November 25, 2011, 09:08:44 pm by Magician » Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: