# Constant Sample Rate

I am building a Arduino based AC power monitor with analogue inputs (A0) and (A1) measuring voltage and current respectively. I need to sample the voltage and current waveforms at a constant rate in order to obtain accurate results when calculating power.
I am aware that the Arduino ADC clock is set to 16MHz/128 = 125KHz. Each conversion takes 13 ADC clocks so 125KHz/13 = 9615Hz. However i have soon discovered this is not an accurate representation of the actual sample rate as it depends on the interval between successive conversions calls, basically the sample rate constantly changes as I add and remove things from the code.
I need a constant sample rate for accurate results when calculating power, i have found the ‘blinkwithoutdleay’ example online and thought this was along the right tracks however struggled to incorporate into my code. Any ideas what i need to do to obtain a constant sample rate? My code is shown below.

int voltage, current, P, S;
float realPower,IRMS, APower, Average, AvPower, RPower, PF, Sumsqr = 0;
void setup() {
Serial.begin(115200);

}
void loop() {
for(int i=0;i<2000;i++) {

P = voltagecurrent;
S = current
current;

realPower=realPower+abs(P);
Sumsqr = Sumsqr+abs(S);

Average = Sumsqr / 2000;
IRMS = (sqrt(Average)/167);
APower = IRMS*230;

AvPower=(realPower/2000);
RPower = AvPower*0.00682635;

PF = (RPower/APower); // Power Factor calculated by doing Real power divided by Apparant Power
delay(0.5);

Serial.println(i);

Serial.print("Real Power: “);Serial.print(RPower);Serial.print(” W ");

Serial.print("Apparant Power: “);Serial.print(APower);Serial.print(” VA ");

Serial.print("Power Factor: ");Serial.println(PF);

}

}

One way to get the ADC to sample at a known constant frequency would be to trigger the read in an interrupt routine, and use a timer interrupt. I think you can reduce the prescale divider on the ADC clock, but this will increase power consumption a bit.

You'll have to make sure that all your calculations can be done fast enough. Floating point is a lot slower than integer maths, so it would be a good idea to do as much as possible as int. You may need to get creative with your maths to do it all in integer - or at least, integers modelling fixed point arithmetic. Even if you just do the sqrt() as float, that may be enough to make a difference in it working or not.

Also, I'm not sure what your delay(0.5); statement after the Power Factor calculation is meant to do, but it probably doesn't do what you think it does. delay() takes an integer argument in miliseconds, and it's probably not a good idea to introduce additional delays in what is effectively going to be fairly time critical code.

Good luck!

insteed of `delay(0.5);`

use

``````micros(500);
``````

but best is using timers

Have you seen the Arduino projects to monitor AC power at the OpenEnergyMonitor.org site?