# Sampling rate of arduino?

If a input a voltage wave of 50hz and try to measure it using EmonLib.h what will be the sampling rate of ADC?
For a 16 MHz Arduino the ADC clock is set to 16 MHz/128 = 125 KHz. Each conversion in AVR takes 13 ADC clocks so 125 KHz /13 = 9615 Hz. A 50Hz wave will have a time period of 20ms. And with this i will be 192 samples in 20ms.

void setup() {
Serial.begin(9600);
}
void loop() {
long a=millis();
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
if(a<=20){
Serial.println(voltage);
}
But this codes gives me only 15 samples. Kindly tell me where am i going wrong and what is the sapling rate.?

You are confusing the sampling time of the ADC, and the running time of the loop in your sketch.

Most of the extra time that the loop takes over the sampling time is being taken up by the print statement, but the floating point arithmetic is not helping. Also remember that analogRead is not just reading the ADC, it is doing lots of things before and after. If you use emonLib - which you’re not doing with that code (despite including it), you’ll find that you can read about 50 pairs of values (voltage and current) per cycle, and that includes doing part of the calculations for average power and rms voltage and current, but significantly not doing the final part of the calculation nor printing the result nor transmitting it by radio.

If you want to run the ADC at the maximum speed, you will need to look at using the ADC in free-running mode, and using interrupts to obtain the result of the conversions. If you really need the value of each sample, you will need to store the values in an array and handle all the maths, printing etc when you have finished recording.

Each conversion bar the first. The first conversion after enabling the ADC takes 25 ADC clocks, so you might want to put a lone call to analogRead(A0) in setup() to flush out the first slow one before you start timing things. But I agree with Robert… it’ll be the call to println() that is really slowing things down.

Although I’m not so sure about: “analogRead is not just reading the ADC, it is doing lots of things before and after”. The logic for analogRead is:

setup the mux and vref
start the conversion
wait for the conversion to complete
return the result

Given the synchronous nature of its API, I’m not sure it could do any less. It takes 110 usecs Vs 104 usecs for the actual conversion. It needs to map the Arduino pin name space (e.g. “A0”) to a mux setting and that varies from Arduino to Arduino, so there’s a slight cost there of going via a lookup table.

The big cost of analogRead() is step 3 above. It spends 104 of its 110 usecs spinning waiting for the conversion to complete. The big advantage of going with an interrupt based model is that it means the CPU can get on with real work during that 104 usecs (like setting up the mux for the next conversion and processing the data from the last).

Sir,

As you said println consumes most of the time… can you please help me with an Arduino code which will only save the sensor data to a text file without using println? and later on i can use the file.

No, you cannot do that. It is getting the data out of the Arduino that takes the time. I told you what you need to do. You must store the data internally, in an array in the RAM, and then send the data when you have stopped doing the measurements. You can do that with analogRead( ), you don’t need to use interrupts if you don’t need the absolute maximum speed. You should be able to record about 200 points over 1 cycle of mains using analogRead( ) and storing the result in an array.

The very basic idea is:

``````#include <Arduino.h>

#define SIZE 200
#define inPin 0

unsigned int storedValue[SIZE];

void setup()
{
Serial.begin(9600);

for (int n=0; n<SIZE; n++)
{
storedValue[n] = analogRead(inPin);
}

for (int m = 0; m<SIZE; m++)
{
Serial.println(storedValue[m]*5.0/1024);
}

}

void loop(){ }``````