Hi,
this is a general knowledge question asking.
I feel that the analogRead(Ax) speed say number of readings in a certain period of time dramatic changes in different Sketch.
I don't have a specific sketch and specific readings frequency yet, just feeling, may wrong?
Read the data sheets for the processor in question. For the Uno and Nano, etc. the processor is stopped for two clock cycles while the analog read is being done. This is to avoid noise accoding to the data. Other processors may not do this.
The speed of an analogRead can be controlled by the pre scaler register, code can change this value to make it faster or slower. However if you make it too fast you loose some of the accuracy in the least significant bits.
The ADC clock runs at 125 kHz on an Arduino UNO. It has to be slower than 200 kHz to get all 10 bits of resolution but with the limited selection of prescale values, 125 kHz is the highest available rate below 200 kHz.
An ADC read takes 13 ADC clock cycles, so about 9615 Hz (a little under 10,000 samples per second). This has to be shared across multiple inputs if you use more than one. All of the input pins go to the same ADC so there is no advantage or disadvantage to using any particular pin or pins.
If you don't need all 10 bits of resolution you can change the clock to 250 kHz, 500 kHz, or 1 MHz to get close to 20,000, 40,000 or 80,000 samples per second.
How fast are you trying to read and what's the frequency of the signal you're trying to measure? This might not really be an issue, or it might be a problem that's impossible to solve.
And then what are you trying to do? i.e. If you read an audio signal the raw data will "look random" (even if it's a constant sine wave). If you want to re-construct the original analog or display the analog waveform you have to know the sample rate, and if you really want to do it "right" you need a smoothing filter.
actually, I am not looking for how fast or how slow the sampling-rate is, what I really need is just a common speed whatever it is, my concern is why the sampling-rate vary so much, say in one sketch read 50 times, and got only 3 times in another sketch.
As you were told in reply #2 it depends on what else you are doing with your sketch. The speed of an analogRead is constant for any one prescaller setting.
put here avoid a new post.
I found a so-call 'ADC Free Running mode' sketch as below, question is how to get the real value read from ADC (A0), Serial.print(x)? where can put it?
Thanks.
int numSamples = 0;
long t, t0;
void setup ( )
{
Serial.begin(115200);
Serial.println("xxx_setup!");
Serial.print("File : "), Serial.println(__FILE__);
const char compile_date[] = __DATE__ " " __TIME__;
Serial.print("Compile timestamp: ");
Serial.println(compile_date);
//pinMode (A0 , INPUT) ;
ADCSRA = 0; // clear ADCSRA register
ADCSRB = 0; // clear ADCSRB register
ADMUX |= (0 & 0x07); // set A0 analog input pin
ADMUX |= (1 << REFS0); // set reference voltage
ADMUX |= (1 << ADLAR); // left align ADC value to 8 bits from ADCH AREGISTER
// sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles]
// for Arduino Uno ADC clock is 16 MHz and a conversion takes 13 clock cycles
//ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // 32 prescaler for 38.5 KHz
ADCSRA |= (1 << ADPS2); // 16 prescaler for 76.9 KHz
//ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // 8 prescaler for 153.8 KHz
ADCSRA |= (1 << ADATE); // enable auto trigger
ADCSRA |= (1 << ADIE); // enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); // enable ADC
ADCSRA |= (1 << ADSC); // enable ADC measurement
}
ISR (ADC_vect)
{
byte x = ADCH; // read 8 bit value from ADC
numSamples++;
}
void loop ( )
{
if (numSamples >= 1000)
{
t = micros ( ) - t0 ; // calculate elapsed time
Serial.print ( "Sampling frequency:" ) ;
Serial.print ( ( float )1000000 / t) ;
Serial.println ( "KHz" ) ;
delay (2000) ;
// restart
t0 = micros();
numSamples = 0;
}
}
The thing about the free running mode is that it doesn't do an analogue read any faster but if you are clever it allows you to do some other things while it is doing the conversion. Providing that is, that these other things take less time than a conversion. You have to set off a conversion, do the other things like storing the previous sample in an array and incrementing the array pointer. You then end up in a short loop waiting for the end of conversion flag, to indicate that the conversion has finished and the results registers are ready to read.
A good example of this technique is to be found in many FFT libraries where they use it to get a sample in as quickly as possible. Also normally you disable the interrupts from timer zero, which looks after background tasks like updating the millis and micros counts. This ensures that your code is not interrupted by these tasks and the sample rate is as constant as possible. You find this in FFT examples as well.
firstly I‘d like to clarify that the 'free running mode doesn't do an analogue read any faster' ? my misunderstanding?
secondly if the 'free running mode' make it possible to allow to do some other things while it is doing the conversion, it is good enough for my purpose, are there any examples please. for example, if I can get a count of number of the reading times in a certain time say 10ms.