Not sure if I'm doing this correctly but this is my configuration for the MPL3115A2 pressure sensor. I am using it in altimeter mode. It is tied to a PIC24EP microcontroller. I can read the temperature correctly but I have questions regarding the altitude reading. I'm using it in polling mode and check only when needed and I have a serial console where I print the information:
PROTOCOL_Write_I2C( 0xC0, 0x26, 0xB8 );
PROTOCOL_Write_I2C( 0xC0, 0x13, 0x07 );
PROTOCOL_Write_I2C( 0xC0, 0x26, 0xB9 );
Then I tested two options to read the altitude:
Option 1: Use all signed values
float fAltitude = 0;
signed int8 MSB = PROTOCOL_Read_I2C( 0xC0, 0x01 );
signed int8 CSB = PROTOCOL_Read_I2C( 0xC0, 0x02 );
signed int8 LSB = PROTOCOL_Read_I2C( 0xC0, 0x03 );
fAltitude = ((float) (( MSB << 8 ) | CSB )) + ((float) (LSB >> 4) * 0.0625 );
With the above, the reading calculates as around -18. The problem is that I'm at probably 300m above sea level and I'm on the 6th floor of a building.
Use unsigned long values follow the logic from the datasheet P21 section 7.1.3 (Document Number: MPL3115A2 Rev 3.0, 12/2013) where it states: The Altitude data is stored as a signed fractional 20-bit value in meters in Q16.4 format. The OUT_P_MSB and OUT_P_CSB registers contain the integer part in meters and the OUT_P_LSB register contains the fractional part. Left shifting the OUT_T_MSB byte by 24 bits into a 32 variable and doing a logical OR with the OUT_T_CSB byte left shifted 16 bits and a logical OR with the OUT_T_LSB byte left shifted 8 bits gives the altitude in meters times 65536.
float f_Altitude = 0;
unsigned int32 Altitude = 0;
unsigned int32 MSB = PROTOCOL_Read_I2C( 0xC0, 0x01 );
unsigned int32 CSB = PROTOCOL_Read_I2C( 0xC0, 0x02 );
unsigned int16 LSB = PROTOCOL_Read_I2C( 0xC0, 0x03 );
MSB = MSB << 24;
CSB = CSB << 16;
LSB = LSB << 8;
Altitude = MSB | CSB | LSB;
f_Altitude = (float) Altitude / 65536;
Altitude (raw): FFEDB000
Here I notice that if I substract the result <Altitude> value of 65517.68 from 65536, I get basically the same result as option 1 above, which is -18.32m.
Question 1: Does this make any sense?
Question 2: My guess is option 1 is the way to go?
Question 3: Why am I not getting the correct height?
My goal is that wherever I initialize the device, this will be my 0-base so if I go up a floor, I'll know it and if I go down a floor, I'll know it as well.
Let me know if you have questions.
The results you are getting are correct. You are never going to get absolute altitude, especially inside a building where the pressure can be different from an ambient atmospheric pressure. The MPL3115A2 computes altitude as a function of pressure and temperature using the NASA Standard Atmospheric Model of 1976 as shown in the datasheet, section 9.1.3. As you can notice, the calculated altitude will be negative if the measured pressure is higher than 1013.26 hPa, which is the default pressure reference at sea level stored in the BAR_IN_MSB (0x14) and BAR_IN_LSB (0x15) registers. If your local weather/airport gives the pressure normalized for sea level, this value should go into these registers to bring the computed altitude closer to a real value. As I explained in your another post, the MPL3115A2 also has the OFF_H register for further altitude offset adjustments.