AC Power Theory - Arduino maths

Instantaneous Voltage and current

As the name suggests, AC Voltage and current continually alternate. If we draw a picture of the voltage and current waveform over time, it will look something like the image below. Depending on the type of load consuming power, the current waveform - blue in the diagram below - is what you get if you look at a typical laptop computer power supply. (There's an incandescent light bulb present, as well).

The image was 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 100 measurements every 20 milliseconds. 100 if sampling only current. 50, if sampling voltage and current. We're limited by the Arduino analog read command and calculation speed.

Each individual sample is an instantaneous voltage or current reading.

Calculating real power on an Arduino

Real power is the average of instantaneous power. The calculation is relatively straightforward.

First we calculate the instantaneous power by multiplying the instantaneous voltage measurement by the instantaneous current measurement. We sum the 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 finally, the square-root of the mean of the squares, this is how its done:

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). It's possible to approximate apparent power without making a voltage measurement by setting the RMS voltage to 230V. This is a common practice used by commercially available energy monitors.

Power factor

power_factor = real_power / apparent_power;

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


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

Next: AC Power Theory - Advanced maths - The code snippets on this page are expressed in strict mathematical terms.