cancel
Showing results for 
Search instead for 
Did you mean: 

Using accelerometer IIS3DWB

KKots.1
Associate II

Hello all, 

I am trying to read the temperature out of the IIS3DWB chip and I am following the github example (iis3dwb_reg.c).    My code is given below.

However, once I start running the programme, the temperature I am measuring in degrees Celsius does not make sense at all. I am getting negative values which jump by 10 or 20 degrees every time I resume the programme.           Any advice and recommendation would be appreciated. 

Best regards, 

Kosta 

FIND CODE BELOW:

 

 HAL_StatusTypeDef IIS3DWBTR_ReadTemperature(IIS3DWBTR *dev ){
 
/* Read Raw Values from temperature registers 16bit */
    uint8_t regData[2];
 
HAL_StatusTypeDef status = IIS3DWBTR_ReadRegisters( dev, IIS3DWBTR_OUT_TEMP_L, regData, 2 );
 
/* Combine register values to give raw (UNSIGNED) temperature readings 16bits */
    uint16_t tempRaw;
 
    tempRaw = (uint16_t)(regData[0]<<8 | regData[1]<<0 );
 
 
    /* Convert to SIGNED integers (two's complement) */
    int16_t tempSigned = *(int16_t*) &tempRaw;
 
    /* Convert to deg C  */
    dev-> temp_C = 0.00390625f * ((float) tempSigned -0.0f) + 25.0f;
 
return status;

 

3 REPLIES 3
wb346
Associate II

Hello,

When reading from your temperature data registers, note that the first register (0x20) is your least significant byte and the second (0x21) is most significant. Your code above is shifting the LSB 8 bits whereas you should be shifting your MSB 8 bits. Therefore, when your register data changes by 1 bit, your readings are changing by 1<<8 bits.

When converting this to degrees C, 1<<8 bits changes the temperature by massive values.

Also, this is unrelated, but I don't see the need to store the data into a uint16 only to reassign it to a new int16.
Just put the data into an int16. There is no such thing as a 2's complement conversion. It is 2's compliment which is automatically read out as human decimal.

I hope this helps.
Tom



wb346_0-1688561536666.png

 

Hello Tom, 

Thank you for your reply. 
I do understand your argument and I tried to make the necessary changes in my code. So the way I exctract my tempRaw now looks likes this: 

tempRaw = (uint16_t)(regData[0]<<0 | regData[1]<<8);

 

However I am still getting values that do not really make any sense and are jumping all over. Any other recommendation that you could give me on what may be causing this or what should I look into? 

Regarding the details on how to store data, I will look into that once I solve this issue. 

Best regards,

Kosta

 

 

Kosta,

I've had issues like this a few times. Sometimes the part is not soldered correctly. Other times the part is not configured correctly. Do you have a logic analyzer you can use to confirm the device is being configured? 
It is imperative to read out the config registers after you write to them to confirm settings; assume nothing.

I like to configure it to read out around 12 Hz in High Resolution mode. If the readings are bouncing around a bit, the reading ODR might make a difference, but if they are WAY off, this would not be the issue. 

I'll do what I can to help, but I'd like to know:
1) If you have a logic analyzer and confirmed what data is actually being transferred ( Readings + Config )
2) If you are hand soldering parts
3) Have you tried multiple pieces of hardware?

I've had success in the past with cheap $15 logic analyzers using open source software. They are more than worth their weight in gold.

Thanks 
Tom