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.

17 REPLIES 17
Eleon BORLINI
ST Employee

HI @Ywo.1​ ,

let's think about something related to the hardware connections / pin settings. Are you connecting the CS pin to Vdd during the I2C communication?

-Eleon

CS pin is constantly connected to 3.3v Vcc.

Just to remind, the same design is working for lis2dw sensors.

Yes. the CS pin is constantly connected to 3.3v Vcc. Image from our board design attached:0693W00000GWhNBQA1.png

Eleon BORLINI
ST Employee

Hi @Ywo.1​ ,

No other clues from my side, unfortunately.

But you might try rising a case on the OLS support page.

Let me please know if they can support you.

-Eleon

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."

Hi @Ywo.1​ ,

that's correct, but it is true also for the LIS2DW12 part number.

Did this suggestion anyway solve your issue?

-Eleon

It is not true for the LIS2DW12 part number. from the datasheet: "an 8-bit sub-address (SUB) is transmitted: the 7 LSb represents the actual register address while the CTRL2 (21h) (IF_ADD_INC) bit defines the address increment." It is set by default to increment address for multiple read/write, and that's the difference between those two devices.

It did solve the problem.

Thanks for all the help anyway.

Hi, I have the same problem as yours and I can see you have solved your problem. Do you mind sharing your code so I can have a cross reference? Thanks in advance!🙏