# 89C51 Math problem

Discussion in 'Programmer's Corner' started by Uridan, Jun 27, 2009.

1. ### Uridan Thread Starter Member

Jun 11, 2009
11
0
Hi

I am using keil to program my 89C51 using C language, and I am trying to work the following equation.

humidity = (0.6785 * (ADC_value)) - 27.1

note that ADC_value is giving correct values.

But when I build my program it will give me 8 warrnings and when I debug my program the humidity will remain empty, thus the equation is not being implimented within the program.

So I decided to eliminate the Point, at first by using the following equation.

humidity = ((6785 * (ADC_value))/10000) - 27

This time no warrnings were given but when debugging the program a pair of .. will always appear regardless the ADC value. thus again, the equation is not workling properly.

Again, I decided to manipulate the equation for testing and used the following:

humidity = ((6785 * 2)/10000) - 27, but again the value was not right. so I turning the -27 to + 27 and guess what, the equation worked.

I have no idea what I am doing wrong. Also the keil can work log10(x), sin(x) etc but the program will give some warrnings and will not exectute that part of the program.

I am using the <math.h> library.

Am I missing something important here ?

void sendhumidity_data()
{
char humidity;

//humidity = (((6785)*(150))/10000)-27;
humidity = ((6785*2)/10000) + 20;
bin=(humidity/10); //select first digit of value converted
bin1= bin + 0x30;
dec = (humidity % 10); //most significant digit
dec1 = dec + 0x30;
SBUF = bin1;
while(TI == 0); //Wait until the serial data is sent.
TI = 0;
SBUF = dec1;
while(TI == 0); //Wait until the serial data is sent.
TI = 0;
}

Note: bin and dec are both unsigned char.

The humidity value should be between 99 - 0 and since I am using hyperterminal I am spliting the hex result in two to display the right ASCII characters from 0 to 9 serially.

Any help would be great please

Regards
Uridan

2. ### Papabravo Expert

Feb 24, 2006
10,340
1,850
I'm not abolutely certain that this is your problem, but unless you have the 8051 doing integer arithmetic with long integers you are probably dealing with overflow
Code ( (Unknown Language)):
1.
2. 6875 * 150 = 1,031,400 >> 65535 !!
3.
The limit for 16 bit integer arithmetic is 65535. Are you interested in breaking up the problem in such a way that you avoid overflow and other nasty fixed point arithmetic problems? Express 6875/10000 as a quotient of prime factors. Cancel the common terms, and voila, the exact fraction 11/16 is all that is left. Your new equation is
Code ( (Unknown Language)):
1.
2. ((11 * (adc_value))/16) - 27
3.
5. result = 148 which is still bigger than 99
6.
7. Lets Try 150
8. result 76
9.
I guess the adc_value must not cover the full range of [0,...,255]

Last edited: Jun 27, 2009
3. ### Mark44 Well-Known Member

Nov 26, 2007
626
1
That's for unsigned int. If you are using int, the limits are -32768 through 32767. I think that Papabravo hit the nail on the head with his diagnosis of integer overflow.

4. ### Uridan Thread Starter Member

Jun 11, 2009
11
0
Paperbravo,

Thank you very much!!!, Shame on me for forgetting such an important thing ! /bang head on table

It worked like a charm, I had to modify the serial part a little bit but now the value is being displayed perfectly by using that type of equation.

I was doing another silly mistake, I set the ADC_value to unsigned Char, which holds only 1 bit , silly me!

Thanks again Paperbravo I own you one!

Yes regards the ADC_value range, I calculated the formula on a 0.5 difference voltage divider and the maximum output voltage from humidity is 3.7V. So yes I will never reach greater then 99 with that formula.

Regards
uridan

5. ### Mark44 Well-Known Member

Nov 26, 2007
626
1
I'm pretty sure you meant one byte, or eight bits. That would be it could represent any number in the range 0 through 255.