CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Average power measurement by PIC 18f4431

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PROMOD



Joined: 01 Feb 2018
Posts: 42

View user's profile Send private message

Average power measurement by PIC 18f4431
PostPosted: Fri Mar 30, 2018 9:37 am     Reply with quote



Code:
#include<18f4431.h>
#device adc=10
#fuses xt,nowdt,nolvp
#use delay(clock=20000000)
#include "flex.c"

float k=0,a=0,r=0,p=0,pav=0;int16 i=0;

#int_timer2
void pwm_interrupt()
{
i=i+1;

set_adc_channel(0);
k=read_adc(); //convert the instantaneous voltage value of a certain moment(let t1) in channel 0
k=((k/204)-2); //calibrating the decimal value of ADC output;here offset value is 2. 10bit ADC means maximum 1023 so 1023/5=204;

set_adc_channel(1);
a=read_adc(); //convert the instantaneous current value of the certain moment t1 in channel 1
a=((a/204)-2); //calibrating the decimal value of ADC output; here offset value is 2. 10bit ADC means maximum 1023 so 1023/5=204;
p=p+a*k; //a*k= instantaneous power of the certain moment t1. p storing the summation of power of 50 different moment like t1.

if(i==49)
  {
   pav=p/i; //pav is the average of 50 different moment instantaneous value. 
   printf(lcd_putc," Average=%f", pav);
   i=0;pav=0;p=0;//setting all variable to 0.
  }
}

void main()
{
lcd_init();
setup_timer_2(t2_div_by_16,125,1); //interrupt setting time (Here in every 4*10^-4 seconds interrupt occurs) for 50 Hz signal 50 interrupts makes one complete cycle.
enable_interrupts(global);
enable_interrupts(int_timer2);
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);

while(1)
  {
  }
}

If I use 2 volt sine wave and 2 Ampere sine wave at channel 0 & 1 respectively then "pav" should be 0.637*2*0.637*2=1.623. But when I run the program it shows pav=1.9 in LCD display.

Could someone please tell me what is the problem in my coding? Thanks in advance!


Last edited by PROMOD on Fri Mar 30, 2018 11:02 am; edited 1 time in total
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Mar 30, 2018 11:00 am     Reply with quote

There are many things wrong here.

You've been shown how to do this in one of the parallel posts you're running.

One of the Mr T's has commented about your ADC setup.

I think you might need 50 samples assuming that you've got a 50Hz mains source.

Your expected average power calculation is flawed.

I suggest you draw a graph of the instantaneous power against time for one complete cycle.

It should show power as a sine wave going from 0W to 4W.
It should also be obvious from the symmetry what the average power is.

Mike


Is this real hardware or ISIS/proteus?
PROMOD



Joined: 01 Feb 2018
Posts: 42

View user's profile Send private message

PostPosted: Fri Mar 30, 2018 11:36 am     Reply with quote

Mike Walne wrote:
One of the Mr T's has commented about your ADC setup.
I have seen it. And Now I understand.

Mike Walne wrote:
Your expected average power calculation is flawed.
You mean "average power=0.637*2*0.637*2=1.623" is wrong?

Mike Walne wrote:
Is this real hardware or ISIS/proteus?
It is ISIS/proteus.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Mar 30, 2018 12:58 pm     Reply with quote

You should read the sticky called PIC101 up top.
Please note that ISIS/Proteus is NOT reliable or accurate. Think of it to PICs as what Windows (BSOD) is to PCs.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Mar 30, 2018 1:56 pm     Reply with quote

Mike Walne wrote:
Your expected average power calculation is flawed.
You mean "average power=0.637*2*0.637*2=1.623" is wrong?

Yes, it's seriously wrong.
You need to revisit your college notes.
Average REAL power is the mean time integral of instantaneous power.
What you've calculated is flawed in several ways

What you appear to have calculated is (roughly) mean_voltage * mean_current.
What you need are RMS voltage and current;
Then APPARENT power is RMS_voltage * RMS_current.
Most crude AC meters measure mean volts(or amps) and convert to RMS with a fudge factor.
If you want REAL power use the integral expression above, it gives the correct values for both sinusoidal and non-sinusoidal waveforms.

