AC Power Theory - Arduino maths

Instantaneous Voltage and current

AC Voltage and current is continually alternating as the name suggests, if we draw a picture of the voltage and current waveform over time is will look something like the image below (depending on what's using power - the current waveform in blue in the diagram below is what you get if you look at the waveform of a typical laptop power supply, there's also an incandescent light bulb in there).

This image is made by sampling the mains voltage and current at high frequency, which is exactly what we do on the emontx or arduino. We make between 50 and a 100 measurements every 20 milliseconds. (100 if sampling current only and 50 if sampling voltage and current - due to speed of arduino analog read command and calculations).

Each individual sample is an instantaneous voltage or current reading.

Calculating real power

Real power is the average of the instantaneous power. The calculation is relatively straight forward on the arduino: First we calculate the instantaneous power by multiplying the instantaneous voltage measurement with the instantaneous current measurement. We sum this instantaneous power measurement over a given number of samples and divide by that number of samples:

for (n=0; n<number_of_samples; n++)
{
  // inst_voltage and inst_current calculation from raw ADC input goes here

  inst_power = inst_voltage * inst_current;

  sum_inst_power += inst_power;
}

real_power = sum_inst_power / number_of_samples;

Root-Mean-Square (RMS) Voltage

The root-mean-square is calculated in the way the name suggests first we square the quantity, then we calculate the mean and finaly the square-root of the mean-square, this is how its done on the arduino:

for (n=0; n<number_of_samples; n++)
{
  // inst_voltage calculation from raw ADC input goes here.

  squared_voltage = inst_voltage * inst_voltage;

  sum_squared_voltage += squared_voltage;
}

mean_square_voltage = sum_squared_voltage / number_of_samples;
root_mean_square_voltage = sqrt(mean_square_voltage);
 

Root-Mean-Square (RMS) Current

Same as the rms voltage calculation:

for (n=0; n<number_of_samples; n++)
{
  // inst_current calculation from raw ADC input goes here.

  squared_current = inst_current * inst_current;

  sum_squared_current += squared_current;
}

mean_square_current = sum_squared_current / number_of_samples;
root_mean_square_current = sqrt(mean_square_current);

Apparent power

apparent_power = root_mean_square_voltage * root_mean_square_current;

As RMS voltage is generally a fixed value such as: 230V (+10% -6% in the Uk) its possible to approximate apparent power without having to make a voltage measurement by setting rms voltage too 230V. This is a common practice used by domestic energy monitors.

Power factor

power_factor = real_power / apparent_power;

That's the fundamentals of AC power measurement on the emontx or an arduino.

EmonLib

We have packaged these calculations into an arduino library called EmonLib to simplify energy monitor arduino sketches. The library can be found on github here: https://github.com/openenergymonitor/EmonLib