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

This discussion is locked. Please start a new topic to ask your question.
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.

Announcement

We’re moving the ST Community to a new platform to give you a better and more reliable community experience.