View previous topic :: View next topic |
Author |
Message |
heavenlyrider
Joined: 04 Mar 2016 Posts: 7 Location: India
|
Power factor calculation using microcontroller |
Posted: Fri Apr 07, 2017 6:56 am |
|
|
hi,
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: |
#include <18f46k22.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses hsh
#use delay(crystal=20M)
#use rs232(baud=9600,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,stream=PORT1)
#define LCD_ENABLE_PIN PIN_B3
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7
#define Sample 40
#define k_value 10
#INCLUDE <LCD.C>
#include "personal_mcp3204pic45k22.c"
#INCLUDE <math.h>
char read_count=0;
char tick=0;
unsigned int32 adc_accum_v=0;
unsigned int32 adc_accum_i=0;
unsigned int16 adc0_ref=0;
unsigned int16 adc1_ref=0;
float voltsperunit = 0.001220703125; //(volts per Unit =5/4096)
float rms_v=0;
float rms_i=0;
float rms_v_cor=1.04245;
float rms_v_accum=0;
float rms_i_accum=0;
float adc0_step=0;
unsigned int32 adc_value_v[sample];
unsigned int32 adc_value_i[sample];
unsigned int32 sampling_period=60536; // 65536-60536=5000 >> 5000x200ns=1ms
float apparent_power=0;
float average_power_accum=0;
float vi_accum=0;
char i,k;
#INT_RTCC
void RTCC_isr(void)
{
set_rtcc(sampling_period);
tick=1;
read_count++;
return;
}
void initialize() {
adc_init();
lcd_init();
delay_ms(200);
setup_timer_0(RTCC_DIV_8); //13.1 ms overflow
}
void main()
{
set_tris_b(0x01);
set_tris_d(0x80);
initialize();
adc1_ref = 2048;
adc0_ref = 2048;
adc0_step = 2.5/adc0_ref;
k=0;
while (true) {
set_rtcc(sampling_period);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while (read_count<Sample) {
while(tick==0) {}
tick=0;
adc_value_v[read_count-1] =read_analog(0,2); // channel, slave
//adc_value_i[read_count-1] = read_analog(5,1); // code for acs712 // try this pin too
adc_value_i[read_count-1] = read_analog(0,1);
}
disable_interrupts(INT_RTCC);
disable_interrupts(GLOBAL);
read_count=0;
for (i=0;i<Sample;i++) {
if (adc_value_v[i]>=adc0_ref) {adc_value_v[i] = adc_value_v[i] - adc0_ref;}
else {adc_value_v[i] = adc0_ref - adc_value_v[i];}
if (adc_value_i[i]>=adc1_ref) {adc_value_i[i] -= adc1_ref;}
else {adc_value_i[i] = adc1_ref - adc_value_i[i];}
adc_accum_v += (adc_value_v[i] * adc_value_v[i]);
adc_accum_i += (adc_value_i[i] * adc_value_i[i]);
vi_accum += ((adc_value_v[i]*adc0_step*201) * rms_v_cor) * (adc_value_i[i] * (voltsperunit/0.066));
printf("\n%fV %fI",((adc_value_v[i]*adc0_step*201) * rms_v_cor),((adc_value_i[i] * (voltsperunit/0.066))));
}
printf("\n\r\n\r\n\r");
average_power_accum += vi_accum /Sample;
vi_accum=0;
rms_v = ((sqrt(adc_accum_v /Sample))*adc0_step*201) * rms_v_cor ;
rms_i = sqrt(adc_accum_i /Sample) * (voltsperunit/0.066);
rms_v_accum += rms_v;
rms_i_accum += rms_i;
k++;
if (k == k_value) {
k=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"\f%fV %fA ",((rms_v_accum/k_value)-5),abs(((rms_i_accum/k_value)-0.03)));
delay_ms(2000);
apparent_power=((rms_v_accum/k_value)-5)*abs(((rms_i_accum/k_value)-0.03));
lcd_gotoxy(1,1);
printf(lcd_putc,"\f%0.1fW %0.1fKVA ",(average_power_accum/k_value),apparent_power);
lcd_gotoxy(1,2);
printf(lcd_putc,"PF: %f ",((average_power_accum/k_value)/apparent_power));
printf("\f%fV %fA ",((rms_v_accum/k_value)-5),abs(((rms_i_accum/k_value)-0.03)));
printf("\n%0.1fW %0.1fKVA ",(average_power_accum/k_value),apparent_power);
printf("\nPF: %f ",((average_power_accum/k_value)/apparent_power));
printf("\n\r\n\r\n\r");
rms_v_accum=0;
rms_i_accum=0;
average_power_accum=0;
}
adc_accum_v=0;
adc_accum_i=0;
}
}
|
I can measure the rms voltage, rms current and averaged power. But i have problem in measuring Power factor. 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.
This is my hardware:
[img]https://ibb.co/ncgv6F[/img] _________________ Thanks & Regards,
Heavenlyrider. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Apr 07, 2017 11:23 am |
|
|
We don't have your ADC code, which does not help.
Several approaches can be tried.
1)
You could record a series of current and voltage readings.
Then work out RMS values, real & apparent power and PF by hand.
Could be revealing.
2)
Seriously simplify, get rid of all the correction factors and fudges.
RMS values, real & apparent power will all be wrong but PF should be OK.
3)
Use a simpler load.
Say an X rated capacitor.
You SHOULD then get a PF of zero.
On UK mains 1uf gives RMS current of ~70mA.
Just a few things to try.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Apr 07, 2017 11:53 am |
|
|
Look through your samples to find the zero crossing point of the current. (interpolate between the samples each side of this point). Do the same for the voltage. Given you know your sampling rate, you can then calculate the time between these, and calculate the phase angle. Cosine of this is the PF.
Any other approach goes wrong if the waveshape goes non sinusoidal..... |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Apr 09, 2017 2:11 am |
|
|
I gave up trying to decipher your schematic.
(You appear to be using drawing methods I abandoned half a century ago.)
You seem to be assuming that voltage & current readings of 2048 coincide with zero crossings.
That's possibly not the case and unneccessary.
You are creating an array for all your current and voltages but don't use them in any real way.
I'm guessing you are working with 50Hz mains.
There is a neater way to do all your calculations which:-
1) Uses less maths, and only unsigned integers except for the final stage.
2) Does not require the use of an array.
3) Does not require you to guess at (or make assumptions about) the zero crossing point.
4) Works for both sinusoidal and non-sinusoidal waveforms.
You simply process the raw current and voltage readings as follows.
Start by resetting all the running totals to zero then do the following:-
1) Calculate Square of Voltage (V2).
2) Calculate Square of Current (I2).
3) Calculate product of Current&Voltage (IV).
Keep running totals of:-
4) Sum_of_Voltages. Sum_V
5) Sum_of_Voltages_Squared. Sum_V2.
6) Sum_of_Currents. Sum_I
7) Sum_of_Currents_Squared. Sum_I2.
8) Sum_of_Current*Voltage, Sum_IV
Assuming you have n samples you then calculate:-
9) Voltage_Mean as (Sum_V)/n. (This is the zero crossing level for the AC Voltage)
10) Voltage_RMS as SQRT(( Sum_V2 )/n - Voltage_Mean^2 )
11) Similar for Current_Mean and Current_RMS.
12) Power_Real as ((Sum_IV)/n - (Voltage_Mean)*(Current_Mean)).
13) Power_Apparent and PF are then straightforward.
14) Convert to engineering units.
At this stage you have an arrays of all your values.
Take a complete set of values and process by hand by both your method and mine.
(Or transfer to Excel and let the PC do the work)
Both methods SHOULD yield the same results.
On the other hand you could try with a small set of simple numbers and use pencil and paper.
You could take samples for multiples of 100ms (5 cycles of 50Hz, 6 cycles of 60Hz).
That way you could work on either 50/60 mains.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Apr 09, 2017 5:28 am |
|
|
OK, I had a look at the schematic and it makes NO sense to me and like Mike I have several decades of design under my belt.
The glaring problem I have is in feeding an AC voltage into the ADC chip(MCP3204) that was only designed for +ve inputs.
The second ADC (for current ) isn't needed either.
What is missing is a zero cross detector. If that was wired in, it's dead simple to aquire the voltages and currents and do the 'math'. the 'math' of course would be done in scaled integers,easily in realtime.
Also missing is a TTL<>RS232 convertor for the PC interface. Typically a MAX232 device, the 2nd section of it can be used for the aforementioned 'zero cross detector'. That clever bit of kit was done for a 'Mains frequency meter' 30 years ago, using a PIC16C84.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Apr 09, 2017 7:46 am |
|
|
Aargh.....
I must admit I hadn't seen that there was a circuit link.
Whimper. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Apr 09, 2017 11:56 am |
|
|
The key advantage of my method of calculating is that you do not need a zero crossing detector at all.
If you do use one it can be used to synchronise your sampling to the incoming signal.
That way you make measurements over several complete whole cycles.
Mike
No response from O/P so assume this topic is dead. |
|
|
heavenlyrider
Joined: 04 Mar 2016 Posts: 7 Location: India
|
|
Posted: Mon Apr 24, 2017 6:36 am |
|
|
Hi Mike,
Quote: |
The key advantage of my method of calculating is that you do not need a zero crossing detector at all.
If you do use one it can be used to synchronise your sampling to the incoming signal.
That way you make measurements over several complete whole cycles.
Mike
|
I found that the problem was in the MCP3204 library file, where the SPI function itself uses 400us delay. So that the voltage and current samples cannot be taken at the same time. i adjusted those delays, Now my program is working without any problem.
And MIKE, Thanks for your help. I tried your method too, the results seems to be pretty good than my own code. _________________ Thanks & Regards,
Heavenlyrider. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Wed Apr 26, 2017 1:16 am |
|
|
If you need to rectify the sinewave signal for the ADC without losing the Vf of the diodes, use a good Precision Detector circuit. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Apr 28, 2017 10:08 am |
|
|
heavenlyrider wrote: | Hi Mike,
Quote: |
The key advantage of my method of calculating is that you do not need a zero crossing detector at all.
If you do use one it can be used to synchronise your sampling to the incoming signal.
That way you make measurements over several complete whole cycles.
Mike
|
I found that the problem was in the MCP3204 library file, where the SPI function itself uses 400us delay. So that the voltage and current samples cannot be taken at the same time. i adjusted those delays, Now my program is working without any problem.
And MIKE, Thanks for your help. I tried your method too, the results seems to be pretty good than my own code. |
A great many ADC's cannot measure two channels simultaneously.
My usual solution is to take readings either side of each other.
In your case that would be measure Amps, Volts followed by Amps again.
If you get the timing right you can assume the average Amps reading is in effect taken at the same time as the volts reading.
Job done.
Mike |
|
|
|