Do what I said before and plot the power/time graph.
Then you'll find the average power for your resistive load.
(For a resistive load REAL_power = APPARENT Power, resistive loads are a special case.)
Your expected power is ~20% out. As such is useless as a reference value.

Mike Walne wrote:
Is this real hardware or ISIS/proteus?
It is ISIS/proteus.
You should be using real hardware, ISIS is a complete waste of time for PICs.

Mike

I've looked through your previous posts.
You were told ~2 months ago, in no uncertain terms, to get rid of ISIS/proteus.
No one here can help you fix it.
The only proper test is to use REAL HARDWARE.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 31, 2018 5:31 am     Reply with quote

re:
Code:

if(i==49)
  {
   pav=p/i; //pav is the average of 50 different moment instantaneous value. 

Isn't 'pav' is the average of 49 values, since 'i' is 49 ?

also a and k can never be greater than .0098, if 2V is the max ADC input
though we don't know what Vref is (I'll assume VDD= 5V).

adc_clock_internal is still wrong.

Having FP math inside an ISR is wrong.

normally you sync to zero cross when doing anything with AC.....

the huge problem is that ISIS allows you to inject a PIC with AC voltage. Do that for real and POOF.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Apr 04, 2018 11:04 am     Reply with quote

I've had another look at your code

This line is wrong!
Code:
setup_timer_2(t2_div_by_16,125,1); //interrupt setting time (Here in every 4*10^-4 seconds interrupt occurs) for 50 Hz signal 50 interrupts makes one complete cycle.

To get 0.4ms interrupt interval it needs to be:-
Code:
setup_timer_2(t2_div_by_16,124,1); //interrupt setting time (Here in every 4*10^-4 seconds interrupt occurs) for 50 Hz signal 50 interrupts makes one complete cycle.

Replacing your 125 with 124 (it's in the data sheet).

Then I tried replacing your adc input with the expected data you should get.
i.e I introduced these arrays after your declarations (I've only used 32 value rather than your 50).
Code:

float data_k[32] = {409,489,566,636,698,749,787,810,
                    818,810,787,749,698,636,566,489,
                    409,329,252,182,120, 69, 31,  8,
                      0,  8, 31, 69,120,182,252,329};

float data_a[32] = {409,489,566,636,698,749,787,810,
                    818,810,787,749,698,636,566,489,
                    409,329,252,182,120, 69, 31,  8,
                      0,  8, 31, 69,120,182,252,329};


In the ISR I:-

Moved the increment i.
Replaced the read adc lines.
Adjusted the pav calculation.

So the whole ISR now looks like this:-

Code:
#int_timer2
void pwm_interrupt()
{
k=data_k[i]; //Get effective adc value
k=((k/204)-2); //Convert to engineering units (volt).

a=data_a[i]; //Get effective adc value
a=((a/204)-2); //Convert to engineering units (ampere)

p=p+a*k; //a*k= instantaneous power of the certain moment t1. p storing the summation of power of 32 different moment like t1.

i+=1; // increment loop counter

if(i==32)
  {
   pav=p/i; //pav is the average of 32 different moment instantaneous value. 
   printf(lcd_putc," Average=%f", pav);
   i=0;pav=0;p=0;//setting all variable to 0.
  }
}

Using your floating point method I'm now getting close to my expected value for the average power.
Which begs the question, why don't you? Your ISIS/Proteus generated value is in error by ~5%.
Which means you've got yet another fundamental problem!
I don't like to admit it, but, ISIS/Proteus is possibly giving you the correct answer for your flawed procedure.

BIG QUESTION (which might lead you to the correct conclusion):-

How does the time spent in your ISR compare to your expected ISR interval?
What you're measuring bears scant relation to your intention.

Mike

PS. You could increase the array sizes to 50.
You'll still find that your adc method and the array one disagree.
This will still apply when you get round to using REAL hardware.
There's a fundamental flaw in your procedure and MrT has told you what it is!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group