This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problems with accessing Magneto- and Gyrometer from the BMX055 sensor

Hello, we are working on a project where we use the nrf52836 with a BMX055 sensor. Due to BLE, we have to use a softdevice. For now, we are using this version of the sdk: nRF5_SDK_11.0.0_89a8197

We want to read the following sensors:

  • Accelerometer (works like a charm)
  • Gyrometer
  • Magnetometer

We used this documentation here: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMX055-DS000-02.pdf


Ok, now to our problems: we have problems accessing the values for both the gyro- and magnetometer. I set the magnetometer to active mode by setting both OpMode bits in register 0x4C to 0 with this code:

uint8_t reg[1] = {0};
nrf_drv_twi_tx(&m_twi_mma_7660, 0x4C, reg, sizeof(reg), true); 

I try to access the values this way, following this example:

void getMagnet(int16_t * data)
{
		uint8_t reg[0x72];
		nrf_drv_twi_rx(&m_twi_mma_7660, BMX055_MAGNETO_ADRESS, reg, sizeof(reg));
		int MAG_RAW_OFFSET = 0x42;
		//check data ready bit
		if (true) {
			int16_t tmpX 			= (int16_t) (((int16_t)reg[MAG_RAW_OFFSET+1] << 8) | reg[MAG_RAW_OFFSET+0]) >> 3;
			int16_t tmpY 			= (int16_t) (((int16_t)reg[MAG_RAW_OFFSET+3] << 8) | reg[MAG_RAW_OFFSET+2]) >> 3;
			int16_t tmpZ 			= (int16_t) (((int16_t)reg[MAG_RAW_OFFSET+5] << 8) | reg[MAG_RAW_OFFSET+4]) >> 1;
			uint16_t hallRes 	= (uint16_t) (((uint16_t)reg[MAG_RAW_OFFSET+7] << 8) | reg[MAG_RAW_OFFSET+6]) >> 2;
			
			#define BMM050_DIG_X1             0x5D // needed for magnetic field calculation
			#define BMM050_DIG_Y1             0x5E  
			#define BMM050_DIG_Z4_LSB         0x62
			#define BMM050_DIG_Z4_MSB         0x63
			#define BMM050_DIG_X2             0x64  
			#define BMM050_DIG_Y2             0x65  
			#define BMM050_DIG_Z2_LSB         0x68  
			#define BMM050_DIG_Z2_MSB         0x69  
			#define BMM050_DIG_Z1_LSB         0x6A  
			#define BMM050_DIG_Z1_MSB         0x6B  
			#define BMM050_DIG_XYZ1_LSB       0x6C 
			#define BMM050_DIG_XYZ1_MSB       0x6D 
			#define BMM050_DIG_Z3_LSB         0x6E
			#define BMM050_DIG_Z3_MSB         0x6F
			#define BMM050_DIG_XY2            0x70 
			#define BMM050_DIG_XY1 						0x71 
			
			nrf_drv_twi_rx(&m_twi_mma_7660, BMX055_ACCEL_ADRESS, reg, sizeof(reg));
			int16_t dig_x1 = reg[BMM050_DIG_X1];
			int16_t dig_x2 = reg[BMM050_DIG_X2];
			int16_t dig_y1 = reg[BMM050_DIG_Y1];
			int16_t dig_y2 = reg[BMM050_DIG_Y2];
			int16_t dig_xy1 = reg[BMM050_DIG_XY1];
			int16_t dig_xy2 = reg[BMM050_DIG_XY2];
			
			nrf_drv_twi_rx(&m_twi_mma_7660, BMX055_MAGNETO_ADRESS, reg, sizeof(reg));
			
			int16_t dig_z1 = (uint16_t) (((uint16_t)reg[BMM050_DIG_Z1_LSB+1] << 8) | reg[BMM050_DIG_Z1_LSB]);  
			int16_t dig_z2 = (int16_t) (((int16_t)reg[BMM050_DIG_Z2_LSB+1] << 8) | reg[BMM050_DIG_Z2_LSB]);  
			int16_t dig_z3 = (int16_t) (((int16_t)reg[BMM050_DIG_Z3_LSB+1] << 8) | reg[BMM050_DIG_Z3_LSB]);  
			int16_t dig_z4 = (int16_t) (((int16_t)reg[BMM050_DIG_Z4_LSB+1] << 8) | reg[BMM050_DIG_Z4_LSB]);
			
			int16_t dig_xyz1 = (uint16_t) (((uint16_t)reg[BMM050_DIG_XYZ1_LSB+1] << 8) | reg[BMM050_DIG_XYZ1_LSB]);  
			//temperature compensation
			int16_t temp = ((int16_t)(((uint16_t)((((int32_t)dig_xyz1) << 14)/(hallRes!=0? hallRes : dig_xyz1))) - ((uint16_t)0x4000)));
			int16_t finalX = ((int16_t)((((int32_t)tmpX) *
													((((((((int32_t)dig_xy2) * ((((int32_t)temp) * ((int32_t)temp)) >> 7)) +
													(((int32_t)temp) * ((int32_t)(((int16_t)dig_xy1) << 7)))) >> 9) +
													((int32_t)0x100000)) * ((int32_t)(((int16_t)dig_x2) + ((int16_t)0xA0)))) >> 12)) >> 13)) +
													(((int16_t)dig_x1) << 3);

			int16_t finalY = ((int16_t)((((int32_t)tmpY) *
													((((((((int32_t)dig_xy2) * ((((int32_t)temp) * ((int32_t)temp)) >> 7)) + 
													(((int32_t)temp) * ((int32_t)(((int16_t)dig_xy1) << 7)))) >> 9) +
													((int32_t)0x100000)) * ((int32_t)(((int16_t)dig_y2) + ((int16_t)0xA0)))) >> 12)) >> 13)) +
													(((int16_t)dig_y1) << 3);
			int16_t finalZ = (((((int32_t)(tmpZ - dig_z4)) << 15) - ((((int32_t)dig_z3) * ((int32_t)(((int16_t)hallRes) -
													((int16_t)dig_xyz1))))>>2))/(dig_z2 + ((int16_t)(((((int32_t)dig_z1) * 
													((((int16_t)hallRes) << 1)))+(1<<15))>>16))));
			/*float accG = 1.;
			float accBits = 1.6;
			*/
			//printf("x=%i, y=%i, z=%i\n", (tmpX), (tmpY), (tmpZ));
			//printf("MAGNET: x=%i, y=%i, z=%i\n", (finalX), (finalY), (finalZ));
			data[0] = finalX;
			data[1] = finalY;
			data[2] = finalZ;
		}					

}

