469,312 Members | 2,496 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,312 developers. It's quick & easy.

measuring RMS Current, RMS Volatge, Power factor - any sample prog in C?

365 100+
Need to write small prog to measure RMS Current, RMS Voltage and power factor for 50HZ 8 plug power strip, any sample prog?.
Oct 14 '09 #1
37 13369
Banfa
9,064 Expert Mod 8TB
To my knowledge most power strips don't usually have a data interface.

How are you planning on physically taking the measurements? Should surely be the first question to ask before you ask the question of how you write the code to obtain and process that data.
Oct 14 '09 #2
tvnaidu
365 100+
Thanks for question. I have designed small hardware with small microcontroller to do these measurements.
Oct 14 '09 #3
Banfa
9,064 Expert Mod 8TB
OK what data interface exists on the micro control, RS232 for example?
What protocol are you using to transfer data across this interface?
Oct 14 '09 #4
tvnaidu
365 100+
This is 24 plug power strip (8 plugs are one group - 3 power boards in strip), with 3 input power cards for strip, each power card controls one power board on that 24 port strip, only one microcontroller to read all 24.

Basically I am using GPIO to select plugs on 24 plug power strip, to read Current and voltage form each plug, I have ADC on microcontroller, I select one plug at a time (840 samples per second, I have to read 24 currents form 24 plugs and 3 voltages from each group (8 plugs are one group)), select one and read ADC input, which gives value of that either I[1].....I[24] or V[1], V[2], V[3].


I am using Five GPIOs as input to a mux to fanout 32 separate input sources like below (since all other GPIO used for something else),

Current 1 00000
Current 2 00001
Current 3 00010
Current 4 00011
Current 5 00100
Current 6 00101
Current 7 00110
Current 8 00111
Current 9 01000
Current 10 01001
Current 11 01010
Current 12 01011
Current 13 01100
Current 14 01101
Current 15 01110
Current 16 01111
Current 17 10000
Current 18 10001
Current 19 10010
Current 20 10011
Current 21 10100
Current 22 10101
Current 23 10110
Current 24 10111
Current 25 11000
Current 26 11001
Current 27 11010
Current 28 11011
Current 29 11100
Current 30 11101
Current 31 11110
Current 32 11111
Oct 14 '09 #5
donbock
2,422 Expert 2GB
There must be some interface circuit between the plugs and the ADC. What sort of signal is presented to the ADC: instantaneous voltage, peak voltage, RMS voltage? Same question for current.

That is, are you obtaining RMS via hardware or via software?

By the way ... be careful. You're working with potentially lethal currents.
(That's lethal to you, I'm much less worried the microcontroller.)
Oct 14 '09 #6
tvnaidu
365 100+
Thanks for your valuable mail.

There is an interface circuit, all AC outlets are controlled through relays, relay can turn ON/OFF each plug, that is separate logic, but there is a mux between microcontroller (ADC) and relay, that is an analog MUX which gets feed current and voltage back to ADC for measurement, which gives Instaneous current and Instaneous voltage. I have to read 24 currents and 3 voltages 840 times per second (840 samples per second). I have to store those 27 readings in separate buffers, then I have to calculate average and then RMS of each 24 current and voltage.

for (count=0; count < 840; count++)
{
for(inst_curr_cnt=0; inst_curr_cnt < 24; inst_curr_cnt++)
{
set GPIO of one out of 32 and read ADC value and store
I_buff_loc[inst_curr_cnt] = ADC
}

for(inst_volt_cnt=0; inst_curr_cnt < 3; inst_curr_cnt++)
{
set GPIO of one out of 32 only Three times and read ADC value and store
V_buff_loc[inst_curr_cnt] = ADC
}

square those accumulation of each instaneous curent and voltage, then calculate rms for all 24 currents and voltages
rms_curr = accumulation of each current / 420
}


I need some logic how to calculate power factor for reach based on instaneous current and voltag, thanks in advance.
Oct 14 '09 #7
donbock
2,422 Expert 2GB
@tvnaidu
The only way I can think of to do this involves measuring the phase angle between the voltage and the current.
Oct 14 '09 #8
tvnaidu
365 100+
Hardware provides an input to ADC to measure instaneous current and voltage only, by measuring those two 840 samples per second and then store those values, accumulate, then average and get RMS of each and calculate real power, then apparent power, using those Two calculate power factor.

The Hardware doesnot provide anything besides inst. Currewnt and volatge?
Oct 14 '09 #9
Banfa
9,064 Expert Mod 8TB
You can not use instantaneous voltage and current to calculate the power factor and you need the power factor to calculate real power.

You can calculate instantaneous apparent power from instantaneous voltage and instantaneous current.

You can calculate root mean squared (RMS) values relatively easily. As the name suggests this is the square root of the mean of the squares of the value (voltage or current or power) taken of 1 period of the wave.

However for a sinusoidal wave centred on y=0 (true for instantaneous voltage and current but not power) this simplifies to the peek value divided by the square root of 2.

Expand|Select|Wrap|Line Numbers
  1.         peek value
  2.         ----------
  3.          sqrt(2)
  4.  

You will have to examine the captured data to determine the peek value numerically.

You will need to calculate the power factor because

real power = apparent power * power factor

where apparent power = Vrms * Irms

You should be able to calculate the phase different between the voltage and current by looking for the peaks in those values and determining the time difference between those 2 peaks compared to the total period for the wave.

Time the time difference in the range -wave period/2 to +wave period/2 this corresponds linearly to a phase difference of -180 degrees to +180 degrees.

Once you have the phase difference the power factor is

