cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSO ACC and GYR setting

JXiao.1
Associate II

Hi,

I am using LSM6DSO to measure acceleration and angular velocity. To save the power of device, I want to use accelerator in most case. Some conditions, the gyroscope will need to open.

I used the function 'lsm6dso_fifo_xl_batch_set', 'lsm6dso_fifo_gy_batch_set', 'lsm6dso_xl_data_rate_set' and 'lsm6dso_gy_data_rate_set' to control the sensor. The function is provided by lsm6dso_reg.c. It should be a official library. I used them in the following picture.

0693W00000Ba7ifQAB.pngI found when I set them off simultaneously, there is no data from the sensor. But if one of them is open and another is off, two types' data can be read from sensor. It is very strange. Then I use funcition to check the parameters.

0693W00000Ba8oFQAR.pngI have found the gyroscope cannot be set under 26Hz. When I set it off or 12.5Hz, it will be changed to 26 automatically. But it can be set to higher frequency.How to change the problem?

Do you have some advices?

12 REPLIES 12
JXiao.1
Associate II

Does anyone meet similar condition?

niccolò
ST Employee

Hi @JXiao.1​ ,

let me try to understand your problem:

are you having trouble enabling both sensors together?

how do you read data?

it is very strange that the gyro does not go to 12.5Hz, can you check the function to set it does not return error?

Niccolò

Hi,

This is my code for initial sensor. I want disable the gyroscope and only enable the accelerator. I use fifo to read data from sensor.

bool sensor_init(void)
{
	lsm6dso_device_id_get(&imu_dev_ctx, &whoamI);
	if(whoamI != LSM6DSO_ID)
		return false;
 
	lsm6dso_reset_set(&imu_dev_ctx, PROPERTY_ENABLE);
	do
	{
		lsm6dso_reset_get(&imu_dev_ctx, &rst);
	}while(rst);
 
	lsm6dso_i3c_disable_set(&imu_dev_ctx, LSM6DSO_I3C_DISABLE);
 
	lsm6dso_xl_full_scale_set(&imu_dev_ctx, LSM6DSO_2g);
	lsm6dso_gy_full_scale_set(&imu_dev_ctx, LSM6DSO_250dps);
	lsm6dso_block_data_update_set(&imu_dev_ctx, PROPERTY_ENABLE);
 
	lsm6dso_fifo_watermark_set(&imu_dev_ctx, PATTERN_LEN);
	lsm6dso_fifo_stop_on_wtm_set(&imu_dev_ctx, PROPERTY_ENABLE);
 
	lsm6dso_fifo_mode_set(&imu_dev_ctx, LSM6DSO_STREAM_TO_FIFO_MODE);
 
        lsm6dso_xl_power_mode_set(&imu_dev_ctx, LSM6DSO_LOW_NORMAL_POWER_MD);
        lsm6dso_gy_power_mode_set(&imu_dev_ctx, LSM6DSO_GY_NORMAL);
 
        lsm6dso_xl_data_rate_set(&imu_dev_ctx, LSM6DSO_XL_ODR_104Hz);
	lsm6dso_gy_data_rate_set(&imu_dev_ctx, LSM6DSO_GY_ODR_OFF);
 
	lsm6dso_fifo_xl_batch_set(&imu_dev_ctx, LSM6DSO_XL_BATCHED_AT_104Hz);
	lsm6dso_fifo_gy_batch_set(&imu_dev_ctx, LSM6DSO_GY_BATCHED_AT_104Hz);
}

