@@ -61,38 +61,39 @@ int BMI055::init(calData cal, uint8_t address)
6161
6262void BMI055::update ()
6363{
64- int16_t AccelCount[3 ]; // used to read all 6 bytes at once from the BMI055 accel
65- int16_t GyroCount[3 ]; // used to read all 6 bytes at once from the BMI055 gyro
66- uint8_t rawDataAccel[7 ]; // x/y/z accel register data stored here
67- uint8_t rawDataGyro[6 ];
68-
69- readBytesI2C (wire, AccelAddress, BMI055_ACCD_X_LSB, 7 , &rawDataAccel[0 ]); // Read the 7 raw accelerometer data registers into data array
70- accel.timestamp = micros ();
71-
72- readBytesI2C (wire, GyroAddress, BMI055_GYR_RATE_X_LSB , 6 , &rawDataGyro[0 ]); // Read the 6 raw gyroscope data registers into data array
73- gyro.timestamp = micros ();
64+ bool accelReady = readByteI2C (wire, AccelAddress, BMI055_ACCD_X_LSB) & 0x01 ;
65+ bool gyroReady = readByteI2C (wire, GyroAddress, BMI055_GYR_INT_STATUS_0) & 0x80 ;
66+ if (!accelReady && !gyroReady) return ;
7467
75- // accel registers
76- AccelCount[ 0 ] = ((rawDataAccel[ 1 ] << 8 ) | (rawDataAccel[ 0 ] & 0xF0 )) >> 4 ; // Turn the MSB and LSB into a signed 12-bit value
77- AccelCount[ 1 ] = (( rawDataAccel[3 ] << 8 ) | (rawDataAccel[ 2 ] & 0xF0 )) >> 4 ; // praise sign extension, making this code clean and simple.
78- AccelCount[ 2 ] = ((rawDataAccel[ 5 ] << 8 ) | (rawDataAccel[ 4 ] & 0xF0 )) >> 4 ;
68+ int16_t AccelCount[ 3 ] = { 0 };
69+ int16_t GyroCount[ 3 ] = { 0 };
70+ uint8_t rawDataAccel[7 ];
71+ uint8_t rawDataGyro[ 6 ] ;
7972
80- // gyro registers
81- GyroCount[0 ] = (rawDataGyro[1 ] << 8 ) | (rawDataGyro[0 ]);
82- GyroCount[1 ] = (rawDataGyro[3 ] << 8 ) | (rawDataGyro[2 ]);
83- GyroCount[2 ] = (rawDataGyro[5 ] << 8 ) | (rawDataGyro[4 ]);
73+ if (accelReady) {
74+ readBytesI2C (wire, AccelAddress, BMI055_ACCD_X_LSB, 7 , &rawDataAccel[0 ]);
75+ accel.timestamp = micros ();
76+ AccelCount[0 ] = ((rawDataAccel[1 ] << 8 ) | (rawDataAccel[0 ] & 0xF0 )) >> 4 ;
77+ AccelCount[1 ] = ((rawDataAccel[3 ] << 8 ) | (rawDataAccel[2 ] & 0xF0 )) >> 4 ;
78+ AccelCount[2 ] = ((rawDataAccel[5 ] << 8 ) | (rawDataAccel[4 ] & 0xF0 )) >> 4 ;
79+ temperature = -((rawDataAccel[6 ] * -0 .5f ) * (86 .5f - -40 .5f ) / (float )(128 .f ) - 40 .5f ) - 20 .f ;
80+ }
8481
85- float ax, ay, az, gx, gy, gz;
82+ if (gyroReady) {
83+ readBytesI2C (wire, GyroAddress, BMI055_GYR_RATE_X_LSB, 6 , &rawDataGyro[0 ]);
84+ gyro.timestamp = micros ();
85+ GyroCount[0 ] = (rawDataGyro[1 ] << 8 ) | rawDataGyro[0 ];
86+ GyroCount[1 ] = (rawDataGyro[3 ] << 8 ) | rawDataGyro[2 ];
87+ GyroCount[2 ] = (rawDataGyro[5 ] << 8 ) | rawDataGyro[4 ];
88+ }
8689
87- // Calculate the accel value into actual g's per second
88- ax = AccelCount[0 ] * (float )aRes - calibration.accelBias [0 ];
89- ay = AccelCount[1 ] * (float )aRes - calibration.accelBias [1 ];
90- az = AccelCount[2 ] * (float )aRes - calibration.accelBias [2 ];
90+ float ax = AccelCount[0 ] * (float )aRes - calibration.accelBias [0 ];
91+ float ay = AccelCount[1 ] * (float )aRes - calibration.accelBias [1 ];
92+ float az = AccelCount[2 ] * (float )aRes - calibration.accelBias [2 ];
9193
92- // Calculate the gyro value into actual degrees per second
93- gx = GyroCount[0 ] * (float )gRes - calibration.gyroBias [0 ];
94- gy = GyroCount[1 ] * (float )gRes - calibration.gyroBias [1 ];
95- gz = GyroCount[2 ] * (float )gRes - calibration.gyroBias [2 ];
94+ float gx = GyroCount[0 ] * (float )gRes - calibration.gyroBias [0 ];
95+ float gy = GyroCount[1 ] * (float )gRes - calibration.gyroBias [1 ];
96+ float gz = GyroCount[2 ] * (float )gRes - calibration.gyroBias [2 ];
9697
9798 switch (geometryIndex) {
9899 case 0 :
@@ -136,8 +137,6 @@ void BMI055::update()
136137 accel.accelZ = ay; gyro.gyroZ = gy;
137138 break ;
138139 }
139- // Calculate the temperature value into actual deg c
140- temperature = -((rawDataAccel[6 ] * -0 .5f ) * (86 .5f - -40 .5f ) / (float )(128 .f ) - 40 .5f ) - 20 .f ;
141140}
142141
143142void BMI055::getAccel (AccelData* out)
@@ -306,4 +305,32 @@ void BMI055::calibrateAccelGyro(calData* cal)
306305 cal->gyroBias [1 ] = (float )gyro_bias[1 ];
307306 cal->gyroBias [2 ] = (float )gyro_bias[2 ];
308307 cal->valid = true ;
308+ }
309+
310+ // Accel ODR = 2 × bandwidth. PMU_BW values 0x08-0x0F give BW 7.81-1000 Hz.
311+ static const int BMI055_ACCEL_ODR_TABLE[] = {15 , 31 , 62 , 125 , 250 , 500 , 1000 , 2000 };
312+ static const uint8_t BMI055_ACCEL_BW_REG[] = {0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F };
313+
314+ // Gyro: distinct ODR values with highest available bandwidth for each.
315+ static const int BMI055_GYRO_ODR_TABLE[] = {100 , 200 , 400 , 1000 };
316+ static const uint8_t BMI055_GYRO_BW_REG[] = {0x07 , 0x06 , 0x00 , 0x01 };
317+
318+ int BMI055::setAccelODR (int odr_hz) {
319+ if (odr_hz <= 0 ) return -1 ;
320+ int actual = nearestHigherODR (BMI055_ACCEL_ODR_TABLE, 8 , odr_hz);
321+ int idx = 0 ;
322+ while (BMI055_ACCEL_ODR_TABLE[idx] != actual) idx++;
323+ writeByteI2C (wire, AccelAddress, BMI055_PMU_BW, BMI055_ACCEL_BW_REG[idx]);
324+ currentAccelODR = actual;
325+ return actual;
326+ }
327+
328+ int BMI055::setGyroODR (int odr_hz) {
329+ if (odr_hz <= 0 ) return -1 ;
330+ int actual = nearestHigherODR (BMI055_GYRO_ODR_TABLE, 4 , odr_hz);
331+ int idx = 0 ;
332+ while (BMI055_GYRO_ODR_TABLE[idx] != actual) idx++;
333+ writeByteI2C (wire, GyroAddress, BMI055_GYR_BW, BMI055_GYRO_BW_REG[idx]);
334+ currentGyroODR = actual;
335+ return actual;
309336}
0 commit comments