J. Doe
J. Doe

Reputation: 87

How convert raw data to useful temperature which comes from LSM303DLHC sensor

I use STM32F4 microcontroller and HAL library. I would like to read temperature from LSM303DLHC sensor. Following code is responsible for this task.

LSM303DLHC_Status_t LSM303DLHC_get_temp(int16_t *temp)
{
    uint8_t data_h = 0x00;
    uint8_t data_l = 0x00;
    uint16_t data_tmp = 0x00;
    uint8_t temp_enable = 0x00;

    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, TEMP_OUT_H_M, 1, &data_h, 1, 100) != HAL_OK)
    {
        return LSM303DLHC_ERROR;
    }

    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, TEMP_OUT_L_M, 1, &data_l, 1, 100) != HAL_OK)
    {
        return LSM303DLHC_ERROR;
    }

    data_tmp = (int16_t)((data_h << 8) | data_l);

    *temp = data_tmp/8;

    /*Enable temperature sensor*/
    if (HAL_I2C_Mem_Read(&hi2c1, LSM303_MAGNE_ADDRESS, CRA_REG_M, 1, &temp_enable, 1, 100) != HAL_OK)
    {
        return LSM303DLHC_ERROR;
    }

    temp_enable |= (0x01 << 7);

    if (HAL_I2C_Mem_Write(&hi2c1, LSM303_MAGNE_ADDRESS, CRA_REG_M, 1, &temp_enable, 1, 100) != HAL_OK)
    {
        return LSM303DLHC_ERROR;
    }
    /*End enable temperature sensor*/

    return LSM303DLHC_OK;
}

According to data sheet and many tutorial temperature is computed by this expression:

temp = (int16_t)((data_h << 8) | data_l);
temp = temp/8;

In room where I am is about 20 degree of Celsius. My function returns about 128-136 value.

Where did I make mistake?

Upvotes: 1

Views: 2273

Answers (3)

hoon
hoon

Reputation: 1

# python

# enable Temperature sensor 
bus.write_byte_data(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_CRA_REG_M, 0x90)  

...
# read register
tempH = bus.read_byte_data(LSM303_ADDRESS_MAG, 0x31)
tempL = bus.read_byte_data(LSM303_ADDRESS_MAG, 0x32)
temp = (tempH << 8 ) +  tempL
if temp > 32767:  # 2's complement
    temp -= 65536
temperature = float( 20 + ( temp >> 4 )/ 8 )  # 16bit --> 12bit , 8LSB/deg

Upvotes: 0

ppmarco
ppmarco

Reputation: 21

Well, on my side I get the following value when I read the temp register in a room at 20 C.

TH=255, TL=224

So it seems that the 0 value from the register corresponds to 21 C (approx.), and I can get the correct value using code when the temperature goes under 21 C (TH bit 7 set to 1):

printf("TH=%d, TL=%d\n", RegVal[0], RegVal[1]);
int16_t IntTemp = ((int16_t)RegVal[0] << 8) + RegVal[1];

printf("temp=%0.2f\n", (float)IntTemp / 128 + 21);

temp=20.75

Upvotes: 2

Stefan Z.
Stefan Z.

Reputation: 24

Your Value is a 12 bit value but you treated it like a 16 bit value.

in the LSM303DLHC Datasheet the temperature register is shown like this: TEMP_OUT_H_M (31h), TEMP_OUT_L_M (32h)

High Register: TEMP11, TEMP10, ..., TEMP4 Low Register: TEMP3, TEMP2, TEMP1, TEMP0, -, -, -, -

The first 4 bits (LSB(!)) do not have temperature values.

Your temp value is around 0x130 (128-136) as you wrote. In binary it is 0000 0001 0011 0000. The first four bits are not relevant. So you have to read 0000 0001 0011 which is 0x13 which is 19 in decimal.

Best regards, Stefan

Edit: Be careful with datatypes! You try to shift a byte Value by 8. This will not work. define your values with int:

int16_t data_h = 0;
int8_t data_l = 0;

Then use:

*temp = ((int16_t)((data_h << 8) | data_l)>>4);

Tipp: Use the programming mode of the MS Windows Calculator and play with binary and hex and decimal numbers.

Upvotes: 0

Related Questions