The next is reading data from sensor. First, I use the function to get data rate. The acc data rate is same as I set which is 104Hz. But the data rate of gyroscope is 26Hz. It is not turned off. There is no error returned.

        lsm6dso_xl_data_rate_get(&imu_dev_ctx, &x);
        lsm6dso_gy_data_rate_get(&imu_dev_ctx, &y);
        LOG_INF("%d %d \n", x, y);
        lsm6dso_fifo_xl_batch_get(&imu_dev_ctx, &m);
        lsm6dso_fifo_gy_batch_get(&imu_dev_ctx, &n);
        LOG_INF("%d %d \n", m, n);
 
        u8_t tmpbuf[100] = {0};
 
        memset(data_raw_acceleration.u8bit, 0x00, 3*sizeof(int16_t));
        lsm6dso_fifo_out_raw_get(&imu_dev_ctx, data_raw_acceleration.u8bit);
        acceleration_mg[0] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[0]);
        acceleration_mg[1] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[1]);
        acceleration_mg[2] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[2]);
 
        acceleration_g[0]   = acceleration_mg[0]/1000;
        acceleration_g[1]   = acceleration_mg[1]/1000;
        acceleration_g[2]   = acceleration_mg[2]/1000;
 
        sprintf(tmpbuf, "accx is %f, accy is %f, accz is %f", acceleration_g[0], acceleration_g[1], acceleration_g[2]);
        LOG_INF("%s", tmpbuf); 
 
        delay_ms(500);
 
         memset(data_raw_angular_rate.u8bit, 0x00, 3*sizeof(int16_t));
        lsm6dso_fifo_out_raw_get(&imu_dev_ctx, data_raw_angular_rate.u8bit);
        angular_rate_mdps[0] = lsm6dso_from_fs250_to_mdps(data_raw_angular_rate.i16bit[0]);
        angular_rate_mdps[1] = lsm6dso_from_fs250_to_mdps(data_raw_angular_rate.i16bit[1]);
        angular_rate_mdps[2] = lsm6dso_from_fs250_to_mdps(data_raw_angular_rate.i16bit[2]);
 
        angular_rate_dps[0] = angular_rate_mdps[0]/1000;
        angular_rate_dps[1] = angular_rate_mdps[1]/1000;
        angular_rate_dps[2] = angular_rate_mdps[2]/1000;
 
        sprintf(tmpbuf, "gyrx is %f, gyry is %f, gyrz is %f", angular_rate_dps[0], angular_rate_dps[1], angular_rate_dps[2]);
        LOG_INF("%s", tmpbuf); 

Hi @JXiao.1​ ,

why do you use lsm6dso_fifo_gy_batch_set(&imu_dev_ctx, LSM6DSO_GY_BATCHED_AT_104Hz) if you want to turn the gyro off?

can you check what does the function do?

I fear it turns on the gyro.

Niccolò

Hi Niccolò,

Using this function is to make sure there is nothing read from gyro.

I have also close it and it is useless.

Jiahe

Hi @JXiao.1​ ,

can you check the meaning of the LSM6DSO_GY_ODR_OFF define?

also, try to get into lsm6dso_gy_data_rate_set and see what it does.

another check to try is commenting the function lsm6dso_gy_full_scale_set.

let me know if this helps

Niccolò

Hi Niccolò,

I have checked LSM6DSO_GY_ODR_OFF  can select gyroscope work mode. I have also use lsm6dso_gy_data_rate_set this function. Its return value is always 2. That means it is set to 26Hz.

Commenting the function lsm6dso_gy_full_scale_set is also useless.

Hi @JXiao.1​ ,

let's try to dig into the issue.

you are using the function->

int32_t lsm6dso_gy_data_rate_set(lsm6dso_ctx_t *ctx, lsm6dso_odr_g_t val)

{

 lsm6dso_ctrl2_g_t reg;

 int32_t ret;

 ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);

 if (ret == 0) {

  reg.odr_g = (uint8_t) val;

  ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);

 }

 return ret;

}

(please. check if it is the same as yours)

a ret value different from 0 means that there is an error, so you should check where the error is.

try to set breakpoints at the read_reg and write_reg functions, and check what is "reg" before and after the execution.

Let me know what you find

Niccolò

Hi Niccolò,

I have check the function and my library has some different. The FSM will affect the frequncy set.

I found my problem may be happen on the FSM part. Because I also use the FSM and I found in the library that the gyroscope frequency will be set again. And I try to commit all the code about FSM setting, it does nothing. Do you have some function to chekc the FSM state and turn off the FSM?

This is the code. You can see in line 40. Althought hte gyro is off, the FSM will open it agian.

