Skip to main content
Visitor II
February 15, 2019
Question

H3LIS331DL sensor readings do not change

  • February 15, 2019
  • 1 reply
  • 663 views

I'm using the STEVAL-MKI153V1 evalulation board together with a Nucleo F443RE board and the STM reference driver implementation from github.

The code is basically the read_simple.c example provided by STM adapted to mbed.

I've checked the I²C communication with a logic analyzer, all good.

Typically it outputs something like:

X=-3856 Y=-3856 Z=-3856

X=-3856 Y=-3856 Z=-3856

X=-3856 Y=-3856 Z=-3856

X=-3856 Y=-3856 Z=-3856

X=-3856 Y=-3856 Z=-3856

X=-3856 Y=-3856 Z=-3856

X=0 Y=0 Z=0

X=-3856 Y=-3856 Z=-3856

#include <h3lis331dl_reg.h>
#include <string.h>
 
I2C i2c(PB_9, PB_8);
 
Serial serial(SERIAL_TX, SERIAL_RX, 9600);
 
#define TWI_ADDR	(H3LIS331DL_I2C_ADD_H) 
 
static axis3bit16_t data_raw_acceleration;
static float acceleration_mg[3];
static uint8_t whoamI;
static uint8_t tx_buffer[1000];
 
int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
 uint8_t buffer[10] = {0};
 buffer[0]= reg; // | 0x80;
 memcpy(&buffer[1], bufp, len);
 return i2c.write(TWI_ADDR, (char*)buffer, len+1, false);
}
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
 
 i2c.write(TWI_ADDR, (char*)&reg, 1, true);
 return i2c.read(TWI_ADDR, (char*)bufp, len);
}
 
int main() {
 h3lis331dl_ctx_t dev_ctx;
 
 /* Initialize mems driver interface */
 dev_ctx.write_reg = platform_write;
 dev_ctx.read_reg = platform_read;
 i2c.frequency(400000);
 
 serial.printf("Starting up\n");
 
 /* Check device ID */
 whoamI = 0;
 do {
 h3lis331dl_device_id_get(&dev_ctx, &whoamI);
 if ( whoamI != H3LIS331DL_ID ) {
 serial.printf("Device not found 0x32 != %x\n", whoamI);
 wait(2.0f);
 }
 } 
 while( whoamI != H3LIS331DL_ID );
 
 serial.printf("Device found.\n");
 
 /* Enable Block Data Update */
 h3lis331dl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
 
 /* Set full scale */
 h3lis331dl_full_scale_set(&dev_ctx, H3LIS331DL_200g);
 
 /* Configure filtering chain */
 h3lis331dl_hp_path_set(&dev_ctx, H3LIS331DL_HP_DISABLE);
 
 /* Set Output Data Rate */
 h3lis331dl_data_rate_set(&dev_ctx, H3LIS331DL_ODR_5Hz);
 
 serial.printf("Device set up, running loop..\n\n");
 
 /* Read samples in polling mode (no int) */
 while(1) {
 /* Read output only if new value is available */
 h3lis331dl_reg_t reg;
 h3lis331dl_status_reg_get(&dev_ctx, &reg.status_reg);
 
 if (reg.status_reg.zyxda) {
 /* Read acceleration data */
 memset(data_raw_acceleration.u8bit, 0x00, 3*sizeof(int16_t));
 h3lis331dl_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit);
 
 serial.printf("X=%d Y=%d Z=%d\n", 
 data_raw_acceleration.i16bit[0], 
 data_raw_acceleration.i16bit[1],
 data_raw_acceleration.i16bit[2]);
 }
 }
}

    This topic has been closed for replies.

    1 reply

    NLiebAuthor
    Visitor II
    February 15, 2019

    Found the error.

    The chip doesn't support automatic address incrementation on block read so to read multiple registers at once is not working. Therefore my I²C implementation reads the X_OUT_L register over and over. Since the others are not read the registers are never refreshed with new readings and return the old value over and over.