Hello , i have a problem . So , i'm programming a BMP-180 on my Tiva C (123gh6pm) using keil 5. I've setted i2c driver (my own , not a library) and a BMP180 driver (my own , not using any librarys) .And it's working fine showing me temperature , but there is a bug in pressure calculus.
uint16_t CalculateTruePress (int16_t UPressure) {
uint32_t Pressure = 0 ;
float PressResult = 0.0 ;
int16_t B6 = 0 ;
int16_t X3 = 0 ;
int32_t B3 = 0 ;
uint16_t B4 = 0 ;
uint32_t B7 = 0 ;
B6 = B5 - 4000 ; // ++
X1 = (int32_t)(calibrationData.B2 * (B6 * B6 / 4096)) / 2048 ;//++
X2 = (int32_t)(calibrationData.AC2 * B6) / 2048 ;//++
X3 = X2 + X1 ;//++
B3 = (int32_t)(((calibrationData.AC1 * 4 + X3) << 1 ) + 2 ) / 4 ; //+ // Change oss to selected oversampling
X1 = (int32_t)(calibrationData.AC3 * B6 ) / 8192 ;//++
X2 = (calibrationData.B1 * ((B6*B6)/4096)) / 65536 ; //++
X3 = ((X1 + X2) + 2) / 4 ; //++
//********************************************************************************
B4 = (uint16_t)calibrationData.AC4 * (uint16_t)(X3 + 32768) / 32768 ;//++
B7 = (UPressure - (uint32_t)B3) * (50000 >> 1) ;//++ // Change oss to selected oversampling
if(B7 < 0x80000000) {
Pressure = (B7 * 2) / B4 ; // -> problem here
//*******************************
CursorToLocation(0,1) ;
sprintf(strResult2,"%d",Pressure) ;
SendStringOfData(strResult2) ;
//*******************************
//********************************************************************************
}
else {
Pressure = (B7 / B4) * 2 ;
}
X1 = (Pressure/pow(2,8)) * (Pressure/pow(2,8)) ;
X1 = (X1 * 3038) / pow(2,16) ;
X2 = ((0 - 7357) * Pressure) / pow(2,16) ;
Pressure = (Pressure + (X1 + X2 + 3791) / pow(2,4)) ;
PressResult = (float)Pressure / 100.0f ;
// FloatToArray(PressResult) ;
// CursorToLocation(0,1) ;
// SendStringOfData("Press: ") ;
// sprintf(strResult2,"%d.%d",splitParts[0],splitParts[1]) ;
// SendStringOfData(strResult2) ;
// SendStringOfData(" hPa") ;
return Pressure ;
}
So , i marked problem area with a big border of *** . B7 in my case is something around 1,24 *10^9 and B4 near 34000.
Pressure = (B7 * 2) / B4 ; ------> almost 2.5*10^9 / 34000 and i get 8000 or something near this value.
I print this value on my LCD using sprintf , and i can't figure out why i get this small value , when i must get a value 10 times greater?!
Funniest thing is that , if i change (B7*2) to it's value (a constant) division is right...
B5 is not defined ?
Why does your code look obfuscated ? Do you have any documentation for the conversion you are trying to perform ? Is looks super complicated for what it does. Do your really need floating point ?
What is the range and the resolution of the result ? It may be possible to get away with fixed point. Floating point is evil and should be avoided, especially with small devices.
Yeap , this conversion is showed in the datasheet , all the formulas. And here i convert floating point into 2 integers (integer part and fraction part ). B5 is an global variable that is calculated in function that calculate true temperature.
Ok I found the formula in the datasheet. I attached it below.
All their variables are "long", why did you decide to use int16_t for some values in your implementation ?
B6 for example is a small value why it needs to be a long type? it is actually -1000 or something like that...
You should be very careful with downgrading the size of those variables; C rules for type coercion (when you do stuff with two operands of different types) are real voodoo sometimes.
This might help. Different compiler (MikroC) but I've tested it on a PIC18F25K50. Works a treat
Ok , thank you both , i'll try to retype my variables...
Yeap , i've solved it , it was variables type issue and a little bug in my i2c driver)
Thank you for help guys.