I have a barometer (BMP180) and am interfacing it with aSTM32. I have to read the altitude which should have a precision of a foot.
While interfacing the barometer, I get a consistent real value of temperature but the pressure comes in the range of 59400 Pa (Pa - as per Bosch Datasheet). The example given in the datasheet also has pressure of 69964 Pa.
I have taken care of the delays required for the barometer to sample the data by using software based counters. Also, I checked my sensor with available libraries and everything comes consistent. But due to some academic reasons I can't use the libraries and so I need help in measuring the pressure.
Here is my STM32 Code:
//calibration params from the sensor
static int16_t AC1 = 8353;
static int16_t AC2 = -1041;
static int16_t AC3 = -14621;
static uint16_t AC4 = 33880;
static uint16_t AC5 = 25158;
static uint16_t AC6 = 18608;
static int16_t B1 = 6515;
static int16_t B2 = 35;
static int16_t MB = -32768;
static int16_t MC = -11786;
static int16_t MD = 2724;
static int TMPCNT = 0, PRSCNT=0; //loop counters
static double temperature, pressure;
static uint8_t oss = 3; // bmp high resolution
static long UT, X1, X2, B5, UP;
int main() {
while (1) {
if (TMPCNT == 2) { //2.7*2 > 5ms so sample temp every 5 ms
MSR_TEMP(); //measure for previous request
RQST_TEMP(); // request again
TMPCNT = 0;
}
TMPCNT++;
if (PRSCNT == 10) { //sample pressure every 27ms (25ms wait time for UH resolution)
MSR_PRESS();
RQST_PRESS();
PRSCNT = 0;
}
PRSCNT++;
/* some more code which takes 2.7 milliseconds */
}
}
void RQST_TEMP() {
i2c_transmit(BMP, 0xF4, 0x2E); // transmit 0x2E to 0xF4 reg of BMP addr
}
void MSR_TEMP() {
char buff[2];
requestData(BMP, 0xF6, buff, 2); //request 2 bytes from BMP addr, reg 0xF6, and put it in the buff
UT = (buff[0] << 8 | buff[1]);
X1 = (long)((UT - AC6) * AC5 * pow(2, -15));
X2 = (long)(MC * pow(2, 11) / (X1 + MD));
B5 = X1 + X2;
temperature = ((B5 + 8) * pow(2, -4)) / 10.0;
}
void RQST_PRESS(){
i2c_transmit(BMP, 0xF4, (char)(0x34 + (oss << 6)));
}
void MSR_PRESS() {
long B6,x1,x2,x3,B3,p;
unsigned long B4,B7;
char buff[3];
requestData(BMP, 0xF6, buff, 3);
UP = ((buff[0] << 16) + (buff[1] << 8) + buff[2]) >> (8-oss);
B6 = B5 - 4000;
x1 = (long)((B2 * (B6 * B6 * pow(2, -12))) * pow(2, -11));
x2 = (long)(AC2 * B6 * pow(2, -11));
x3 = x1 + x2;
B3 = ((((long)AC1 * 4 + x3) << oss) + 2) / 4;
x1 = AC3 * B6 * pow(2, -13);
x2 = (B1 * (B6 * B6 * pow(2, -12))) * pow(2, -16);
x3 = ((x1 + x2) + 2) * pow(2, -2);
B4 = AC4 * (unsigned long)(x3 + 32768) * pow(2, -15);
B7 = ((unsigned long)UP - B3) * (50000 >> oss);
if (B7 < 0x80000000) {
p = (B7 * 2) / B4;
} else {
p = (B7 / B4) * 2;
}
x1 = (p * pow(2, -8)) * (p * pow(2, -8));
x1 = (x1 * 3038) * pow(2, -16);
x2 = (-7357 * p) * pow(2, -16);
pressure = p + ((x1 + x2 + 3791) * pow(2, -4)); // pressure is in Pa as per data sheet
// SerialPrint("%lf\n",pressure);
}
The code written is based on the algorithm mentioned in the datasheet. Here is the datasheet. I dont know what I am doing wrong. My location should have pressure of 101209Pa which is way far from what I am getting. My I2C driver functions are also working as they should. So I cant figure out where exactly the problem is. I'll surely appreciate some help.
User contributions licensed under CC BY-SA 3.0