PDA

View Full Version : math problem?



serdar_ozcan
- 13th January 2005, 15:51
Hello everybody!! Sorry my english. I am beginner in pic.
fer var word
ker var word
ler var word
cal var byte
der = ((yuk - sifir)/(c1 - c0))
fer = ((yuk - sifir)//(c1 - c0))
ler = fer dig 2
cal = der*10 + ler
adve = (((cal * (adval - c1)) / 10) + yuk)

I have this formula. adval is my analog input.
if yuk = 10100 , sifir = 100 , c0 = 2 and c1 = 1022 and adval = 2 then normally adve = 104. but in 16f877 adve = 13211. How can I solve this problem? Thank you.

Ingvar
- 13th January 2005, 18:12
Hi,

There are a couple of bad things happening in the line "adve = (((cal * (adval - c1)) / 10) + yuk)".

(adval - c1) * cal = -99960 (since cal will be 98), -99960 is way higher than PBP can handle in a wordsized variable. You then try to divide this number by 10, that will not work since PBP can't divide a negative number.

There are a few possible solutions to your problem. "adval-c1" will almost always be neagtive(assuming 10bit AD). Reverse the order to make it positive instead. The number will still be too large for PBP, decrease the accuracy by dividing cal by 2, later you will divide by 5 instead of 10 to keep it the same. Change you "formula" to ......

der = ((yuk - sifir)/(c1 - c0))
fer = ((yuk - sifir)//(c1 - c0))
ler = fer dig 2
cal = der*10 + ler
cal = cal / 2
adve = yuk - (cal*(c1-adval))/5

... this should give you correct results(assuming 10bit AD).

However, i suspect there might be a mistake even earlier aswell. The code......

der = ((yuk - sifir)/(c1 - c0))
fer = ((yuk - sifir)//(c1 - c0))
ler = fer dig 2
cal = der*10 + ler

.... may not do what you want it to do. I assume that you want to do "cal = 10 *((yuk - sifir)/(c1 - c0))". The code you've written will not do that. It will hit the correct number somtimes but not always. You could use DIV32 instead .....

dummy VAR WORD
var1 VAR WORD
var2 VAR WORD

dummy = 10
var1 = yuk - sifir
var2 = c1 - c0
dummy = var1 * dummy
cal = DIV32 var2

.... this will produce correct results.

There might be a simpler and more accurate way of doing what youre trying to do. It looks like you're trying to do some sort of "twopoint calibration". Tell me/us what you want to do more precice and i may be able to help you further.

/Ingvar

serdar_ozcan
- 14th January 2005, 12:03
Thank you very much...

serdar_ozcan
- 14th January 2005, 12:29
Normally I want use this formula for loadcell calibration. C0 and C1 are analog voltage input from ADC. C0 is platform empty value and C1 is with any load value. sifir is kg. value of correspond to C0 value and yuk is kg. value of correspond to C1 value. So two point standart formula is :
adve(kg.) = ((adval-c1)*(yuk-sifir)/(c1-c0)) + yuk

I want use 16-bit ADC IC with 16f877....

Thank You.

Ingvar
- 14th January 2005, 16:31
I kinda suspected that this was your application. I'd rewrite your formula like this. This way you'll get rid of all those nasty negative numbers.

adve(kg.) = ((adval-c0)*(yuk-sifir)/(c1-c0)) + sifir

You could realize this formula like this.

dummy VAR WORD
dummy1 VAR WORD
dummy2 VAR WORD
dummy3 VAR WORD

adve VAR WORD
adval VAR WORD
yuk VAR WORD
sifir VAR WORD
c0 VAR WORD
c1 VAR WORD

dummy1 = adval - c0
dummy2 = yuk - sifir
dummy3 = c1 - c0
dummy = dummy1 * dummy2
adve = DIV32 dummy3
adve = adve + sifir

Bummer, just remembered that DIV32 actually can't candle more than 31/15 bits. No big deal, we just need to divide by 2 in a couple of places.

dummy1 = (adval - c0) > 1
dummy2 = yuk - sifir
dummy3 = (c1 - c0) > 1
dummy = dummy1 * dummy2
adve = DIV32 dummy3
adve = adve + sifir

If you decide to use anything less than 16 bits ADC you don't need to do this last step.

You can probably save some memory by reusing some of the variables inside your calculation. I'll leave that task to you.

cheers
/Ingvar