Pages: [1]   Go Down
Author Topic: Faster Read times for analogRead  (Read 1507 times)
0 Members and 1 Guest are viewing this topic.
Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is a sample sketch from the Arduino Cookbook -- somewhat modified...

It shows a simple method to improve (shorten) the read time for Analog Sensors on the Arduino

Code:
/*
  Sketch to demonstrate how to decrease time of analog read.
  it shortens the delay by manipulating registers and reducing the prescale
  timer value from 128 to 16;

  Note Serial Speed! Change to suit yourself!

  Sample Sketch From Arduino Cookbook by Margolis (O'Reilly Press)
  Modified by Willr March24, 2011

  Tested on Mega2560 Arduino board with an MA7361 Z output hooked to
  Sensor 5

*/

// CHANGE Sensor Pin to suit yourself...
const int sensorPin = 5;

// Change  number of entries to a value divisible by 100 only
const int numberOfEntries = 100;

unsigned long microseconds;
unsigned long duration1;
unsigned long duration2;


int results[numberOfEntries];

void setup(){
  Serial.begin(9600); ///CHANGED
  Serial.flush();
  

 // standard analog read performance -- prescale == 128
 microseconds = micros();
 for (int i=0; i < numberOfEntries; i++)
 {
   results[i] = analogRead(sensorPin);
 }
 
 duration1 = micros() - microseconds;

 Serial.print(numberOfEntries);
 Serial.print("   readings took ");
 Serial.println(duration1);

// This double loop just prints a neat table..
 for( int j=0; j < numberOfEntries; j=j+20){
   for (int i=0; i < 20; i++) {
     Serial.print(results[j+i]);
     Serial.print(",  ");
   } //end loop i
   Serial.println();
 } //end loop j
 
 Serial.println();
 
 // prescale clock to 16
 bitClear(ADCSRA,ADPS0);
 bitClear(ADCSRA,ADPS1);
 bitSet(ADCSRA,ADPS2);

 // Performance with Changeed Prescale...
 microseconds = micros();
 for (int i=0; i < numberOfEntries; i++)
 {
   results[i] = analogRead(sensorPin);
 }
 
 duration2 = micros() - microseconds;
 Serial.print(numberOfEntries);
 Serial.print("   readings took ");
 Serial.println(duration2);

 for( int j=0; j < numberOfEntries; j=j+20){
 for (int i=0; i < 20; i++)
 {
   Serial.print(results[j+i]);
   Serial.print(",  ");
 } //end loop i
   Serial.println();
 } //end loop j
 
 Serial.println();
 
 Serial.print("Ratio of read times is : ");
 Serial.println((float)duration1/duration2);
 Serial.println("********************");
 

}

void loop(){
  // empty main loop is deliberate...
  
}

Hope that helps people looking for that "faster read".  smiley-twist

Cheers!
« Last Edit: March 24, 2011, 12:11:37 pm by WillR » Logged

Just another Hacker

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

strange, it doesn't print anything to the serial port for me.

Anyway, remind me what the tradeoff is?  is there a loss of resolution or accuracy?

Also worth noting that analog reads can be done in the background at the hardware level.
Logged

Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

strange, it doesn't print anything to the serial port for me.

Anyway, remind me what the tradeoff is?  is there a loss of resolution or accuracy?

Also worth noting that analog reads can be done in the background at the hardware level.

Well -- it works for me...  smiley-lol  but....

Check the serial port rate. I tested this on a Mega2560 -- the 115200 rate may be too fast  -- so set it to 9600 and try again. Feel free to modify it and post back if it needs to be changed for other processors.


Also the registers may be different on another processor. I don't think so -- but no guarantees...

Background reading may or may not be practical. In my case I am reading multiple sensors and want as few interrupts as possible.


As for trade-offs -- my simple testing does not see one. I think it just cuts the overhead... That's the claim in the book anyway and it seems to be true.
« Last Edit: March 24, 2011, 11:17:51 am by WillR » Logged

Just another Hacker

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're creating an array of ints with 1000 elements.  With ints being two-bytes, that's a 2000 byte array.  On a Mega256 with 8k ram, that's fine.  On just about any other Arduino with 2k or less ram, just isn't going to work.  Cut it down to 100 elements and it'll work fine on even a 168.
Logged


Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're creating an array of ints with 1000 elements.  With ints being two-bytes, that's a 2000 byte array.  On a Mega256 with 8k ram, that's fine.  On just about any other Arduino with 2k or less ram, just isn't going to work.  Cut it down to 100 elements and it'll work fine on even a 168.

Done on the original post.
Logged

Just another Hacker

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Anyway, remind me what the tradeoff is?  is there a loss of resolution or accuracy?

Yes.  Per the datasheets:

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

Logged


0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thx jraskell, it is working on my 168.

A little output never hurt smiley.  I'm sure there are plenty of applications for lower resolution and faster analog.

Code:
100   readings took 11304
440,  440,  441,  441,  441,  442,  443,  443,  444,  444,  445,  445,  446,  446,  447,  448,  449,  449,  450,  451, 
452,  453,  454,  454,  455,  456,  457,  458,  459,  460,  461,  462,  462,  463,  464,  464,  465,  466,  466,  467, 
468,  469,  469,  470,  471,  472,  473,  473,  474,  474,  475,  475,  476,  477,  477,  478,  478,  478,  479,  479, 
479,  479,  479,  479,  479,  479,  479,  478,  478,  478,  478,  477,  477,  477,  477,  476,  475,  475,  474,  473, 
472,  471,  471,  470,  469,  468,  467,  466,  465,  464,  463,  462,  461,  460,  459,  458,  457,  456,  455,  454, 

100   readings took 1716
463,  463,  463,  463,  463,  463,  463,  463,  463,  463,  463,  463,  462,  462,  462,  462,  462,  462,  463,  463, 
463,  463,  462,  462,  462,  462,  462,  462,  462,  462,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460, 
460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460,  460, 
460,  459,  459,  459,  459,  459,  458,  457,  457,  457,  457,  457,  456,  457,  457,  457,  457,  457,  456,  455, 
455,  455,  455,  455,  455,  455,  455,  455,  455,  455,  454,  454,  453,  452,  452,  452,  452,  451,  451,  451, 

Ratio of read times is : 6.59
********************

Logged

Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appear to be getting full 10 bit resolution on the Mega 2560 at least. A pre-scale of 16 is not 16us -- I did not check. I suppose I could.
Logged

Just another Hacker

Pages: [1]   Go Up
Jump to: