How to Measure AC Power Factor Using Arduino


Introduction: How to Measure AC Power Factor Using Arduino

About: By day I am an electronic engineer for a certification and approvals company, by night I am an avid technology hobbyist and DIY'er. I enjoy learning how things work, and sharing my learning experiences with ...

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.



    • Water Contest

      Water Contest
    • Clocks Contest

      Clocks Contest
    • Creative Misuse Contest

      Creative Misuse Contest

    42 Discussions

    I am impressed after reading this wonderful instructable.. I am building a similar project by following the
    instructions on your page. However, I am getting some weird readings. I am getting my angles as:
    143, 153, 146 etc and my pf_max goes negative then. Of course, I can take just
    the magnitude but just wanted to know if it’s possible?

    I’m using this circuit for getting my

    And I have a
    (100A/333mV) CT, which I am feeding directly to my opamp.

    And then taking output of these two and
    feeding into my XOR gate. And then running your code on Arduino ide using a
    Arduino Nano on pin D4.

    Does this arrangement look right to you?
    I would really appreciate your help.

    1 more answer

    The circuit in your link is a half wave rectifier fed directly into an arduino. You can measure Voltage just fine but you can't use the same DC signal to measure PF because you need two pure AC sine waves to be fed into the comparitors.


    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

    7 more answers

    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 ?

    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.


    Question 3 months ago

    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??

    2 more answers

    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.

    I assume you are making this specific project with the LM358, and a single rail supply (i.e. 9V and GND). Your problem is you are using a single supply on your LM358 and therefore the output signal will never be lower than 0V, which is necessary for the comparators to trigger the logic gate. Easiest option is to connect a second battery to make a -9V rail in addition to +9V and GND shown in the attached.


    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.

    2 replies

    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 ;-)


    Questions like that suggest you don't know what you're doing. Yes, there are other ways but I'd stick with the current transformer if I were you (much safer). Perhaps consider simulating the input signals with the waveform generator too.

    Yes. Pretty much any comparator IC will work, it's just a zero crossing detector.