cancel
Showing results for 
Search instead for 
Did you mean: 

H3LIS331DL sensor readings do not change

NLieb
Associate II

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]);
    }
  }
}

1 REPLY 1
NLieb
Associate II

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.