cancel
Showing results for 
Search instead for 
Did you mean: 

LSM303AGR: Accelerometer and magnetometer cannot work at the same time if thresholds were set (I2C communication)

RJasz
Associate II

Hi guys,

I succesfully wrote a code that reads XZY of magnetometer and accelerometer at the same time. It works well only if there was no write to accelerometer thresholds registers!!!

It is initialization to accelerometer:

	const uint8_t REG_10HZ_WAIT_FOR_INSERT_OR_SHOW[][2]=
	{
	// Turn on the sensor, enable X, Y, and Z
	// ODR = 10 Hz
	{LSM303AGR_ACC_CTRL_REG1	,LSM303AGR_ACC_ZEN_ENABLED | LSM303AGR_ACC_YEN_ENABLED |
				LSM303AGR_ACC_XEN_ENABLED | LSM303AGR_ACC_LPEN_ENABLED |
				LSM303AGR_ACC_ODR_DO_10Hz},
	// High-pass filter enabled on data and interrupt1
	{LSM303AGR_ACC_CTRL_REG2	, LSM303AGR_ACC_FDS_BYPASSED|LSM303AGR_ACC_HPCF_00|
			LSM303AGR_ACC_HPM_NORMAL|LSM303AGR_ACC_HPIS1_DISABLED},	
	// Interrupt driven to INT1 pad
		{LSM303AGR_ACC_CTRL_REG3	, 0}
 
	//Threshold
	{LSM303AGR_ACC_INT2_THS	, 0},
	{LSM303AGR_ACC_INT2_DURATION	, 0},	
		
	};

When I remove the last two lines - magnetometer works! Otherwise, I can only get samples from accelerometer.

This is how setup magnetometer:

	value = LSM303AGR_MAG_MD_CONTINUOS_MODE| LSM303AGR_MAG_LP_MODE;
	payload.reg = LSM303AGR_MAG_CFG_REG_A;		
	payload.pBuffer = &value;
	payload.size = 1;
	payload.destination = SEL_MAG;
		
	MEMS_writeData(&payload);

Magnetometer reading:

err_t MEMS_MAG_readSampleAndSleep(int16_t *x,int16_t *y,int16_t *z)
{
	uint8_t value;
	uint16_t delay2;
	value = 0;
	payload_t payload;
 
	payload.reg = LSM303AGR_MAG_STATUS_REG;		
	payload.pBuffer = &value;
	payload.size = 1;
	payload.destination = SEL_MAG;
		
	MEMS_readData(&payload);
		
	if(value & LSM303AGR_MAG_ZYXDA_EV_ON)
	{
		payload.destination = SEL_MAG;
		payload.reg = LSM303AGR_MAG_OUTX_L_REG|0x80; //Enabled auto incremental;
		payload.pBuffer = (uint8_t*)buff;
		payload.size = 6;
		MEMS_readData(&payload);
		*x = buff[0];
		*x |= (int16_t)buff[1]<<8;
		*y= buff[2];
		*y |= (int16_t)buff[3]<<8;
		*z = buff[4];
		*z |= (int16_t)buff[5]<<8;
 
	}else return NO_NEW_DATA;
	return OK;
}

And how I read accelerometer:

void MEMS_getAccXYZ(int8_t *x, int8_t *y, int8_t *z)
{
	static uint8_t buff[6],int2_source;
	payload_t payload;
	
	payload.destination = SEL_ACC;
 
	payload.reg = LSM303AGR_ACC_OUT_X_H|0x80; //Enabled auto incremental;
	payload.pBuffer = (uint8_t*)buff;
	payload.size = 5;
	MEMS_readData(&payload);
	
	*x = buff[0];
	*y = buff[2];
	*z = buff[4];
	
 
}

Once I remove two lines relating to accelerometer thresholds, then disconnect power for a while (must to be), it works again! I have checked all things on Logic Analyzer - I2C from STM32L011 works well too. With two thresholds lines there is no response from magnetometer (no ack to address).

It is a proper communication(without threshold lines)(CS_MAG should be CS_ACC):

0690X000006CtgKQAS.png

This is ACK error when thresholds were stored (accelerometer works well):

0690X000006CthXQAS.png

I already tried:

  • change I2C timming/resistors etc.
  • software restart of all LSM303 registers
  • changed order of the readings
  • changed continous to single shot mode

What is wrong - I did not found any errata to this IC? I spent 3 days to solve it...

I also noticed that even when "threshold lines" are off, the data are ok for same time, but later there is no response from accelerometer or magnetometer. It looks like some problems with switching between those two sensors.

0 REPLIES 0