Hi, I would like to get close to maximum analog read sample rate possible. I wrote a test code and got the sample rates around 3600 samples/s. Then I added a prescaler of 16 and got a sample rate of around 5500 samples/s. I am using a delay of 15 microseconds between each reading. The code is provided below. It just calculates time taken for reading and printing 10000 values:
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup()
{
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
Serial.begin(250000);
pinMode(A4, INPUT);
int a = analogRead(A4);
int i = 0;
int start = millis();// starting the timer
while (i < 10000) { // reading and printing 10000 values
a = analogRead(A4);
Serial.println(a);
delayMicroseconds(15);
i++;
}
int finish = millis();
int time_t = finish - start; // time taken for reading 10000 values
Serial.println(time_t);
Serial.println("DONE");
}
void loop()
{
}
I also tried a variation of above code and read it using serial communication using MATLAB and got around same sample rates.
The Arduino code for the variation is:
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int a;
void setup()
{
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
Serial.begin(250000);
pinMode(A4, INPUT);
}
void loop()
{
a = analogRead(A4);
Serial.println(a);
delayMicroseconds(15);
}
Please let me know if there is a way to increase the sample rate more than this.
Thanks!
jaskiratubhi:
Hi, I would like to get close to maximum analog read sample rate possible.
ATmega_328_datasheet:
By default, the successive approximation circuitry requires an input clock frequency between 50kHz and
200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency
to the ADC can be higher than 200kHz to get a higher sample rate.
...
A normal conversion takes 13 ADC clock cycles
So, at 200kHz, the best will be around 65uS/convert ~ 15,000/sec
Remove the delayMicroseconds()
The Serial.println(a) at 250000 baud will take approx. 40uS/char, 4 characters = 160uS
I think it will slow to this rate once the serial output buffer is full (i.e. about 6,000/sec)
The clock frequency should be 50-200 kHz for full 8-bit resolution. On a 16 MHz system and /128 prescaler you'd have a frequency of 125 kHz, so 9615 samples per second.
You can increase this rate - the ADC is rated up to 1 MHz so a /16 prescaler - but you lose resolution: the effective resolution is just 8 bits at that rate. But you can get almost 77,000 sps.
IIRC there's an interrupt available for the ADC, that's triggered when ready. May be useful in the "free running" mode: have it trigger an interrupt every time the reading is done, have the ISR read the registers (only the high byte or also the low byte if you're sampling at <200 kHz), and deal with the data in your code.
wvmarle:
You can increase this rate - the ADC is rated up to 1 MHz so a /16 prescaler - but you lose resolution: the effective resolution is just 8 bits at that rate. But you can get almost 77,000 sps.
Yes, but that would be a sample every 15uS or so, to output that over async serial as text you would need a baudrate of over 2Mbps
jaskiratubhi has Serial.println(a) in the timing loop