Search code examples
avratmegaadc

floating point operations anomaly


I am reading temperature from temp sensor tmp36 using atmega2560. After reading temperature sensor digital values and converting them into readable form in two atmega2560 microcontrollers, I get different answers. Why do I get this type of answers. ? Piece of code is present below:

float temp;   // global variable

{
unsigned long temp_volt;
unsigned char temp_h, temp_l;
unsigned int temp_buf;

temp_l=ADCL;
temp_h=ADCH;
temp_buf=((int)temp_h<<8)|temp_l;


temp_volt =(((unsigned long)temp_buf*256*10)/1023) - 993;   //  subtract offset gain    
temp = ((float)temp_volt*1000/1014*100/196)/10;       //  adjust the gain 
printf("temp_buf: %d, temp_volt: %d, temp: %0.2f\r\n", temp_buf, temp_volt, temp);
}

On one ATMEGA2560 answers I got is:

temp_buf: 55, temp_volt: 447, temp: 22.4

On another ATMEGA2560 what i got is:

temp_buf: 53, temp_volt: -861, temp: 0.00

Because of this I made this adjustments

temp_volt =(((unsigned long)temp_buf*256*100)/1023) - 904;

Why is two microcontrollers behaving differently when I am usiong same code?


Solution

  • Have double type for temp_volt and temp_buf so that you don;t lose data because of integer arithmetic, for example, 7/4 = 1 and 7.0/4.0 = 1.75 So,

    double temp_volt;
    double temp_buf;
    

    and your computations as:

    temp_volt =temp_buf*256.0*10.0)/1023.0) - 993.0;   //  subtract offset gain    
    temp = ((float)temp_volt*1000.0/1014.0*100.0/196.0)/10.0;       //  adjust the gain 
    

    If you need your result as int, then do that in the final step, e.g.

     temp_volt =(double)(int)(temp_buf*256.0*10.0)/1023.0) - 993.0);