Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Power factor calculation using microcontroller

Status
Not open for further replies.

Heavenlyrider

Newbie level 5
Joined
Mar 9, 2016
Messages
10
Helped
1
Reputation
2
Reaction score
0
Trophy points
1
Location
India
Activity points
88
Hi,

I am designing a cheap Pic-micro controller based energy meter using voltage divider and hall effect sensor. I can measure the power in KWh for Resistive loads but i need to calculate the power of inductive loads. while surfing the internet, i found that "Power factor" should be measured for calculating the power of the inductive load. But the same time, all the examples given were using the 'zero crossing principle', along with voltage and current transformers. Is there any other method to find the power factor without using VT and CT?
 

Hi,
I can measure the power in KWh for Resistive loads
Power is in kW
kWh is energy

****
How do you measure current and how do you measure voltage?
If you have the instantaneous values, then:
P(t) = V(t) x I(t)
if you wnat power then you need to calculate the mean value of P() over a known time.
If you want the energy, then you need to integrate P(t).

***
The other way is to use zero cross method (but this is less exact for random waveform)

Klaus
 

hi,

How do you measure current and how do you measure voltage?


I am using voltage divider network to measure voltage, and ACS712 (hall effect sensor) to measure current. I am using MCP3204 for ADC conversion.

Here is my code.

Code:
#define array_samplei   41           
#define array_samplev   31
#define K_VALUE   6        

#define real_curcnt 31  
#define real_volcnt 14  


void main()
{              
       
      lcd_init();    
      delay_ms(100);      
      MCP3204_init();               

      lcd_gotoxy(2,1);
      printf(lcd_putc,"please wait..             ");
      delay_ms(500);    
             
                              
      delay_ms(100);
      adcv_ref=2048; 
      adci_ref=2048;
      adc0_step = 2.5/adcv_ref;   
      k=0;   
      read_count=0;


      while(true)
      {
            read_voltage(); 
            read_current();     
            real_power();            
            calculation();   
            lcd_gotoxy(1,1);          
            printf(lcd_putc,"%0.2fRv  %0.2fRi  ",voltage1,current1);
         
            lcd_gotoxy(1,2);
            printf(lcd_putc,"%0.2fiv  %0.2fii",inst_voltage,inst_current);            
            delay_ms(1000);
            
            lcd_gotoxy(1,1);          
            printf(lcd_putc,"%0.2frp  %0.2fap  ",real_power1,apparent_power);
         
            lcd_gotoxy(1,2);
            printf(lcd_putc,"%0.2fpf                 ",power_factor);
            delay_ms(1000);
             
      }
}




void read_voltage()
{
      while (read_count<array_samplev) 
      {
         read_count++;
         delay_ms(1);
         adc_value_v[read_count-1] =read_analog(0,2);   // channel, slave                   
      }
       read_count=0;

      for (i=0;i<array_samplev;i++) 
      {
         if (adc_value_v[i]>=adcv_ref) {adc_value_v[i] = adc_value_v[i] - adcv_ref;}
         else {adc_value_v[i] = adcv_ref - adc_value_v[i];}                

         adc_accum_v +=  (adc_value_v[i] * adc_value_v[i]);          
      }
   restart_wdt();    
}



void read_current()
{
    while (read_count<array_samplei) {
      
         read_count++;
         delay_ms(1);
            
         adc_value_i[read_count-1] =read_analog(5,1);   // channel, slave   0,2        
         restart_wdt();
      }
        read_count=0;
        
         for (i=0;i<array_samplei;i++) {         
         restart_wdt();   
         
         if (adc_value_i[i]>=adci_ref) {adc_value_i[i] = adc_value_i[i] - adci_ref;}
         else {adc_value_i[i] = adci_ref - adc_value_i[i];}
                           
         adc_accum_i +=  (adc_value_i[i] * adc_value_i[i]);
       }       
}

void real_power()
{
      while (read_count<real_volcnt) 
      {
         read_count++;
         delay_ms(1);
         adc_value_v[read_count-1] =read_analog(0,2);   // channel, slave                   
      }
       read_count=0;

      for (i=0;i<real_volcnt;i++) 
      {
         if (adc_value_v[i]>=adcv_ref) {adc_value_v[i] = adc_value_v[i] - adcv_ref;}
         else {adc_value_v[i] = adcv_ref - adc_value_v[i];}                        
          value_v+=adc_value_v[i];
      }
   restart_wdt();  
   VALUE_V=VALUE_V/real_volcnt;
   inst_voltage=value_v*adc0_step*201 * rms_v_cor ;
   
 
   
   while (read_count<real_curcnt) {
      
         read_count++;
         delay_ms(1);
            
         adc_value_i[read_count-1] =read_analog(5,1);   // channel, slave   0,2        
         restart_wdt();
      }
        read_count=0;
        
         for (i=0;i<real_curcnt;i++) {         
         restart_wdt();   
         
         if (adc_value_i[i]>=adci_ref) {adc_value_i[i] = adc_value_i[i] - adci_ref;}
         else {adc_value_i[i] = adci_ref - adc_value_i[i];}
                           
         value_i+=adc_value_i[i];
       }     
   restart_wdt();  
   VALUE_i=VALUE_i/real_curcnt;
   inst_current=value_i* (voltsperunit/0.066);   
}


void calculation2()
{
  rms_v = ((sqrt(adc_accum_v /array_samplev))*adc0_step*201) * rms_v_cor ;       
  rms_v_accum += rms_v;               
  
  rms_i = sqrt(adc_accum_i /array_samplei) * (voltsperunit/0.066);    
  rms_i_accum += rms_i;
  
  k++;
      
      if (k == K_VALUE) {             
         k=0;
         current1=(abs(((rms_i_accum/K_VALUE))));               
         voltage1=(rms_v_accum/K_VALUE);      
         
         if(current1<=0.250 || current1>=30.00)
         current1=0;
         if(voltage1<150)
         voltage1=0;                                 

         real_power1=inst_voltage * inst_current;
         apparent_power =voltage1*current1;         
         power_factor = real_power1 / apparent_power;            
         rms_v_accum=0;        
         rms_i_accum=0;

     }
     
      adc_accum_v=0;            
      adc_accum_i=0;
}


i can measure the rms voltage and rms current. But i have problem in measuring instantaneous voltage and current. While connecting a Ceiling Fan, My meter's power factor is always near to 0.9 but a reference meter which am i using shows 0.5 to 0.9 for various speeds. please give me some idea to rectify this problem.
 
Last edited by a moderator:

Hi,

if I am correct, then you calculculate the "rectified average" of your input signal instead of RMS.

So you need to be aware that this is only ggod for sine waveform. and you need to use the correct factor.

Klaus
 

Hi,

if I am correct, then you calculculate the "rectified average" of your input signal instead of RMS.

So you need to be aware that this is only ggod for sine waveform. and you need to use the correct factor.



could you explain with some example codes?
 

Hi,

could you explain with some example codes?
I´d say there are plenty around... this is a frequently discussed topic.
I see no need to do the research for you.

***
for apparent power calculation you need RMS values. For current and for voltage.
"true RMS" is independent of waveform (up to a dedicated frequency limit).
You use what I call "fake RMS". It is just the average of the rectified input signal.
Only for ONE special waveform you can transfer the average signal into RMS signal by a simple multiplication.

Maybe you are sure that the waveforms a pure sine, without distortion...then you may use this method.

You are free to use wikipedia: "RMS value" and "Average rectified value" ... or any other source...

May I ask why you don´t use an energy metering IC? It should give you all you want.

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top