Magneto Address is 0x13.

But the values in tmpX, tmpY and tmpZ are all just 1; What are we doing wrong here?


Our other problem is the Gyrometer, we can access it just fine without the SoftDevice, but as soon as we try to access it with a softDevice, we get a NRF_DRV_TWI_EVT_ADDRESS_NACK error, what could be the problem here?

Our code for the Gyrometer looks like this:

void getGyro(int16_t * data)
{
		uint8_t reg[8];
		nrf_drv_twi_rx(&m_twi_mma_7660, BMX055_GYRO_ADRESS, reg, sizeof(reg));
		int16_t x,y,z;
		x = (int16_t) (((int16_t)reg[3] << 8) | reg[2]) >> 4;
		y = (int16_t) (((int16_t)reg[5] << 8) | reg[4]) >> 4;
		z = (int16_t) (((int16_t)reg[7] << 8) | reg[6]) >> 4;
		float accG = 249.75;
		float accBits = 32768.0;
		data[0]=x;//(x*(accG/(float)accBits));
		data[1]=y;//(y*(accG/(float)accBits));
		data[2]=z;//(z*(accG/(float)accBits));
	  //printf("GYRO: x=%f, y=%f, z=%f\n", (x*(accG/(float)accBits)), (y*(accG/(float)accBits)), (z*(accG/(float)accBits)));
}

Gyro Address is 0x69.

Thanks for your help!

Parents
  • Again: thanks a lot for your support! We fixed the issue and I want to summarize how to connect the sensor to the board.

    The board we are using is called "Rigado BMD 300". www.rigado.com/.../

    The sensor we are using is called "Bosch BMX055". www.bosch-sensortec.com/.../bmx055 The sensor is connected with a breakout board made by a Company called MasterE.

    The correct I2C-connection is (master left, slave right): VSHIELD -> VDD (top left) | GND -> GND (bottom right) | PO.03 -> SDx | P0.28 -> SCx

    The two PO-pins must be declared as SC and SD in the firmware. As example we used TWI-Scanner (NRF 12). The scanner now recognizes the sensors. I hope this helps you. :-) Thanks again and keep up the great support.

Reply
  • Again: thanks a lot for your support! We fixed the issue and I want to summarize how to connect the sensor to the board.

    The board we are using is called "Rigado BMD 300". www.rigado.com/.../

    The sensor we are using is called "Bosch BMX055". www.bosch-sensortec.com/.../bmx055 The sensor is connected with a breakout board made by a Company called MasterE.

    The correct I2C-connection is (master left, slave right): VSHIELD -> VDD (top left) | GND -> GND (bottom right) | PO.03 -> SDx | P0.28 -> SCx

    The two PO-pins must be declared as SC and SD in the firmware. As example we used TWI-Scanner (NRF 12). The scanner now recognizes the sensors. I hope this helps you. :-) Thanks again and keep up the great support.

Children
No Data
Related