power factor = cos(phase difference)

Look up these pages, the explain a lot of it and have some useful graphs and equations

power factor
root mean square
Oct 14 '09 #10
Banfa
9,064 Expert Mod 8TB
On and a final point on your code, your loop 0 - 840 will not produce 840 samples per second, it will produce a burst of 840 samples.

To get 840 samples per second you need some sort timer triggering the sample mechanism. Your micro-controller probably has 1 or more timer interrupts available so you can trigger it off an interrupt.

However I would tend not to perform 27 ADC conversions and readings in an interrupt routine as it would block any other interrupt routines and ADC readings can be slow (in comparison to processor clocks). So use the timer interrupt to set a flag that the main code uses to trigger 1 set of ADC readings.

Also you can just take the read, every reading will need to be time stamped if you want to calculate the phase difference.
Oct 14 '09 #11
tvnaidu
365 100+
actually this microC had inbuilt 4/8 channel ADC, I am not using any timer interrupt for that, it had 8 ADC pins can be used as GPIO or ADC inputs, I am using 5 pins to select one of plug and one ADC input to select read current/voltage.

My question is: I have only instantaneous current and instantaneous voltage readiungs only, using those Two can I calculate real power and apparent power, then using those power readings can I calculate power factor?. My goal is to calculate power factor with instantaneous current and instantaneous voltage.

anyway below is my routine to calculate RMS current, RMS voltage from instantaneous current and voltage, also I did actual power and apparent power calculations, also I did power factor calculations. 840 times I took ADC value for inst. current and inst, voltage, the others readings (RMS CURR, RMS VOLT, ACTUAL POWER, APPARENT POWER, POWERFACT) I did for every half-second, please take a look my routine below (sorry for syntax), please see logic and let me know. appreciated.

please point me if I am wrong. appreciated you all.


