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!