PDA

View Full Version : Math help please!!!



jbirnsch
- 8th August 2007, 17:53
I am building a watt meter around a Allegro ACS755-50 hall effect curent sensor. The output is scaled so that 0 to 4.995V = 0 to 50ADC. I also have a /11 voltage divider to measure up to 55Vdc. I am having a hard time trying to calculate Watts with this integer math stuff. The current and voltage measurements are dead on. The problem I am having is that my voltage and current reading are split into a byte.word configuration. How to carry the remainder of the word over to the byte so that my calculation is correct. I am now trying to just myultiply the word vars together but that isn't working either....Here is my code so far:

DEFINE OSC 20

DEFINE ADC_BITS 10
DEFINE ACD_CLOCK 3
DEFINE ADC_SAMPLEUS 200
INCLUDE "modedefs.bas"

ADCON0 = %11000001
ADCON1 = %11000000

' Define LCD registers and bits
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 3
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 2
'Pulsin definations
'define pulsin_max 1000
'Button Variable
B0 var byte

B0 = 0

'Misc. VAR's and CON's
BDLY con 20
maxim var word
Position VAR WORD ' Servo position data
Y VAR BYTE ' Servo position update speed
Servo var PortC.2 ' PortB.4 = left servo output
AD_Raw Var Word ' 10-bit result of A/D conversion
AD_Result Var Word ' Quantasized ADC result
AD_Result1 Var Word ' Quantasized ADC result
Average Var Word ' Variable for building up the average result
Samples Var Byte ' Amount of samples taken
Volts Var Byte ' Holds the Volts part of the result (only for display purposes)
Millivolts Var Word ' Holds the Millivolts part of the result (only for display purposes)
Amps Var byte
milliamps Var word
W var word
Milliwatts var Word
ph var word
pl var word
c vaR word
' quanta level = (5/1024) * 256 == 1250
Quanta Con 1250

Y = 20

Amp:

Average=0 ' Clear the Average variable befor use
For Samples=0 to 9 ' We will take 10 samples of the ADC
ADCIN 0,AD_Raw ' Place the conversion of channel0 into AD_RAW
Average=Average+AD_Raw ' Build up the Average result
Next ' Close the loop
Average=Average/10 ' Calculate the average by dividing by the number of samples taken
AD_Result1=(Average) */ Quanta ' Quantasize the result
AD_Result1=AD_Result1*10
amps= AD_Result1/1000 ' Calculate the Amps part of the result
Milliamps=AD_Result1//1000 ' Calculate the Milliamps part of the result
IF Milliamps < 60 THEN
Milliamps=Milliamps-Milliamps
ENDIF
RETURN

Volt:

Average=0 ' Clear the Average variable befor use
For Samples=0 to 9 ' We will take 10 samples of the ADC
ADCIN 1,AD_Raw ' Place the conversion of channel0 into AD_RAW
Average=Average+AD_Raw ' Build up the Average result
Next ' Close the loop
Average=Average/10 ' Calculate the average by dividing by the number of samples taken
AD_Result=(Average) */ Quanta ' Quantasize the result
AD_Result=AD_Result*11
Volts= AD_Result/1000 ' Calculate the Volts part of the result
Millivolts=AD_Result//1000 ' Calculate the Millivolts part of the result
RETURN

Watt:

AD_Raw=AD_Result*AD_Result1
W= AD_Raw/1000 ' Calculate the watts part of the result
Milliwatts=AD_Raw//1000 ' Calculate the Milliwatts part of the result
Return

Darrel Taylor
- 8th August 2007, 18:21
You definately want to use the WORD values, but you need to use DIV32.

AD_Raw=AD_Result*AD_Result1
W= AD_Raw DIV32 1000' Calculate the watts part of the result

Milliwatts=W//1000 ' Calculate the Milliwatts part of the result
W= W/1000 ' Calculate the watts part of the result


HTH,

Darrel Taylor
- 8th August 2007, 18:45
Oops again. :o

That won't work either, it'll overflow less than half way thru the range.

Still playing with it.

Can you use just Hundredths, instead of Thousanths. (2 decimal places)?
<br>

jbirnsch
- 8th August 2007, 19:32
I really don't need that kind of resolution so tenths is fine. I was thinking about this before that the thousands digit is in the mud anyway. I might just add a FPU chip to this project and call it done.......

Jason

Darrel Taylor
- 8th August 2007, 21:44
I might just add a FPU chip to this project and call it done.......


No, No don't do that. Just a few modifications and you're there.

OK, let's start with the Amp routine.
The way is is now, it takes 10 samples, averages them by dividing the total by 10.
Then after multiplying by Quanta (convert to voltage) it multiplies the result by 10 again.

So the last digit (1mv) would always be zero.

Instead, let's let the accumulation of the 10 samples be the * 10. Then you don't need to divide and multiply later.

10 samples of 1023 would be 10230 max.
*1250 (quanta) / 256 = 54946 max (54.946 VDC). So it's still within the Word limit.

So now it looks like ...
Amp:
Average=0 ' Clear the Average variable befor use
For Samples=0 to 9 ' We will take 10 samples of the ADC
ADCIN 0,AD_Raw ' Place the conversion of channel0 into AD_RAW
Average=Average+AD_Raw ' Build up the Average result
Next ' Close the loop
; Average=Average/10 ' Calculate the average by dividing by the number of samples taken
AD_Result1=(Average) */ Quanta ' Quantasize the result
; AD_Result1=AD_Result1*10
amps= AD_Result1/1000 ' Calculate the Amps part of the result
Milliamps=AD_Result1//1000 ' Calculate the Milliamps part of the result
IF Milliamps < 60 THEN
Milliamps=Milliamps-Milliamps
ENDIF
RETURN

Now for the volts, it's a similar situation, except the multiplier is 11.
So if you take 11 samples, instead of 10, then again, it doesn't need to divide and multiply later.

Volt:
Average=0 ' Clear the Average variable befor use
For Samples=0 to 10 ' We will take 11 samples of the ADC
ADCIN 1,AD_Raw ' Place the conversion of channel0 into AD_RAW
Average=Average+AD_Raw ' Build up the Average result
Next ' Close the loop
; Average=Average/10 ' Calculate the average by dividing by the number of samples taken
AD_Result=(Average) */ Quanta ' Quantasize the result
; AD_Result=AD_Result*11
Volts= AD_Result/1000 ' Calculate the Volts part of the result
Millivolts=AD_Result//1000 ' Calculate the Millivolts part of the result
RETURN


And finally to get Watts, we need to drop one of the values down (/10), I chose amps, no particular reason.
At the maximum values, Amps will be 4995 (49.95 amps), and Volts will be 54946 (54.946 V).
Multiply those 2 together, then DIV32 by 10,000 and the maximum result is 27445 (2744.5 Watts).

Here's the last part.
Watt:
AD_Result1 = AD_Result1 / 10 ' Scale amps down to 2 decimals
AD_Raw=AD_Result*AD_Result1
AD_Raw = DIV32 10000
W = AD_Raw / 10 ' Calculate the watts part of the result
Milliwatts=AD_Raw//10 ' Calculate the Milliwatts part of the result
' resolution is 100 milliwatts (0.1W)
' max = 2744.5 Watts
Return

This time I tested it. :)

HTH,

Patrick Pending
- 10th August 2007, 00:34
I'm pretty new to PIC programming and I don't understand everything DT has suggested but I think that accuracy could be improved a little by rounding before discarding your unwanted decimals (/10 - scaling down). It is pretty trivial to do codewise.

jbirnsch
- 10th August 2007, 14:45
Code works great! Thanks for the help.


Jason