Power factor measurement using Atmel AVR Micro-Controllers
To learn about the power factor measurement, you should have a basic knowledge of power factor. There are three types of loads.
- Resistive
- Inductive
- Capacitive
When we apply AC voltage to resistive loads it will not change the current wave form. But inductive loads will force to lag the current waveform and in the case of capacitive loading it will force to lead the current waveform than voltage waveform.
You can see the waveforms of inductive load. The phase shift of 30 degree is present in the current waveform.

The power factor is basically the “angle cosine of that lagging current”. In simple words, current is lagging by voltage with some angle and if we take the cosine of that angle we will get power factor.
Now how to get that lagging angle? This is only problem left here. If somehow we can measure the time difference of both waveforms then we can find our required angle by using the formula below:
Where frequency (f) is the frequency of the system which may be 50 or 60 Hz.
Zero Cross Detection:
Zero cross detection is a method which can enable us to measure the time between voltage and current. In this technique we get a high value (i.e. 1) whenever a zero will cross the system. There are many ways to implement it. But remember, this technique is the heart of this project so implementation must be accurate. In this project we implemented zero crossing using LM358 an 8 pin IC having dual amplifiers in it. In zero crossing, we have to get a “high” value during crossing of zero in waveforms. So to get that value we use amplifier as a comparator which will compare the non inverting reference value and then act accordingly.

We will use a 16×2 LCD to show our results and ATmega 8 or ATmega16 can be used for the project. In the simulation, take upper sine generator as output of Potential Transformer (PT) and lower sine generator as output of Current Transformer (CT). The reason behind using CT and PT is, we cannot give high voltage to the IC LM358. It will burn the IC badly. So first step down the voltage and step down the current at such extent that the highest peak of current and voltage is not more than 5V. If you have no idea of using CT and PT in the real systems then see the links below.
1.AC Voltage Measurement Using Atmel AVR Microcontroller
2. AC Current Measurement Using Atmel AVR Microcontroller
Now comeback to the zero crossing method, you can see that we set the reference value of zero volts at non – inverting pin (+) of both amplifiers. So, according to comparator action it will give us high value (1) at the output whenever a zero will cross in the waveform. The output of comparators is shown below in the figure in which yellow is the output of voltage and blue is the output of current having some lag.
Implementation:


