cancel
Showing results for 
Search instead for 
Did you mean: 

lis2dh12 returns constant data using STMems driver read data polling

Ywo.1
Associate II

I have several boards with lis2dh12 and all of them keeps return constant data for lis2dw12_acceleration_raw_get function, every board has its own constant, 0x5050, 0xe0e0, 0x7070.

I tried using the STEVAL-MKI135V1 connected to STM3220G-EVAL to test maybe our implementation and board design is the problem, but the same happens, it returns constant 0x6060.

We also have some boards that we use lis2dw12 instead, everything else is exactly the same, and it works great with the drivers for this sensor.

Here is the code for init and for reading data:

void Accelerometer_Init(void)
{
  lis2dw12_device_id_get(&dev_ctx, &whoamI);
 
  if (whoamI == LIS2DW12_ID)
	{
		/* Restore default configuration */
	//  lis2dw12_reset_set(&dev_ctx, PROPERTY_ENABLE);
 
	//  do {
	//    lis2dw12_reset_get(&dev_ctx, &rst);
	//  } while (rst);
 
		/* Enable Block Data Update */
		lis2dw12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
		/* Set full scale */
		//lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_8g);
		lis2dw12_full_scale_set(&dev_ctx, LIS2DW12_2g);
		/* Configure filtering chain
		 * Accelerometer - filter path / bandwidth
		 */
		lis2dw12_filter_path_set(&dev_ctx, LIS2DW12_LPF_ON_OUT);
		lis2dw12_filter_bandwidth_set(&dev_ctx, LIS2DW12_ODR_DIV_4);
		/* Configure power mode */
		lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_HIGH_PERFORMANCE);
		//lis2dw12_power_mode_set(&dev_ctx, LIS2DW12_CONT_LOW_PWR_LOW_NOISE_12bit);
		/* Set Output Data Rate */
		lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_ODR_25Hz);
	}
	else if(whoamI == LIS2DH12_ID)
	{
		/* Enable Block Data Update. */
		lis2dh12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
		/* Set Output Data Rate to 1Hz. */
		lis2dh12_data_rate_set(&dev_ctx, LIS2DH12_ODR_25Hz);
		/* Set full scale to 2g. */
		lis2dh12_full_scale_set(&dev_ctx, LIS2DH12_2g);
//		/* Enable temperature sensor. */
//		lis2dh12_temperature_meas_set(&dev_ctx, LIS2DH12_TEMP_ENABLE);
		/* Set device in continuous mode with 12 bit resol. */
		lis2dh12_operating_mode_set(&dev_ctx, LIS2DH12_HR_12bit);		
	}
}
 
int Accelerometer_Get_Data(void)
{  /* Read samples in polling mode (no int) */
	uint8_t reg;
	int16_t data_raw_acceleration[3];
	for (uint8_t i=0; i<3; i++)
		prev_acc[i] = acceleration_mg[i];
  if (whoamI == LIS2DW12_ID)
	{
		/* Read output only if new value is available */
		lis2dw12_flag_data_ready_get(&dev_ctx, &reg);
 
		if (reg) 
		{
			/* Read acceleration data */
			memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
			lis2dw12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
			//acceleration_mg[0] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[0]);
			//acceleration_mg[1] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[1]);
			//acceleration_mg[2] = lis2dw12_from_fs8_lp1_to_mg(data_raw_acceleration[2]);
			acceleration_mg[0] = lis2dw12_from_fs2_to_mg(data_raw_acceleration[0]);
			acceleration_mg[1] = lis2dw12_from_fs2_to_mg(data_raw_acceleration[1]);
			acceleration_mg[2] = lis2dw12_from_fs2_to_mg(data_raw_acceleration[2]);
		}
	}
	else if(whoamI == LIS2DH12_ID)
	{
    /* Read output only if new value available */
    lis2dh12_xl_data_ready_get(&dev_ctx, &reg);
 
    if (reg) {
      /* Read accelerometer data */
      memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
      lis2dh12_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
      acceleration_mg[0] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration[0]);
      acceleration_mg[1] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration[1]);
      acceleration_mg[2] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration[2]);
    }
	return 0;
}
 

Any help or tips will be appreciated.

Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions

there is an answer from the ST support.

They explained that in order to have multiple-byte read with I2C on lis2dh sensors, there is a bit in the subaddress field that should be set by the user.

As mentioned in datasheet: "In order to read multiple bytes, it is necessary to assert the most significant bit of the subaddress field. In other words, SUB(7) must be equal to 1 while SUB(6-0) represents the address of first register to be read."

View solution in original post

17 REPLIES 17
Eleon BORLINI
ST Employee

Hi @Ywo.1​ ,

note that the STEVAL-MKI135V1 device is the lis2dh, while you are testing the lis2dh12.

They are two different devices. Can you read the correct ID who_am_I?

-Eleon

Ywo.1
Associate II

Thanks for the information. As far as I saw, they are almost the same and both drivers can work.

I can read correct who_am_I register, it returns 0x33 for both lis2dh and lis2dh12.

Hi @Ywo.1​ ,

yes, actually the two devices differs only for the footprint, and not in the relevant registers.

Are you waiting the turn on time before starting the acquisition?

0693W00000DmgeBQAR.png 

And are you using the I2C or the SPI lines for communication? I'm wondering whether this could be an issue related to the multiple bytes reading...

-Eleon

I'm waiting about 2 seconds from mcu turn on until calling Accelerometer_Init function and about 30 seconds until first Accelerometer_Get_Data call. I think it should be enough.

I'm using I2C for communication. Here is the initialization:

static void MX_I2C2_Init(void)
{
  hi2c2.Instance = I2C2;
  hi2c2.Init.ClockSpeed = 100000;
  hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

And again, with lis2dw it works like magic, lis2dh is the problem.

Thanks.

Yair.

Ywo.1
Associate II

Can anyone try to help me? I haven't figured it out yet.

Eleon BORLINI
ST Employee

Hi Yair @Ywo.1​ ,

Did you check the schematic is correct? Are you using the same I2C lines between LIS2DW12 and LIS2DH?

By the way, I have added the STM3220G tag for more help on STM32 configuration side.

-Eleon

I checked several times, also the boards with lis2dh and lis2dw are identical so it should work.

Thanks for adding the tag, anything that could help is appreciated.

Thanks.

Yair.

Hi Yair @Ywo.1​ ,

this should not be the case, but did you have the possibility to test another lis2dh?

-Eleon

Yes. Like I have mentioned in previous posts, I tried with about 5 different board, all have lis2dh sensor.