Expand|Select|Wrap|Line Numbers
  1. #define SAMPLES 840 /*Total sampes per second*/
  2.  
  3. int insta_curr_read[27] = 0; /* 24 instantaneous current  */
  4. int insta_volt_read[3] = 0; /* 3 instantaneous voltage */
  5.  
  6. float insta_cumulate_curr_read[27] = 0; /* 24 cumulative currents  */
  7. float insta_cumulat_volt_read[3] = 0; /* 3 cumulative voltage */
  8.  
  9. int read_adc_val;
  10.  
  11. float rms_current[27] = 0; /* 24 RMS Current  */
  12. float rms_voltage[3] = 0; /* 3 RMS Voltages */
  13. int actual_power[24] = 0;
  14. float apparent_power[24] = 0;
  15. float power_factor[24] = 0;
  16.  
  17. int count, sample_count, curr_count, volt_count;
  18.  
  19. main_task()
  20. {
  21.  
  22.  
  23. for (sample_count=0; sample_count < SAMPLES; sample_count++)
  24. {
  25.     for(curr_count=0; curr_count < 24; curr_count++)
  26.     {
  27.     set GPIO to select curr_count;
  28.     read_adc_val = ADC value;
  29.     insta_curr_read [curr_count]+ = read_adc_val;
  30.     /* below is square the above read and acuumulate into buff */
  31.     insta_cumulate_curr_read[curr_count]   += (read_adc_val * read_adc_val) ; /* cumulative */
  32.    }
  33.     for(volt_count=0; volt_count < 3; volt_count++)
  34.     {
  35.     set GPIO to select volt_count;
  36.     read_adc_val = ADC value /*read adc */
  37.      insta_volt_read[volt_count] += read_adc_val;
  38.     /* below is square the above read and acuumulate into buff */
  39.         insta_cumulate_volt_read[volt_count]  +=  (read_adc_val * read_adc_val);   /*cumulate */
  40.    }
  41.  
  42.   /* these calculations for every Half second - for 420 samples only */
  43.   if(sample_count == 419 )
  44.   {
  45.   /* RMS calculations */
  46.    for(count=0; count<24;count++)
  47.   {
  48.    rms_current[count] = sqrt(insta_cumulate_curr_read[count] / (SAMPLES/2))
  49.   }
  50.    for(count=0; count<3;count++)
  51.   {
  52.    rms_volt[count] = sqrt(insta_cumulate_volt_read[count] / (SAMPLES/2))
  53.   }
  54.  
  55.    /* ACTUAL POWER CALCULATION (V-inst * I-inst) */
  56.    /* first 8 plug board actual power )(V-inst * I-inst) */
  57.    for(count=0; count < 8; count++)
  58.    {
  59.    actual_power[count] = int insta_curr_read[count] * insta_volt_read[1];
  60.    }   
  61.  
  62.    /* second 8 plug board use second insta. voltage reading */
  63.    for(count=8; count < 16; count++)
  64.    {
  65.    actual_power[count] = insta_curr_read[count] * insta_volt_read[2];
  66.    }   
  67.  
  68.    /* third 8 plug board use third inst. voltage reading */
  69.    for(count=16; count < 24; count++)
  70.    {
  71.    actual_power[count] = insta_curr_read[count] * insta_volt_read[3];
  72.    }   
  73.  
  74.  
  75.    /* APPARENT POWER CALCULATION, (V-rms * I-rms) */
  76.    /* first 8 plug board apparent power (V-rms * I-rms) */
  77.    for(count=0; count < 8; count++)
  78.    {
  79.    apparent_power[count] = rms_current[count] * rms_volt[1];
  80.    }   
  81.  
  82.    /* second 8 plug board apparent power (V-rms * I-rms) */
  83.    for(count=8; count < 16; count++)
  84.    {
  85.    apparent_power[count] = rms_current[count] * rms_volt[2];
  86.    }   
  87.  
  88.    /* Third 8 plug board apparent power (V-rms * I-rms) */
  89.    for(count=16; count < 24; count++)
  90.    {
  91.    apparent_power[count] = rms_curr[count] * rms_volt[3];
  92.    }   
  93.  
  94.    /* POWER FACTOR CALC */
  95.   for(count=0; count < 24; count++)
  96.   {
  97.    power_factor[count] = (actual_power[count] / apparent_power[count]);
  98.    }
  99.   } /* if count == 419 */ 
  100. }
  101.  
Oct 15 '09 #12
newb16
687 512MB
this will not compile - no space between '+' and '=': insta_curr_read [curr_count]+ = read_adc_val
And why insta_volt is only one sample per channel in power calculation?
Oct 15 '09 #13
Banfa
9,064 Expert Mod 8TB
Your calculations for all rms values, actual power are all wrong. Note your calculated apparent power and power factor will be wrong too but only because theyare based on the incorrectly calculated other values not because the calculation logic is wrong.

Starting with rms values you are

Accumulating the square of the instantaneous values
Taking the square root of: the accumulation divided by 1/2 the number of samples

This is neither the square root of the mean of the squares of the values over one period; because you do make any attempt to ensure that you are taking a set of readings that last for a single period of the sine wave. Also the accumulator is never zeroed, that means its value is always increasing so your rms values for voltage and current will always be increasing which is clearly wrong.

To calculate the RMS value you must either

capture a set of data points that last for 1 period of the sine wave and have a regular period, then use the to manually calculate the RMS value by calculating the sum of the mean of their squares.

or

detect the peak value as you take measurements and calculate the rms value using

rms = peak / sqrt(2)

Your calculation for actual power is

actual_power[count] = insta_curr_read[count] * insta_volt_read[3];

This calculates the instantaneous actual power. You then use this along with the rms apparent power to calculate the power factor. You can not mix instantaneous and rms values in an equation like this the result is meaningless.

You need to calculate the rms actual power and then you can use you equation above to get the power factor or calculate the power factor and then you can use that and the rms apparent power to calculate the rms actual power.


I didn't say you were using the timer interrupt. I said you should use the timer interrupt to ensure that you accurately spread you 840 samples across the second rather than doing them in a burst which is what happens if you just use a for loop.
Oct 15 '09 #14
donbock
2,422 Expert 2GB
Some of the formulas suggested above are only true for sinuisoidal wave forms, for example:
rms = peak / sqrt(2)
power factor = abs(cos(phase angle))

Do you have any big reactive loads on the power strip that might significantly distort the waveform?

Does it matter if your computations are inaccurate while that load is kicking?
Oct 15 '09 #15
tvnaidu
365 100+
Hi Donbock:

The plugs are used for equipemnt like computers, some servers, some switches, mainly this power strip to use in lab. that is why I need to calculate RMS values for current and voltage, later power factor.

I don't think I get peak value, but with the above reply from "Banfa", I still need to understand more how to accumulate all those instaneous values.

Let me figureout to use timer interrupt which should generate for every One second to measure 840 samples per second. instead of separate task's for loop.

I don't get peak value, I onnly gets instantaneous current and instantaneous voltages, can I use those two with Timer interrupt to calculate power factor?. thanks.
Oct 15 '09 #16
donbock
2,422 Expert 2GB
If you can trust that the waveform is sinusoidal and that the frequency is 50Hz, then ...
  • Draw a sine wave on a piece of paper.
  • Now draw some vertical lines connecting the X axis to your sine curve. Make these lines equally spaced in the X direction.
  • The vertical lines represent your ADC samples, their length is the value you read from the ADC.
  • You will begin sampling at some arbitrary part of the sine curve because your program is not synchronized to the power input; but that's ok.
  • The sample period should be N * 20mS, where N is an integer and 20mS is the period of 50Hz. (It is easiest to visualize what's happening if N=1.)
  • You can compute RMS directly from your array of samples; or you can find the maximum (ie, peak) value and divide it by sqrt(2); or you could fit a sinuisoid to your sample data and find the peak value from that.
  • You can find the phase angle by measuring the time skew between corresponding points in the voltage and current waveforms. From the phase angle you can compute the power factor.

I am still a little nervous about whether this project is safe.
  • How did you come up with the idea of doing this?
  • Are you making the hardware yourself or did you purchase a power strip with all this stuff in it?
  • What are the consequences if your software makes a mistake? Will anyone be hurt; will any equipment be damaged?
Oct 15 '09 #17
tvnaidu
365 100+
Actually I am not making Hardware, designed by hardware, I need to implement software, mainly an extra function to set GPIO and read ADC value, 5 inputs which is 2 to the power of 5 is 32, using 5 GPIO input pins select one of the current/voltage, read that and calculate those readings, Hardware provides Instantaneous current and Instantaneous voltage, I am figuringout with those can I really calculate RMS curent and RMS voltage, then those Three powers.

Sofar I never measured readings like this, that is why I am trying to understand.

I draw sinewave on paper starting positive half one side and the other half in negative side, if I draw lines parallel to Y-axis, I have 420 lines on positive side and 420 lines on negative Y-axis side, those are samples, each one is different height, if I add all of them, I gets zero because of (+)ve and (-ve).

But when I read instaneous voltage or current, not sure whether ADC gives value whether it is (-)ve or (+ve)?. I am just cumulating, may be not be correct?.
Oct 15 '09 #18
tvnaidu
365 100+
The IC was Hall-effect IC, "Hall-effect-based Linear Current sensor IC", its output is connected to one of the analog MUX, chip select the MUX (8 input and select one and read) and read value from ADC.

http://www.allegromicro.com/en/Produ.../0712/0712.pdf
Oct 15 '09 #19
Banfa
9,064 Expert Mod 8TB
@tvnaidu
No but you could use those values to calculate rms voltage and rms current to give apparent power and then use the same values to calculate instantaneous power and that to calculate rms actual power and then use apparent power and actual power to calculate power factor.

You say you only get to measure instantaneous values not peak values. I understand that, if you record enough instantaneous values then you can calculate the peak value (crudely it'll be the largest one).


About your hall effect chip.

That data sheet is actually the data sheet for 3 different parts (all part of the same range just with different performance characteristics). You need to know which part you are using.

Every part takes a current between -N and +N amps and converts it to a positive voltage. For example the +-5 amp part outputs roughly +1.5 - +3.5 volts.

That is connected to your micro-controllers ADC which then converts the value to a 16 (?) bit value. You need to look atthe ADC (micro-controller) data sheet to work out how the value is related to the input voltage and then you can work out from the posted data sheet how the value is related to the line current.

Your micro-controller ADC almost certainly doesn't measure power line voltages (240v?) so there must be some circuitry in there too to aid measuring the voltage.


And finally Don you seem to suggest in post 17 that the sample period should be greater the the mains period. That's not right whatever you are sampling your sample period wants to be less than the period of the thing you are measuring or conversely you sampling rate wants to be higher than the frequency of the of the thing you are sampling.

Slightly strangely at a sample rate of 840Hz you get 16.8 samples per mains frequency period.
Oct 15 '09 #20
newb16
687 512MB
With 24 lines to measure current on them, 840 samples per second will not be enough. You still need to measure current some 10 times per halfperiod, ( ~20000 samples/sec ) If the controller is 'generic' 8-bitter, forget about float - it will take forever, use 8*8 =16 or 16*16 = 32 multiply.
Oct 15 '09 #21
Banfa
9,064 Expert Mod 8TB
I believe the OP is talking about 850 samples per second per measured line.
Oct 15 '09 #22
tvnaidu
365 100+
It is 24 plug power strip, 3 input cards, 24 plugs divided into 3 boards inside power strip, each board had 8 plugs, means one power card for one set of 8 plugs, and second power card for another set of 8 plugs, last power card for last set of 8 plugs, total on power strip 24 plugs, if all 3 cards plugged to 3 inputs, then all 24 plug ports works. just like one big power strip with 24 plugs, 24 lamps can be connected, if all 3 input powerd connected, if only one input, then only one board woreks, each board had 8 plug ports. whether it is one board (8 plugs), or two boards (16 plugs) or 3 boards (24 plugs), I have to do measure 840 times inst. current and inst. voltage in a second. am I wrong?

----------------------------------------
------|_1_| 2_|_3_|_..........|24_|____
Oct 15 '09 #23
tvnaidu
365 100+
Hi Banfa: Thanks for the mail about hall-effect IC.

I am trying to read all these reviews and try ti understand where I did wrong in my above 100 lines program. Bascially I am going to use a timer interrupt to set the flag, then in my task, I am looking for whether flag is set or not, if flag is set, then I want to take samples and store those values in buffers and then calculate those powers, I need to calculate powers for every half a second, that is why I put a if condition at 419 to do that calculation, can you point me where I did wrong in those 100 lines?. appreciated.

I have instantaneous values stores in initial bugffers, later accumulations, later did average and RMS, then powers.
Oct 15 '09 #24
donbock
2,422 Expert 2GB
@Banfa
My mistake -- I used terms that maximized confusion. I meant to say that the overall interval within which all samples are taken should be an integral number of cycles. Ideally, the individual samples would be spread out evenly within that overall interval.

Suppose the overall sampling interval is one 50Hz cycle; and suppose you collect N samples during that overall interval (the sampling frequency is (N-1)*50Hz); and suppose you decide to consider the maximum sample value to be the peak value (ie, no curve fitting). Then, ignoring noise, the worst-case is when the actual peak happens to occur exactly halfway between two samples. The percent-error for that case is:

(sin(90deg) - sin(90deg - 360deg/(N-1))) / sin(90deg) * 100%

You can use this formula to compute the minimum number of samples/cycle to achieve any particular accuracy. As a general rule of thumb, I would prefer for the actual number of samples/cycle to be at least twice the computed minimum value, but that may be unnecessarily excessive.

I recommend that while you're collecting samples that you do nothing else. Perform all your calculations afterwards. Such an approach means that you are not tracking voltage, current, or power factor in real time.
How much latency is acceptable?
Oct 15 '09 #25
donbock
2,422 Expert 2GB
@tvnaidu
How did you come up with 840/second?
Oct 15 '09 #26
tvnaidu
365 100+
Basically this strip used to connect some servers and some computers, need to measure actual power, apparent power and PF.

I would like to setup timer for one second, each timer interrupt sets a flag, I have another task running separately looks if flag sets, then it does sampling and read ADC values and compute those powers and PF.
Oct 15 '09 #27
Banfa
9,064 Expert Mod 8TB
A 1 second timer will not work, you will still end up taking you samples in bursts of 840 samples every second with a big gap.

Imagine if I ask you to count to 10 every 10 seconds as fast as you can, you would

Spend about 2 seconds counting to 10
Spend about 8 seconds waiting for the next 10 second interval.

Your samples have to be taken on a very regular period to properly sample the input voltage and current waveforms. So what you need is a timer that goes off every 1/840 = 1.19 milli-seconds and to take 1 sample of everything every time it goes off. You need to count time or the number of timer ticks and reset all your accumulators every time the mains frequency period is up i.e. every 1/50 = 20 milli-seconds.

That is why I think 840 is a strange sample rate, because it is hard to synchronise sample time and input frequency time. (1/50) / (1/840) = 16.8 samples per mains cycle.

If you took 850 samples per second you would need a 1/850 = 1.176 milli-second timer but you have exactly 17 samples per mains cycle.

If you went further to 1000 samples per second you would have to have a 1 milli-second timer and have 20 samples per mains cycle which gives nice numbers for everything. You would get similarly nice numbers for 500 samples per second but I do not know if that gives you a high enough sampling rate to accurately take your measurements.

A also do not know if your micro-controller has the grunt to be able to sample at any of these frequencies.
Oct 16 '09 #28
donbock
2,422 Expert 2GB
@tvnaidu
You made it clear that you are doing the software, not any of the hardware. I am still unclear about where the 3 input cards and 3 power strip cards come from. Were they designed and built by one of your peers or were they purchased from some company?

@tvnaidu
Why is it so important to calculate RMS values for current and voltage, later power factor? The reason I ask is to discover what the implications are of inaccurate calculations. The severity of these implications drives the accuracy and latency requirements.

For example, if all you do is put the calculated values on a human-readable display then that tells me there is no reason to calculate new values any faster than about 5 times a second. Much faster and the numbers would change too quickly for a person to read.

For another example, the required accuracy of the power factor calculation determines the necessary accuracy and resolution of the timestamps you use to compute the phase angle.
Oct 16 '09 #29
tvnaidu
365 100+
Minimum it should nbe 840 times per Second, reason is I got 840 like this: at 7th harmonic, 7 * 60 = 420, then for two sides multiply with 2, 420 * 2 = 840. Minimum it should be 840, it can beyond 840. may be if I take 1000 samples per Second, 1/1000 = 1 ms, I want to make measurements and calculations twice for every One milli Second, these readings should give some indications like, for example, if one bulb and one fan connected, then it should howmuch power it draws total. also what it tells what is the power factor is.

I have to write software piece, Hardware manufactured somebody. Now a days these power strips are common with web interface to control each plug and shows all these power ratings.
Oct 16 '09 #30
donbock
2,422 Expert 2GB
@tvnaidu
It sounds like you expect power line harmonics. If so, then the sinuisoidal-only equations may not work well enough for you. Take a look at this article to see if you need to include Distortion Factor in your power factor calculation. (I don't know how to compute distortion factor.)

By the way, you probably want the 7th harmonic of 50Hz, not 60Hz.
Oct 16 '09 #31
tvnaidu
365 100+
Thanks for the article, I will take a look.

I re-wrote the program to measure inst. currents and voltages, then calculate other power values. Here I have timer running for 10ms (1000 samples per second, 1/1000 = 10ms, I have to take sampling not less than 840, I rounded to 1000 for easy timer), timer ISR sets a flag, in my main task, I will check if the flag is set, if the flag is set means it is one instant, I am taking only 50 instances (500 ms), then I calculate all powers, I maintain that counter locally whether it reaches 50 or not to measure powers, once power readings calculated, I reset counter to zero. for every Half second means half-of sine wave, I want to take insta. readings and store them.

below program buffers to hold vinstantaneous value only, gets overwritten for every instantaneous, where as accumulators keep accumulates all 50 instantaneous, it resets to zero after 50 instant, after measure power readings.

here below total SAMPLES defines as 100, since interrupt for every 10ms, total is 1 sec (100 * 10ms), but I use "SAMPLES/2" for RMS calculation since I am measuring only 50 readings. Please let me know whether I can use this prog.

Expand|Select|Wrap|Line Numbers
  1. #define SAMPLES 100
  2.  
  3. /* Buffer holds only instantaneous values - Total 24 current bufs */
  4. int curr_buf1 =0;
  5. ......
  6. .....
  7. int curr_buf24 =0;
  8.  
  9. /* Voltage bufs holds only instantaneous volt - total 3 for Three power boards */
  10. int volt_buf1 = 0;
  11. int volt_buf2 = 0;
  12. int volt_buf3 = 0;
  13.  
  14. /* Total 24 accumlators for current - holds summation of squares of insta. for RMS */
  15. int curr1_accu=0;
  16. .....
  17. ....
  18. int curr24_accu=0;
  19.  
  20. /* Total 3 accumlators for voltage - holds summation of squares of insta. for RMS */
  21. int volt1_accu = 0;
  22. int volt2_accu = 0;
  23. int volt3_accu = 0;
  24.  
  25. /* total 24 - actual power, instantaneous current of each board plug * that board voltage */
  26. int power1_accu = 0;
  27. .......
  28. .......
  29. int power24_accu = 0;
  30.  
  31.  
  32. /* Total 3 RMS voltages, one for each 8 plug board */
  33. float rms_volt1 = 0.0;
  34. ........
  35. ........
  36. float rms_volt3 = 0.0;
  37.  
  38.  
  39. /* Total 24 - rms currents */
  40. float rms_curr1 = 0.0;
  41. .........
  42. ........
  43. float rms_curr24 = 0.0;
  44.  
  45.  
  46. /* Total 24 apparent powers */
  47. float appa_pow1 = 0.0;
  48. .....
  49. .....
  50. float appa_pow1 = 0.0;
  51.  
  52.  
  53. /* Total 24 - power factors */
  54. float power_fact1 = 0.0
  55. ......
  56. .....
  57. float power_fact1 = 0.0
  58. int measure_power_factor = 0;
  59.  
  60.  
  61. /* These are accumulators, gets reset for every half-second */
  62.         int curr_18_AT = 0;
  63.         int curr_9_16_AT = 0;
  64.         int curr_17_24_AT = 0;
  65.  
  66.         int curr_8_BT = 0;
  67.         int curr_9_24_BT = 0;
  68.         int curr_17_24_BT = 0;
  69.  
  70.         int pow_18_AT = 0;
  71.         int pow_9_16_AT = 0;
  72.         int pow_17_24_AT = 0;
  73.  
  74.  
  75.  
  76.  
  77. main_task {
  78.  
  79.  
  80.          if (timer_isr_take_sampling_flag == TRUE)
  81.             set GPIO to select for volt;
  82.             volt_buf1 = ADC value;
  83.             volt1_accu = volt_buf1 * volt_buf1;
  84.  
  85.             set GPIO to select curr_count;
  86.             curr_buf1 = ADC value;
  87.             curr1_accu += curr_buf1 * curr_buf1;
  88.         power1_accu += volt_buf1 * curr_buf1;
  89.  
  90.             set GPIO to select curr_count;
  91.             curr_buf2 = ADC value;
  92.             curr2_accu += curr_buf2 * curr_buf2;
  93.         power2_accu += volt_buf1 * curr_buf2;
  94.  
  95.             set GPIO to select curr_count;
  96.             curr_buf1 = ADC value;
  97.             curr3_accu += curr_buf3 * curr_buf3;
  98.         power3_accu += volt_buf1 * curr_buf3;
  99.  
  100.             set GPIO to select curr_count;
  101.             curr_buf4 = ADC value;
  102.             curr4_accu += curr_buf1 * curr_buf4;
  103.         power4_accu += volt_buf1 * curr_buf4;
  104.  
  105.             set GPIO to select curr_count;
  106.             curr_buf5 = ADC value;
  107.             curr5_accu += curr_buf5 * curr_buf5;
  108.         power5_accu += volt_buf1 * curr_buf5;
  109.  
  110.             set GPIO to select curr_count;
  111.             curr_buf6 = ADC value;
  112.             curr6_accu += curr_buf6 * curr_buf6;
  113.         power6_accu += volt_buf1 * curr_buf6;
  114.  
  115.             set GPIO to select curr_count;
  116.             curr_buf7 = ADC value;
  117.             curr7_accu += curr_buf7 * curr_buf7;
  118.         power7_accu += volt_buf1 * curr_buf7;
  119.  
  120.             set GPIO to select curr_count;
  121.             curr_buf8 = ADC value;
  122.             curr8_accu += curr_buf8 * curr_buf8;
  123.         power8_accu += volt_buf1 * curr_buf8;
  124.  
  125.  
  126.         curr_18_BT = curr_buf1+curr_buf2 +curr_buf3+ curr_buf4 + curr_buf5 + curr_buf6 + curr_buf7  + curr_buf8;
  127.         curr_18_AT += curr_18_BT * curr_18_BT;
  128.         pow_18_AT += curr_18_AT * volt_buf1;
  129.  
  130.  
  131.  
  132.  
  133.             set GPIO to select for volt;
  134.             volt_buf2 = ADC value;
  135.             volt2_accu += volt_buf2 * volt_buf2;
  136.  
  137.             set GPIO to select curr_count;
  138.             curr_buf9 = ADC value;
  139.             curr9_accu += curr_buf9 * curr_buf9;
  140.         power9_accu += volt_buf2 * curr_buf9;
  141.  
  142.             set GPIO to select curr_count;
  143.             curr_buf10 = ADC value;
  144.             curr10_accu += curr_buf10 * curr_buf10;
  145.         power10_accu += volt_buf2 * curr_buf10;
  146.  
  147.             set GPIO to select curr_count;
  148.             curr_buf11 = ADC value;
  149.             curr11_accu += curr_buf11 * curr_buf11;
  150.         power11_accu += volt_buf2 * curr_buf11;
  151.  
  152.             set GPIO to select curr_count;
  153.             curr_buf12 = ADC value;
  154.             curr12_accu += curr_buf12 * curr_buf12;
  155.         power12_accu += volt_buf2 * curr_buf12;
  156.  
  157.             set GPIO to select curr_count;
  158.             curr_buf13 = ADC value;
  159.             curr13_accu += curr_buf13 * curr_buf13;
  160.         power13_accu += volt_buf2 * curr_buf13;
  161.  
  162.             set GPIO to select curr_count;
  163.             curr_buf14 = ADC value;
  164.             curr14_accu += curr_buf14 * curr_buf14;
  165.         power14_accu += volt_buf2 * curr_buf14;
  166.  
  167.             set GPIO to select curr_count;
  168.             curr_buf15 = ADC value;
  169.             curr15_accu += curr_buf15 * curr_buf15;
  170.         power15_accu += volt_buf2 * curr_buf15;
  171.  
  172.             set GPIO to select curr_count;
  173.             curr_buf16 = ADC value;
  174.             curr16_accu += curr_buf16 * curr_buf16;
  175.         power16_accu += volt_buf2 * curr_buf16;
  176.  
  177.  
  178.  
  179.         curr_9_16_BT = curr_buf9+curr_buf10 +curr_buf11+ curr_buf12 + curr_buf13 + curr_buf14 + curr_buf15  + curr_buf16;
  180.         curr_9_16_AT += curr_9_16_BT * curr_9_16_BT;
  181.         pow_9_16_AT += curr_9_16_AT * volt_buf2;
  182.  
  183.  
  184.             set GPIO to select for volt;
  185.             volt_buf3 = ADC value;
  186.             volt3_accu += volt_buf3 * volt_buf3;
  187.  
  188.             set GPIO to select curr_count;
  189.             curr_buf17 = ADC value;
  190.             curr17_accu += curr_buf17 * curr_buf17;
  191.         power17_accu += volt_buf3 * curr_buf17;
  192.  
  193.             set GPIO to select curr_count;
  194.             curr_buf18 = ADC value;
  195.             curr18_accu += curr_buf18 * curr_buf18;
  196.         power18_accu += volt_buf3 * curr_buf18;
  197.  
  198.             set GPIO to select curr_count;
  199.             curr_buf19 = ADC value;
  200.             curr19_accu += curr_buf19 * curr_buf19;
  201.         power19_accu += volt_buf3 * curr_buf19;
  202.  
  203.             set GPIO to select curr_count;
  204.             curr_buf20 = ADC value;
  205.             curr20_accu += curr_buf20 * curr_buf20;
  206.         power20_accu += volt_buf3 * curr_buf20;
  207.  
  208.             set GPIO to select curr_count;
  209.             curr_buf21 = ADC value;
  210.             curr21_accu += curr_buf21 * curr_buf21;
  211.         power21_accu += volt_buf3 * curr_buf21;
  212.  
  213.             set GPIO to select curr_count;
  214.             curr_buf22 = ADC value;
  215.             curr22_accu += curr_buf22 * curr_buf22;
  216.         power22_accu += volt_buf3 * curr_buf22;
  217.  
  218.             set GPIO to select curr_count;
  219.             curr_buf23 = ADC value;
  220.             curr23_accu += curr_buf23 * curr_buf23;
  221.         power23_accu += volt_buf3 * curr_buf23;
  222.  
  223.             set GPIO to select curr_count;
  224.             curr_buf24 = ADC value;
  225.             curr24_accu += curr_buf24 * curr_buf24;
  226.         power24_accu += volt_buf3 * curr_buf24;
  227.  
  228.         curr_17_24_BT = curr_buf17+curr_buf18+curr_buf19+curr_buf20+curr_buf21+curr_buf22+curr_buf23+curr_buf24;
  229.         curr_17_24_AT += curr_17_24_BT * curr_17_24_BT;
  230.         pow_17_24_AT += curr_17_24_AT * volt_buf3;
  231.  
  232.                 /* reste this flag, Timer ISR will this for next sampling */
  233.                 timer_isr_take sampling_flag = FALSE
  234.                 measure_power_factor ++;
  235.  
  236.            }    /* if (timer_isr_take_sampling_flag == TRUE) */
  237.  
  238.  
  239.            if (measure_power_factor == 50) {
  240.         rms_volt1 = sqrt( (volt1_accu / (SAMPLE/2) ));
  241.  
  242.         rms_curr1 = sqrt( curr1_accu / (SAMPLES/2) );
  243.         rms_curr2 = sqrt( curr2_accu / (SAMPLES/2) );
  244.         rms_curr3 = sqrt( curr3_accu / (SAMPLES/2) );
  245.         rms_curr4 = sqrt( curr4_accu / (SAMPLES/2) );
  246.         rms_curr5 = sqrt( curr5_accu / (SAMPLES/2) );
  247.         rms_curr6 = sqrt( curr6_accu / (SAMPLES/2) );
  248.         rms_curr7 = sqrt( curr7_accu / (SAMPLES/2) );
  249.         rms_curr8 = sqrt( curr8_accu / (SAMPLES/2) );
  250.         appa_pow1 = rms_curr1 * rms_volt1;
  251.         appa_pow2 = rms_curr2 * rms_volt1;
  252.         appa_pow3 = rms_curr3 * rms_volt1;
  253.         appa_pow4 = rms_curr4 * rms_volt1;
  254.         appa_pow5 = rms_curr5 * rms_volt1;
  255.         appa_pow6 = rms_curr6 * rms_volt1;
  256.         appa_pow7 = rms_curr7 * rms_volt1;
  257.         appa_pow8 = rms_curr8 * rms_volt1;
  258.  
  259.         rms_volt2 = sqrt( (volt2_accu / (SAMPLE/2) ));
  260.  
  261.         rms_curr9  = sqrt( curr9_accu / (SAMPLES/2) );
  262.         rms_curr10 = sqrt( curr10_accu / (SAMPLES/2) );
  263.         rms_curr11 = sqrt( curr11_accu / (SAMPLES/2) );
  264.         rms_curr12 = sqrt( curr12_accu / (SAMPLES/2) );
  265.         rms_curr13 = sqrt( curr13_accu / (SAMPLES/2) );
  266.         rms_curr14 = sqrt( curr14_accu / (SAMPLES/2) );
  267.         rms_curr15 = sqrt( curr15_accu / (SAMPLES/2) );
  268.         rms_curr16 = sqrt( curr16_accu / (SAMPLES/2) );
  269.  
  270.         appa_pow9 = rms_curr9 * rms_volt2;
  271.         appa_pow10 = rms_curr10 * rms_volt2;
  272.         appa_pow11 = rms_curr11 * rms_volt2;
  273.         appa_pow12 = rms_curr12 * rms_volt2;
  274.         appa_pow13 = rms_curr13 * rms_volt2;
  275.         appa_pow14 = rms_curr14 * rms_volt2;
  276.         appa_pow15 = rms_curr15 * rms_volt2;
  277.         appa_pow16 = rms_curr16 * rms_volt2;
  278.  
  279.         rms_volt3 = sqrt( (volt3_accu / (SAMPLE/2) ));
  280.  
  281.         rms_curr17 = sqrt( curr17_accu / (SAMPLES/2) );
  282.         rms_curr18 = sqrt( curr18_accu / (SAMPLES/2) );
  283.         rms_curr19 = sqrt( curr19_accu / (SAMPLES/2) );
  284.         rms_curr20 = sqrt( curr20_accu / (SAMPLES/2) );
  285.         rms_curr21 = sqrt( curr21_accu / (SAMPLES/2) );
  286.         rms_curr22 = sqrt( curr22_accu / (SAMPLES/2) );
  287.         rms_curr23 = sqrt( curr23_accu / (SAMPLES/2) );
  288.         rms_curr24 = sqrt( curr24_accu / (SAMPLES/2) );
  289.  
  290.         appa_pow17 = rms_curr17 * rms_volt3;
  291.         appa_pow18 = rms_curr18 * rms_volt3;
  292.         appa_pow19 = rms_curr19 * rms_volt3;
  293.         appa_pow20 = rms_curr10 * rms_volt2;
  294.         appa_pow21 = rms_curr11 * rms_volt2;
  295.         appa_pow22 = rms_curr12 * rms_volt2;
  296.         appa_pow23 = rms_curr13 * rms_volt2;
  297.         appa_pow24 = rms_curr14 * rms_volt2;
  298.  
  299.         power_fact1 = power1_accu / appa_pow1;
  300.         power_fact2 = power2_accu / appa_pow2;
  301.         power_fact3 = power3_accu / appa_pow3;
  302.         power_fact4 = power4_accu / appa_pow4;
  303.         power_fact5 = power5_accu / appa_pow5;
  304.         power_fact6 = power6_accu / appa_pow6;
  305.         power_fact7 = power7_accu / appa_pow7;
  306.         power_fact8 = power8_accu / appa_pow8;
  307.  
  308.  
  309.         power_fact9 = power9_accu / appa_pow9;
  310.         power_fact10= power10_accu / appa_pow10;
  311.         power_fact11 = power11_accu / appa_pow11;
  312.         power_fact12 = power12_accu / appa_pow12;
  313.         power_fact13 = power13_accu / appa_pow13;
  314.         power_fact14 = power14_accu / appa_pow14;
  315.         power_fact15 = power15_accu / appa_pow15;
  316.         power_fact16 = power16_accu / appa_pow16;
  317.  
  318.         power_fact17 = power17_accu / appa_pow17;
  319.         power_fact18 = power18_accu / appa_pow18;
  320.         power_fact19 = power19_accu / appa_pow19;
  321.         power_fact20 = power20_accu / appa_pow20;
  322.         power_fact21 = power21_accu / appa_pow21;
  323.         power_fact22 = power22_accu / appa_pow22;
  324.         power_fact23 = power23_accu / appa_pow23;
  325.         power_fact24 = power24_accu / appa_pow24;
  326.  
  327.         /* set to zero, since 50 samples are equal to Half-Second */
  328.                measure_power_factor = 0;
  329.  
  330.             /* reset all accumulatos */
  331.         curr_18_AT = 0;
  332.         curr_9_16_AT = 0;
  333.         curr_17_24_AT = 0;
  334.  
  335.         pow_18_AT = 0;
  336.         pow_9_16_AT = 0;
  337.         pow_17_24_AT = 0;
  338.  
  339.  
  340.  
  341.  
  342.  
  343.             }     /*  if (measure_power_factor == 50) */
  344.  
  345. }
  346.  
Oct 17 '09 #32
Banfa
9,064 Expert Mod 8TB
@tvnaidu
That all sounds good except 1000 samples per second = 1/1000 = 0.001 = 1ms timer not 10ms timer which is 100 samples per second.

Also please try to remember to put [code] ... [/code] tags round your code, it makes it more readable on the forum.
Oct 17 '09 #33
tvnaidu
365 100+
Thanks Banfa Sir, appreciated for your valuable time.

Actually I though instead of doing 1000 samples, I can do 100 samples, may be 100 samples may not accurate?. also I have change my timer ISR for 10ms instead 1ms, that is my mistake typing 1ms. I don't know whether I should take 1000 samples instead 100 samples. In that case all RMS calculations averate should divide by 500 instead 50. May be if I take 1000 samples, may be accurate?. Please suggest me.

I din't get that tage, please suggest me how to keep those tags?. Thanks again.
Oct 17 '09 #34
Banfa
9,064 Expert Mod 8TB
You can either type the tags or if you are using the advanced editor highlight your code and press the # button at the top right of the editor.

Starting with a sample rate of 100 per second may be a first good step. Get everything working, if less accurately before trying to get the software running at full speed.
Oct 17 '09 #35
tvnaidu
365 100+
Thanks for help, appreciated.
Oct 19 '09 #36
banfa i didn't get the actual power with this method?have you tried this method??
Jan 28 '10 #37
Banfa
9,064 Expert Mod 8TB
No I have and have never had any need to perform power factor calculations in a micro-controller (or on any other computer for that matter).
Jan 28 '10 #38

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

1 post views Thread by Fabian | last post: by
18 posts views Thread by Peter Mount | last post: by
1 post views Thread by WinstonSmith | last post: by
74 posts views Thread by Dominik Wallner | last post: by
9 posts views Thread by mathon | last post: by
9 posts views Thread by Ross | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.