I implemented a voltage divider with PT because the output of PT will be 6 volt. 6 volt PT have peak of 1.4*6 = 8.4 volts which is harmful for the IC. So I placed a voltage divider to cut the peak to the 4.2 volts. The resistor present in front of the CT is burden resistor which is essential for CT. We never leave secondary of CT as open circuit.
Components Needed:
Click on the component name to buy the product from reliable sources:
- ATMEGA8A-PU
- Blue screen 16×2 Character LCD Display Module
- 1-phase transformers 220V/6V volt (1amp or less) or 110V/6V (1amp or less)
- 30A-Toroidal Core Current Transformer
- USB to TTL converter UART module CH340
- Resistor pack 1/4W 1%
- Printed Circuit Board
- Female Single Row Pin Headers
- Male Single Row Pin Headers
Coding part:
The code is written on codevision. You can download whole code from the link present below. If you want code for Atmel Studio email us. Here we will discuss two main functions of code.
//_________function to get the time difference_____________ void pf_func(){ while(1){ if ( PINC.4==1 ){ TCNT1=0; TCCR1B = 0x01; // Start timer at Fcpu/1 break; } else { continue; } } while(1){ if ( PINC.3 == 1 ){ TCCR1B = 0x00; //Stop timer g=TCNT1; break; } else { continue; }}}
In this function, I started the Timer1 of microcontroller when zero crossing of voltage occurs at PINC.4 and turned off the Timer2 at PINC.5 when zero crossing of current occurs. “g variable” has the final time count of the difference.
//________function to calculate the power factor______ int powerfactor(){ k=0; // To complete number of counts g=g+1; //Value from the timer //To convert into seconds pf=(float)g/1000000; //To convert into radians pf=pf*50*360*(3.14/180); //power facor pf = cos(pf); //power factor into percentage k=abs(ceil(pf*100)); return k; }
In this function, I just converted the delay into seconds and then converted that seconds into angle using the formula I mentioned above.
Warning: If you know how to handle electricity then implement this project with precautions. Don’t use any component without understanding completely about it.
If you need more help feel free to comment below and don’t forget to like our facebook page.
To download the proteus file and complete code click the buttons below.
sir, I downloaded the proteus file using above link. but it is not working, please can you send me those files,
my mail is “nadeeshankanchana.ext@gmail.com”
Hi. I am looking for the code of power factor measurement on arduino ide software. I am using atmega8 for my project. Please help me for the code at my email address humza.jawaid1997@gmail.com
i am having problem with the ground.what about all these ground.are they ground from battery/regulator or nutral from earth.pls help me.thanks
Hi,, Please do help me. Its very urgent. I would like to find the powerfactor as a part of my project. Circuits are available. but I couldnt make a program for the same. I am using aTmega 8 . And the code given above is entirely different language than I use. please do provide me a program and circuit for measuring power factor.
my gmal: pachchilllabhanu@gmail.com
Thank you so much sir!….Sir I need full code with extension pde or ino so that i can open this source file in arduino IDE directly or tell me some ways to convert c file to .pde .please mail me at 15103122-011@uog.edu.pk
https://engmousaalkaabi.blogspot.com/2017/12/power-factor-measurment-using-arduino_18.html
This one is working good
please send me the proteus file to sekhar.kc04@gmail.com
#include
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int pin = 13;
float rads = 57.29577951; // 1 radian = approx 57 deg.
float degree = 360;
float frequency = 50;
float nano = 1 * pow (10,-6); // Multiplication factor to convert nano seconds into seconds
// Define floats to contain calculations
float pf;
float angle;
float pf_max = 0;
float angle_max = 0;
int ctr;
void setup()
{
pinMode(pin, INPUT);
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop()
{
for (ctr = 0; ctr angle_max) // Test if the angle is maximum angle
{
angle_max = angle; // If maximum record in variable “angle_max”
pf_max = cos(angle_max / rads); // Calc PF from “angle_max”
}
}
if (angle_max > 360) // If the calculation is higher than 360 do following…
{
angle_max = 0; // assign the 0 to “angle_max”
pf_max = 1; // Assign the Unity PF to “pf_max”
}
if (angle_max == 0) // If the calculation is higher than 360 do following…
{
angle_max = 0; // assign the 0 to “angle_max”
pf_max = 1; // Assign the Unity PF to “pf_max”
}
Serial.print(angle_max, 2); // Print the result
Serial.print(“,”);
Serial.println(pf_max, 2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“PF=”);
lcd.setCursor(4,0);
lcd.print(pf_max);
lcd.print(” “);
lcd.setCursor(0,1);
lcd.print(“Ph-Shift=”);
lcd.setCursor(10,1);
lcd.print(angle_max);
lcd.print(” “);
//delay(500);
angle = 0; // Reset variables for next test
angle_max = 0;
}
can you give me the proteus simulation file for the for link
Just paste this code to arduino IDE
S.H.Rony can you share your final code with me plz…it will be a great help
Hi sir,
I am getting trouble in simulation on Proteus, i have made the program in Atmel studio by the same logic you used above, but its not working. kindly help me out please. Code is below.
#define F_CPU 1000000UL
#include
#include
#include
#include
#include “MRLCD.h”
unsigned char buf[10];
unsigned int k=0,x=0,g=0;
float pf;
uint16_t t;
void loop()
{
while(1)
{
if(PINA0 == 1)
{
TCNT1 = 0;
TCCR1B = 0x01;//start timer//
break;
}
else
{
continue;
}
while(1)
{
if(PINA1 == 1)
{
TCCR1B = 0x00;
g=TCNT1;
break;
}
else
{
continue;
}
}
}
}
int powerfactor()
{
k=0;
g=g+1; // to complete number of counts
pf = (float)g/1000000; // convert into seconds
pf = pf*50*360*(3.1428/180);
pf = cos(pf);
k = abs(ceil(pf*100));
return k;
}
int main(void)
{
DDRA = 0;
LCD_Init();
LCD_String_xy(0,0);
LCD_String(“POWER FACTOR”);
while (1)
{
loop();
x=powerfactor();
LCD_String_xy(1,0);
itoa(x,buf,10);
LCD_String(buf);
}
}
“The above program is display everything except The POWER FACTOR”.
Kindly help me its my final year project.
Please help me sir.
Send me the code on my mail.
i do not have mote knowledge about programming.
ashutoshpradhan1011@gmail.com
can i display current ,voltage and power? then how can i add code for same circuit..
sir I have having problem in measuring power factor ,..I am using Arduino uno… kindly help us ..as it is very urgent..
I implemented the zcd as shown in your simulation. The output of zcd-implemented on hardware-is square wave with 50% duty cycle. The LCD does not show power factor value. But “Power Factor” is displayed. Please help.
Thanks so much.. your code can help me to my skription..
This my phone whatsapp.. 🙂 +685604174884
Calibrate it, use for input signal generator Visual Analyser with knowed phase shift as a input.
hello.
excuse me sir.
if we use transformer than the transformer will shift the phase, am i right ?
so how we could measure appropiate power factor of our system ?
sir i opened your proteus file….i compiled also…it is showing only 87% as power factor if change waveforms in cro… how can i vary power factor …plz tell me
Change the Phase degree by double clicking the SINE wave input probe.
how can we get the voltage and current individually??
Study the article below:
http://engineerexperiences.com/ac-voltage-measurement.html
http://engineerexperiences.com/ac-current-measurment-1.html
Thank you for such project. Can you please explain how to use this code to implement it on arduino mega 2560?
Hello
How to convert your code for stm32f103
Regards Ted
When I compile in ATmel STUDIO 7 these errors appear:
1- recipe for target’main.o’ failed
2- mega8.h:No surch file or directory
What I do?
Use CodeVisionAVR compiler.
Hi ISMAIL
i instilled “atmel studio” but it gives an error “reciep for target ‘main.o’ failed” while building the same programe…
what i have to do now.
please help me any one…
thanks in advance
hello sir!
while building this code on ”MicroC PRO for AVR” it gives error in #include and
#include ,
i think these file are not present in its source files…
i need your help, please give me suggestion ,
The code is written on Atmel Studio. Use Atmel Studio to compile the code.
sir!!! can i have power factor correction code for this pic18
Sir as I extracted above file there are 3 file .dbk .dsn and .pwi so which file is associated with proteus schematic please help me
pf.dsn file. Open it using Proteus 8.
Can anyone say how to open that proteus file in proteus software please
Use Proteus 8 to open file.
In above senario most probably it will work according
But what for capacitive load, in which current leads and there’s 1 on pin 3 first so timer will give wrong durations
What do u think??
Yes you are right. But the issue is capacitive load is not a real world thing. It’s just an ideal assumption for calculations. You cannot achieve capacitive load while doing work on practical things.
Hi Ismail, i used your code on16f877a pic controller but it dosent gets out of loop function,
Any idea what might be the problem?? Any kind of help will be greatly appreciated
Thanks in Advance!!
Most probably problem lie in circuit. First use SPDT switches in places of comparators.
hi sir. please help me i need atmel studio code for power factor meter. please consider my request. i tried many times but i am not able to make it. so please send the code on this email address
majidmanzoor07@gmail.com
sir i have burned the hex file given in the folder but it is not working,. what should i do now ? please help me . kindly mail me the atmel studio code of this project that can be burn and can be implement.
Hi Sir. i want to implement this circuit using atmel studio, so can you please mail me the atmel studio code of this circuit? its very urgent please help me. my email address is below:
majidmanzoor07@gmail.com
Your required code is present right below the article.
Sir, I have used some of the pins of the arduino for other measuring purposes. how do i know which pin is to be connected for powerfactor? can you please provide the code that we usually use in arduino IDE. Please.
No I can’t provide you that. Instead you should study some basics of Atmel AVR microcontrollers and how to control thier pins.
Hi,, Please do help me. Its very urgent. I would like to find the powerfactor as a part of my project. Circuits are available. but I couldnt make a program for the same. I am using aTmega 328 p. And the code given above is entirely different language than I use. please do provide me a program and circuit for measuring power factor. My main project is based on Demand Response .. email id- pranavs405@gmail.com ..
Thanks..
Same code can be used for ATmega328 as well. Just use codeVisionAVR software.
i used dtostr in order to convert the float pf value into string, but its giving an error
“undefined reference to dtostr”
Use ftoa function
Sir. I read this given article but in this article only explain about the relay. i want programming of ATMEGA8 for conditions if pf less than 0.8 then PD0 (pin no.-2) goes high.
how to apply this logic in ATMEGA8 programming ?
” If pf<0.8 then PD0 (pin no.-2) goes HIGH else PD0 goes LOW "
Cause I don't know how to apply pf<0.8 and how to enable PD0 (pin no.-2) in ATMEGA8.
Thank you.
Study this article to understand I/O pins of AVR and how to control them. http://maxembedded.com/2011/06/port-operations-in-avr/
Secondly to get power factor less than 0.8, apply some inductive load or use some low wattage LED bulbs.
Sir. Which instructions can i use if pf is less than 0.7 then pin-0 of port-D goes high and connect the capacitor through the relay for improving pf.
Any examples ?
Study this article to understand relay functioning.
http://engineerexperiences.com/relay.html
Thank you so much sir.
It is worked power factor indicate between 0 to 1.
It took some minor changes.
Just this three lines are removed and it is worked.
lcd_print(“-“);
k=abs(ceil(pf*100));
lcd_print(“%”);
k=abs(ceil(pf*100));
This code is used for converting pf into percentage right.
If i remove this line then simulation not work.
How to get pf in between 0 to 1 ??
Check your mail
Sir. Is it required in this programme to convert pf into percentage ??
Because i put this line ftoa(x,2,buf);
Instead itoa but power factor indicates 88.00 instead it must be like 0.88
Sry. Sir but how to use foat function.
Can you give me any examples of this function ??
ftoa(x,2,buf);
Just put this line instead itoa function.
Thank u Ismail sir. For your quick reply.
Can u send me the code for measuring Power factor between 0 to 1. And if the Power factor is bellow 0.8 then i want any output pin of ATMEGA goes High for improving the power factor by connecting capacitor.
Because i don’t know about the programming.
Please help me sir.
Send me the code on my mail.
kotadiya46@gmail.com
Ask me anything. I will help you throughout your project but don’t force me to complete your project all by myself.
Hello, sir
I want the power factor in between 0 to 1 not in percentage.
What can i do ??
What changes can i make in this programme ???
pf = cos(pf); Take pf from this line and through ftoa function convert pf to character type and then display it on LCD.
sir.. good day to you… i have a question pertaining to the connection of PT and CT in between the load and source, if i substitute all of the PT and CT circuit with a voltage sensor and current sensor and fed it to the arduino will it work ?
why the increment ‘g=g+1’?
In timer counter formula of Atmel AVR, you will see a ‘-1’. It is the reason, I am adding +1 to complete the number of counts.
Sir can you give a suggestion for the CT ? like a brand link or Amazon link ? Because i didnt find the “1:1500” ct at the stores..I mean i didt get actually,which CT is i have to use for this project?
Use this link to get the CT. This CT is rather cheap and gives really accurate results as well.
http://s.click.aliexpress.com/e/MBaIYrj
Does it required external crystal for practical implementation..?
No it doesn’t.
can i have power factor code for atmel studio plz?
For Atmega 8
You can change this code for atmel studio. A little bit hard work will be required which will help you further in understanding the things as well.
I tried. but time difference mesurement is not correct. it can not come out from the loop. so I need help.
Can you assist me with the code in Atmel studio please IDE please, I’m having trouble with the transformation.
At which part you are having trouble?
Sorry I meant the code in arduino IDE, I am getting stuck with the function to get time difference please
Put different serial commands in loops and try to figure out at which loop and at which state of comparators you are having issue.
Dear S.H.RONY,
Please can you send me the atmel code to me.
I have done it correctly. yes, I am successful.
Happy to hear that 🙂
I AM FACING SAME ISSUE REGARDING LOOPS() WHAT YOU DID FACE SO CAN YOU PLEASE TELL ME WHAT IS SOLUTION OF THAT PLEASE REPLY ON MY MAIL ID appyra77@gmail.com.