PDA

View Full Version : Math Formula / Variable Problem! Help!



bwarp
- 17th February 2006, 23:01
I am having a problem with using a math formula to calculate
a PPM value from an ADC reading. I am reading a 0-5 volt
on my input with 10 bit resolution. On the output I see
that the adc value is working as it should. Lets say I get
a reading on the ADC of 11260. When run through the line
"ppm = (AD/64320)*5000" the ppm variable should contain
875.31. When I run the code on the PIC and debug to my
serial port PPM = 0. I am doing something wrong? Any help
would be greatly appreciated. :^)

Source code follows below:


'----[ INCLUDES / DEFINES ]----
include "modedefs.bas" 'Include serout defines

'----[ VARIABLES ]----
SO VAR PORTB.7 ' Define serial output pin
SI VAR PORTB.5 ' Define serial in pin
TEMPB var byte
AD var word ' ADC Channel 0 Conversion Value
PPM var word ' Parts Per Million

'----[ INITIALIZATION ]----
ANSELH = %00000001
TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify result
TRISB = %01110000 'SET PORT B PINS TO OUTPUT EXCEPT PORT RB5 (RX)
PORTB = %00000000 'INIT PORT B TO ALL ZEROS AND POWER LED OFF

'----[ MAIN CODE ]----

Main:
ADCIN 0, AD ' Store value of analog input in AD0
Serout SO,N2400,["ADC0 -> ",#AD,10,13]' Print Data
ppm = (AD/64320)*5000
Serout SO,N2400,["ADC0 PPM -> ",#ppm,10,13]' Print Data
Pause 2000
Goto MAIN

Archilochus
- 18th February 2006, 00:35
Hi bwarp,
I believe the problem is here:

"ppm = (AD/64320)*5000"

If AD = 11260 then

(11260/64320) = 0.175

0.175 is not an 'integer' and the result of PBP's math will be '0' - PBP deals with whole numbers, not the fractions.

Arch

Charles Linquis
- 18th February 2006, 01:52
PBP does integer math only. You should rewrite the equation to multiply the A/D converter result by 5000 then divide by 64320 (or multiply by 500 and divide by 6432).

The result will be an integer, so you will lose the fractional part. However, you can get an extra digit of resolution if you modify the formula to something like:

FirstPart = (ADresult * 5000)/6432

HSEROUT [FirstPart/10,".",FirstPart//10]

Archilochus
- 18th February 2006, 03:42
Wouldn't multiplying the AD result by 5000 or 500 cause the variable to overflow?

Charles Linquis
- 18th February 2006, 06:50
Yes it would. Sorry, my error.

So, the best you could do is to multiply by 50 and divide by 643.
You could possibly get closer by using a different multiply/divide ratio.

Another option would be to use the DIV32 function.

Melanie
- 18th February 2006, 07:59
> Lets say I get a reading on the ADC of 11260.

Well, that in itself would be a problem... your 10-bit ADC shouldn't give you readings outside the range 0-1024.

Do the *5000 multiplication first, this in effect would cause an overflow from a word variable, but if immediately followed by a DIV32 (as Charles suggested) would result in an integer value.

So your input of 0-1024 multiplied by 5000 and divided by 64320 would result in a range of 0-79 which is very small and you lose a great deal of precision.

You can add TWO additional signigicant figures by multiplying by 50000 and dividing by 6432, this will then give you a range of 0-7960 which then by using the DIG function will allow you to extract the digits and insert a decimal point displaying your two decimal points to give you 0-79.60

Always work within a WORD variable but if you must spill out of it momentarily, immediately use the DIV32 function to come back.