int32_t lsm6dso_gy_data_rate_set(stmdev_ctx_t *ctx, lsm6dso_odr_g_t val)
{
  lsm6dso_odr_g_t odr_gy =  val;
  lsm6dso_emb_fsm_enable_t fsm_enable;
  lsm6dso_fsm_odr_t fsm_odr;
  lsm6dso_ctrl2_g_t reg;
  int32_t ret;
 
  /* Check the Finite State Machine data rate constraints */
  ret =  lsm6dso_fsm_enable_get(ctx, &fsm_enable);
  if (ret == 0) {
    if ( (fsm_enable.fsm_enable_a.fsm1_en  |
          fsm_enable.fsm_enable_a.fsm2_en  |
          fsm_enable.fsm_enable_a.fsm3_en  |
          fsm_enable.fsm_enable_a.fsm4_en  |
          fsm_enable.fsm_enable_a.fsm5_en  |
          fsm_enable.fsm_enable_a.fsm6_en  |
          fsm_enable.fsm_enable_a.fsm7_en  |
          fsm_enable.fsm_enable_a.fsm8_en  |
          fsm_enable.fsm_enable_b.fsm9_en  |
          fsm_enable.fsm_enable_b.fsm10_en |
          fsm_enable.fsm_enable_b.fsm11_en |
          fsm_enable.fsm_enable_b.fsm12_en |
          fsm_enable.fsm_enable_b.fsm13_en |
          fsm_enable.fsm_enable_b.fsm14_en |
          fsm_enable.fsm_enable_b.fsm15_en |
          fsm_enable.fsm_enable_b.fsm16_en ) == PROPERTY_ENABLE ){
 
      ret =  lsm6dso_fsm_data_rate_get(ctx, &fsm_odr);
      if (ret == 0) {
        switch (fsm_odr) {
          case LSM6DSO_ODR_FSM_12Hz5:
 
            if (val == LSM6DSO_GY_ODR_OFF){
              odr_gy = LSM6DSO_GY_ODR_12Hz5;
 
            } else {
              odr_gy = val;
            }
            break;
          case LSM6DSO_ODR_FSM_26Hz:
 
            if (val == LSM6DSO_GY_ODR_OFF){
              odr_gy = LSM6DSO_GY_ODR_26Hz;
 
            } else if (val == LSM6DSO_GY_ODR_12Hz5){
              odr_gy = LSM6DSO_GY_ODR_26Hz;
 
            } else {
              odr_gy = val;
            }
            break;
          case LSM6DSO_ODR_FSM_52Hz:
 
            if (val == LSM6DSO_GY_ODR_OFF){
              odr_gy = LSM6DSO_GY_ODR_52Hz;
 
            } else if (val == LSM6DSO_GY_ODR_12Hz5){
              odr_gy = LSM6DSO_GY_ODR_52Hz;
 
            } else if (val == LSM6DSO_GY_ODR_26Hz){
              odr_gy = LSM6DSO_GY_ODR_52Hz;
 
            } else {
              odr_gy = val;
            }
            break;
          case LSM6DSO_ODR_FSM_104Hz:
 
            if (val == LSM6DSO_GY_ODR_OFF){
              odr_gy = LSM6DSO_GY_ODR_104Hz;
 
            } else if (val == LSM6DSO_GY_ODR_12Hz5){
              odr_gy = LSM6DSO_GY_ODR_104Hz;
 
            } else if (val == LSM6DSO_GY_ODR_26Hz){
              odr_gy = LSM6DSO_GY_ODR_104Hz;
 
            } else if (val == LSM6DSO_GY_ODR_52Hz){
              odr_gy = LSM6DSO_GY_ODR_104Hz;
 
            } else {
              odr_gy = val;
            }
            break;
          default:
            odr_gy = val;
            break;
        }
      }
    }
  }
 
  if (ret == 0) {
    ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
  }
  if (ret == 0) {
    reg.odr_g = (uint8_t) odr_gy;
    ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t*)&reg, 1);
  }
 
  return ret;
}