How to Measure AC Power Factor Using Arduino





Introduction: How to Measure AC Power Factor Using Arduino

Hi everyone! This is my third instructable, hope you find it informative :-) This will be an instructable on how to make a basic power factor measurement using an Arduino. Before we start theres a few things to bear in mind:

  1. This will ONLY work with LINEAR loads (e.g inductive motors, transformers, solenoids)
  2. This will NOT work with NON-LINEAR (e.g. CFL Bulbs, switch mode power supplies, LED's)
  3. I am an electrical engineer and very competent when working with mains potential (i.e. 230V)

Warning! If you are not trained or do not know how to work correctly with mains voltage I suggest you don't proceed with that part of the instructable and I will show you a safe method of proving the circuit works.

This is a hardware solution to the problem of measuring PF in linear loads. This can be also be done purely through code including the ability to measure non-linear loads, which I will aim to cover in another instructable.

For the benefit of any beginners reading this, power factor is the ratio of true power to apparent power and can be calculated by finding the cosine of the phase angle between the supply voltage and current (see attached image from Google). This is significant in AC applications as "Apparent Power" (Volt-Amperes) can be easily calculated using Voltage multiplied by Current. However to get the real power or "True Power" (Watts) apparent power must be multiplied by the power factor to make a true measurement of power in Watts. This only applies to loads which have a significant inductive or capactive component (such as a motor). Purely resistive loads such as electric heaters or incandescent bulbs have a power factor of 1.0 (unity) and therefore True Power and Apparent Power are the same.

Step 1: Circuit Design

Power factor can be calculated using an oscilloscope, by measuring the time difference between the voltage and current signal. These can be measured at any point in the wave as long as they are sampled in the same place. In this case it was logical to measure between zero crossing points (points in the wave where the voltage crossed the X-axis).

I designed the following circuit in Multisim. Assuming the current and voltage to the load are pure sinusoidal waveforms, the power factor can be measured. Each waveform is fed into a zero crossing detector (sometimes known as a sine to square wave converter) which is simply an 741 op-amp in comparator mode where the comparison voltage is 0V. When the sine wave is in the negative cycle a negative DC pulse is generated, and when the sine wave is positive a positive DC pulse is generated. The two square waves are then compared using an exclusive OR (XOR) logic gate, which will output a positive high DC pulse only when the square waves do not overlap, and 0V when they overlap. The output of the XOR gate is therefore time difference (delta t) between the two waves from the point they cross the zero point. This difference signal can then be timed by a microcontroller and converted to power factor using the following calculation (make sure your scientific calculator is in degrees not radians):

cos(phi) = f * dt * 360


cos(phi) - the power factor

f - The frequency of the measured supply

dt - delta t or time difference between the waves

360 - a constant used to give answer in degrees

In the pictures you will see three simulated oscilloscope traces for the circuit. The two input signals represent the current and the voltage to the load. I have given the second signal a phase difference of 18 Deg, to demostrate the theory. This gives a PF of approx 0.95.

Step 2: Prototyping & Testing

For my prototype build I put the circuit design on a solderless breadboard. From the UA741CN datasheet and CD4070CN datasheet both IC's run off a 12-15 Vdc supply so I powered using two batteries to make a dual rail +12V ,0V ,-12V Volt power supply.

Simulating a load

You can simulate a load by using a dual channel signal generator or function generator. I used this cheap and cheerful Chinese box to produce two 50 Hz sine waves 18 deg apart, and fed the signals into the circuit. You can see the resultant waveforms on an oscilloscope. In the pictures above you can see the two overlapping square waves (output from each op-amp), and the other three pictures are illustrating the output of the XOR gate. Notice how the width of the output pulse grows shorter with decreasing phase angle. Examples above show 90, 40, 0 Degrees.

Step 3: Arduino Code

As mentioned above, the output from the measurement circuit is the time difference between the two input signals (i.e. the current and the voltage signal). The arduino code uses "pulseIn" to measure the length of the output pulse from the measurement circuit in nano seconds and uses it in the PF formula mentioned above.

The code starts by defining constants, mainly to make the code more organised and readable. Most importantly, C code (arduino code) works in radians not degrees, so a conversion from radians to degrees is needed to calculate angle's and PF's later on. One radian is approx. 57.29577951 degrees. The number 360 is also stored and the multiplication factor 1x10^-6 for converting nano Seconds into plain Seconds. Frequency is also defined at the start, if you are using anything other than 50Hz make sure this is updated at the start of the code.

Inside "void loop()" I've told the Arduino to calculate the angle based on the PF formula mentioned earlier. On my first iteration of this code, the code would return the correct angle and power factor, however between each correct result some erroneous low value also be returned in the serial console. I noticed this was was either every other reading or every four measurements. I placed an "if" statement inside a "for" loop to store the maximum value of every four consecutive readings. It does this by comparing the calculation against "angle_max" which is initially zero, and if it is bigger stores the new value inside "angle_max". This is repeated for the PF measurement. By doing this in a "for" loop it means the correct angle and pf are always returned, but if the measured angle changes (higher or lower), when "for" ends "angle_max" resets to zero for the next test, when "void loop()" repeats. There's a very good example of how this works on the Arduino website ( The second "if" formula simply prevents any value higher than 360 being returned in the event of erroneous high being measured when the device under test is switched off.

Step 4: The Acid Test!

Do not attempt the following unless you know how to work safely with AC mains voltage. If you are in doubt as to your safety, try simulating the input signals with a dual-channel waveform generator.

At the request of a follower, I've made a breadboard layout on Fritzing to give a better idea of the circuit and sampling/sensing circuit (I have attached the .fzz file and a .png diagram). The motor at the top represents the desk fan I used, and the induction coil represents the current transformer I wrapped around the Live conductor. I powered the 741 IC's using a two 12V batteries packs arranged to give +12 VDC, 0 VDC (ground), and -12 VDC. The CD4070 can also be powered directly from the Arduino's 5V power rail.

To prove the concept works in reality, the circuit was built on a solder less breadboard. From the pictures you can see the circuit arrangement. I have used a desk fan as my inductive load to test the concept. Between the 230V mains supply and the load is my sensing equipment. I have a step down transformer which transforms 230V directly to 5V to allow the voltage waveform to be sampled. A non-invasive current transformer clamped around the live conductor was used to sample the current waveform (right of the aluminium clad resistor). Note that you do not necessarily need to know the amplitude of the current or voltage, just the waveform for the op-amp to identify the zero crossing. The above pictures show the actual current and voltage waveforms from the fan, and the arduino serial console, which reports a PF of 0.41 and an angle of 65 Deg.

This working principal can be incorporated into a home made energy monitor to make true power measurements. If your competent you can try monitoring different inductive and resistive loads and determining their power factor. And there it is! a very simply method of measuring power factor.



    • Spotless Contest

      Spotless Contest
    • Science of Cooking

      Science of Cooking
    • Microcontroller Contest

      Microcontroller Contest

    We have a be nice policy.
    Please be positive and constructive.


    6 Questions


    I really thank you a lot for your effort and your work and that you are still replying to the questions, you provided a multism schematic plus a fritzing schematic to try to make as clear as possible to us, I thank you again and I appreciate it so much but actually one thing did not make sense to me, please if you explain it:

    in the fritzing schematic, there are two wires coming out of each op amp ic (pin4) and both of them are to be connected to ground, but they are connected to another line, the lower one, the one above it is the ground, so i really do not understand why we connected only these two pins to a line which is neither high or low, connecting them like this is connecting pin 4 of the first ic to pin 4 of the second one.

    The same notice, about the two two red wires which are to be connected to the high rail.

    I am waiting for your explaination and thanks a lot

    another question on something else, how will the XOR gate sense the two input signals if its powered off a different source ? should not they be sharing the same source ?

    Sorry I've given you pleanty of help now. Everything you need is here.

    yes I will, and I will also be waiting for your next instructable on dual rail suppliers, but please can you answer my previous question, that would be great help :)

    Seriously, If you are confused just use the multisim schematic and the pinout for the uA741 and you can wire it up in the way you understand best. Here, I've attached the pinout from Google and the TI datasheet.


    aha so if its about the dual rail supplies, then that means the two lines at the bottom are on the same potential, and the two lines at the top are also on the same potential ? and that pin 2 and pin 4 are connected to the same potential (-12V) ? and that if you connect pin 4 to the first line or the second one its the same ?

    PIn4 is not connected to Ground, it is connected to -12V. Notice pin7 of the op amp is connected to +12V. Ground which is 0V is exactly halfway between +12V and +12V of the two batteries. There seems to be alot of confuse about how dual rail supplies work, it's actually quite straight forward. If you follow me I will put up an instructable in the next couple of weeks.


    Sir I am using a regulator IC and 9V battery to supply 5v to opamp IC.The problem is battery is getting drained too quickly like in an hour or 2.What might be the problem??

    The regulator is draining the battery since it has to drop 4V across it to give you 5V output. The LM358 will work with any supply up to 32V, you do not need the regulator! Have a look at the datasheet, you may also want to Google about "Virtual Earth" regarding op-amps, and DC biasing if you don't have a positive & negative supply.


    You talk about current transformers, but illustrate a Rogowski coil. Which is used ?

    Do you mean a real CT, or a hallsensing CT ? If you use a real CT, then you need the usual warnings.

    In addition to my previous comment. I believe readers of my instructables should not work with live electricity unless they are skilled in the art. I have given readers the option of using a signal generator to simulate the input signals.

    steveastrouk. It is an encapsulated current transformer same one used in my first instructable (Pic attached HMCT103C). I can only assume you make reference to the Fritzing diagram since I do not illustrate said devices in my Instructable. I apologise for the crudity, I didn't have time to make it to scale or paint it ;-)


    can i have simulation files and circuit diagram in detail !!!

    Please be more specific. There are already two schematics published here and more than enough information for you to do this yourself. If you need anything else you need to tell me exactly what it is. Asking politely wouldn't hurt you either.

    Thanks. Hope will help you to implement pf with arduino in advance measurements.

    Thanks but I don't need to go that deep into it. It's an impressive project for a DIY'er though! I made this instructable just to show people how easy it is to make a basic PF measurement. Hope it has been informative to a few people.

    I'm not sure what you're referring to? sure, you can quite easily add something like a 16x2 lcd if you didn't want to use the serial monitor to print the results.

    Hi Mousa, I'll answer the questions in the order which you have raised them. Number 1: I don't see how that method is much different from mine (except for a few shorter lines of code perhaps). It would be interesting for you to demonstrate which one is more accurate. Number 2: Firstly look at the uA741 datasheet. It requires a dual rail supply to detect both negative and positive half cycles. Secondly It's output is limited to within 2V of its supply rails, so using it with a single supply rail (i.e. 12V and 0V GND) will output will be 10V when the output is "HIGH" and 2V when the output is "LOW". Using the 741 with a single supply is problematic with TTL level MOSFETS as they will often switch "ON" with as little as 0.7V. If you don't fancy using a dual rail supply just use an op-amp like the LM358 which can ouput near 0V in the "LOW" condition.