AnsweredAssumed Answered

MPL3115A2 help needed please

Question asked by BENOIT ST-JEAN on Feb 1, 2019
Latest reply on Feb 7, 2019 by Tomas Vaverka

Hi again,


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.


Screen printout:

MSB: -1
CSB: -18
LSB: 0
Altitude: -18.00m



Option 2:


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;


Screen printout:

MSB: 255
CSB: 237
LSB: 176
Altitude (raw): FFEDB000
Altitude: 65517.68


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.