cancel
Showing results for 
Search instead for 
Did you mean: 

[LSM6DSM] How to properly setup basic readout

AR2
Associate

Hello,

I'm struggling with LSM6DSM readout and would like to ask for some insight. I use a custom board with 7 other I2C sensors and the LSM6DSM is the lost one I need to handle. Among them is a H3LIS331 from ST.

For all of them I use the same code for read/write I2C operations and interrupt handling. So I'm quite certain that every thing is sound on the uC side of things.

I'm trying to start with simple readout of both 3D sensors. I'm using application note AN4987 as a reference. I got stuck on subsection 4.1.

Simplified code:

------ Configuration function ----------
LSM6DSM_softReset();
do{
       LSM6DSM_getCTRL3C(&ctrl3_c);
}while(ctrl3_c.sw_rst == 0b1);
 
LSM6DSM_getCTRL3C(&ctrl3_c); 
    ctrl3_c.pp_od  = 0b1; //open drain
    ctrl3_c.h_lact = 0b1;  //active low
    ctrl3_c.if_inc = 0b1;   //Address auto increment
    ctrl3_c.bdu    = 0b1;  //block data readout
LSM6DSM_setCTRL3C(ctrl3_c);
 
LSM6DSM_getCTRL1XL(&ctrl1_xl); 
ctrl1_xl.odr_xl = 0b1011;
ctrl1_xl.fs_xl  = 0b00;
while(NRF_SUCCESS != LSM6DSM_setCTRL1XL(ctrl1_xl);  
 
LSM6DSM_getCTRL2G(&ctrl2_g);
ctrl2_g.odr_g  = 0b1011;
ctrl2_g.fs_125 = 0b1;
LSM6DSM_setCTRL2G(ctrl2_g);  
 
LSM6DSM_getINT1_CTRL(&int1_ctrl);   
int1_ctrl.drdy_g  = 0b1;
int1_ctrl.drdy_xl = 0b1;
LSM6DSM_setINT1_CTRL(int1_ctrl);   
 
---------- Sensor readout ----------
void LSM6DSM_Service(void){
     LSM6DSM_STATUS_REG_t status;
     float x,y,z;
     if(*newDataFlag){
          
        LSM6DSM_getSTATUSREG(&status);
        *newDataFlag = false;
        
        if(status.XLDA == 0b1){
            LSM6DSM_getOUTX_XL(&x);
            LSM6DSM_getOUTY_XL(&y);
            LSM6DSM_getOUTZ_XL(&z);
        }
        if(status.GDA == 0b1){
            LSM6DSM_getOUTX_G(&x);
            LSM6DSM_getOUTX_G(&y);
            LSM6DSM_getOUTX_G(&z);
        }
             
        *logFlag = true;
     }
}
 
 
nrfx_err_t LSM6DSM_getOUTX_XL(float* output){
    nrfx_err_t err;
    
    int16_t regVal = 0;
    uint8_t* regVal_ptr = (uint8_t*)&regVal;
 
    err = get_reg(LSM6DSM_slv_addr,  LSM6DSM_OUTX_L_XL, regVal_ptr, 2);   
 
    *output = ((float)regVal * LSM6DSM_XL_Sensitivity);
    
    return err;
}

newDataFlag is set in the GPIO interrupt. That wakes up the uC which goes through all the sensors services, similar to one I've listed. I've paste a single readout function for XL, axes X but all other are written in the same way.

I have two problems:

1st - no GDA interrupts

2en - Invalid XL data.

1.

LSM6DSM triggers the uC interrupt - after reading status I always get XLDA and TDA flags. I never get GDA. I can see in debug that after reading through all XL output registers INT1 goes high and interrupt is cleared. So that part seems to work as described in datasheet.

2.

The acceleration I read is:

X = (0x7FD9) 1.999647

Y = (0x7FEE) 1.99775

Z = (0x3F10) 0.984784

The Z axis seems to work fine but has wrong sign. Sensor is mounted on the top side of the PCB and the board is laying flat on the table. According to page 20 of the datasheet Z axis has positive side "above" the IC. So I guess it should be -1G.

If i rotate the board I can see that Z goes from +1 to -1.

X axis is stuck on 7FD9 on the first board I have. It doesn't respond to movement at all. Meanwhile when I use the second one it varies but value makes no sens - when board is flat on the desk it shows around 1G.

What I've already checked:

  1. Register Addresses and structures. I've found github repo with a library for LSM6DSM provided by ST. I crosschecked all the functions/addresses/registers and all seems to be exactly the same.
  2. Switching to INT2, turning on/off G/XL - it behaves exactly the same as INT1
  3. All fifo registers are 0's, FIFO is in bypass mode
  4. User offsets are zeroed for all axes

I written everything based on the assumption that default register values are as described in the datasheet.

2 REPLIES 2
AR2
Associate

Hello,

it seems that we've managed to solve the issue. We've ordered new sensors, replaced the old ones and now everything works fine. It looks like the original sensors were damaged during handling by the company responsible for board assembly or, perchance, are defective due to manufacturing error.

Hi @AR​ , glad to hear from you everything is OK and thank you for coming back for explanation! Your settings seems in fact ok, it's a hardware root cause. Regards