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.