Skip to content

Commit bd40c72

Browse files
committed
Use single dataReady() method, instead of accelDataReady/gyroDataReady
This method is a bit more flexible. There is a version with no parameters, which will return true if all enabled sensors have new data. There is one overload, that takes a single 'flags' parameter, which returns true if all enabled *and* selected sensors have new data. Sensors are selectable through bit flags. For example; CurieIMU.dataReady() : this will return true if both the accel and gyro are enabled, and both have new data ready. CurieIMU.dataReady(ACCEL | GYRO) : this will return true if both the accel and gyro are enabled, and both have new data ready. CurieIMU.dataReady(GYRO) : this will return true if the gyro is enabled and has new data ready. CurieIMU.dataReady(ACCEL) : this will return true if the accel is enabled and has new data ready. This also involved changing the 'begin' method to allow selective enabling of sensors, e.g. CurieIMU.begin() : same as it always has, initializes IMU, enabling both accel and gyro CurieIMU.begin(ACCEL | GYRO) : initializes IMU, enabling both accel and gyro CurieIMU.begin(ACCEL) : initializes IMU, enabling accel only
1 parent 29daefb commit bd40c72

File tree

5 files changed

+123
-37
lines changed

5 files changed

+123
-37
lines changed

libraries/CurieIMU/keywords.txt

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CurieIMUClass KEYWORD1
1414

1515
begin KEYWORD1
1616

17+
dataReady KEYWORD1
1718
getGyroRate KEYWORD1
1819
setGyroRate KEYWORD1
1920
getAccelerometerRate KEYWORD1
@@ -84,6 +85,9 @@ CurieIMU KEYWORD2
8485
# Constants (LITERAL1)
8586
#######################################
8687

88+
ACCEL LITERAL1
89+
GYRO LITERAL1
90+
8791
X_AXIS LITERAL1
8892
Y_AXIS LITERAL1
8993
Z_AXIS LITERAL1

libraries/CurieIMU/src/BMI160.cpp

+41-16
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ uint8_t BMI160Class::reg_read_bits(uint8_t reg, unsigned pos, unsigned len)
8585
* after start-up). This function also sets both the accelerometer and the gyroscope
8686
* to default range settings, namely +/- 2g and +/- 250 degrees/sec.
8787
*/
88-
void BMI160Class::initialize()
88+
void BMI160Class::initialize(unsigned int flags)
8989
{
90+
sensors_enabled = 0;
91+
9092
/* Issue a soft-reset to bring the device into a clean state */
9193
reg_write(BMI160_RA_CMD, BMI160_CMD_SOFT_RESET);
9294
delay(1);
@@ -95,26 +97,36 @@ void BMI160Class::initialize()
9597
reg_read(0x7F);
9698
delay(1);
9799

98-
/* Power up the accelerometer */
99-
reg_write(BMI160_RA_CMD, BMI160_CMD_ACC_MODE_NORMAL);
100-
delay(1);
101-
/* Wait for power-up to complete */
102-
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
100+
if (flags & ACCEL) {
101+
/* Power up the accelerometer */
102+
reg_write(BMI160_RA_CMD, BMI160_CMD_ACC_MODE_NORMAL);
103+
delay(1);
104+
105+
/* Wait for power-up to complete */
106+
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
103107
BMI160_ACC_PMU_STATUS_BIT,
104108
BMI160_ACC_PMU_STATUS_LEN))
109+
delay(1);
110+
111+
sensors_enabled |= ACCEL;
112+
}
113+
114+
if (flags & GYRO) {
115+
/* Power up the gyroscope */
116+
reg_write(BMI160_RA_CMD, BMI160_CMD_GYR_MODE_NORMAL);
105117
delay(1);
106118

107-
/* Power up the gyroscope */
108-
reg_write(BMI160_RA_CMD, BMI160_CMD_GYR_MODE_NORMAL);
109-
delay(1);
110-
/* Wait for power-up to complete */
111-
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
119+
/* Wait for power-up to complete */
120+
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
112121
BMI160_GYR_PMU_STATUS_BIT,
113122
BMI160_GYR_PMU_STATUS_LEN))
114-
delay(1);
123+
delay(1);
124+
125+
sensors_enabled |= GYRO;
126+
}
115127

116-
setFullScaleGyroRange(BMI160_GYRO_RANGE_250);
117-
setFullScaleAccelRange(BMI160_ACCEL_RANGE_2G);
128+
setFullScaleGyroRange(BMI160_GYRO_RANGE_250, 250.0f);
129+
setFullScaleAccelRange(BMI160_ACCEL_RANGE_2G, 2.0f);
118130

119131
/* Only PIN1 interrupts currently supported - map all interrupts to PIN1 */
120132
reg_write(BMI160_RA_INT_MAP_0, 0xFF);
@@ -131,6 +143,17 @@ uint8_t BMI160Class::getDeviceID() {
131143
return reg_read(BMI160_RA_CHIP_ID);
132144
}
133145

146+
/* Checks if the specified sensors are enabled (sensors are specified using
147+
* bit flags defined by CurieIMUSensor enum). If 0 is passed, checks if *any*
148+
* sensors are enabled */
149+
bool BMI160Class::isEnabled(unsigned int sensors)
150+
{
151+
if (sensors == 0)
152+
return sensors_enabled > 0;
153+
154+
return (sensors_enabled & sensors) > 0;
155+
}
156+
134157
/** Verify the SPI connection.
135158
* Make sure the device is connected and responds as expected.
136159
* @return True if connection is valid, false otherwise
@@ -330,10 +353,11 @@ uint8_t BMI160Class::getFullScaleGyroRange() {
330353
* @param range New full-scale gyroscope range value
331354
* @see getFullScaleGyroRange()
332355
*/
333-
void BMI160Class::setFullScaleGyroRange(uint8_t range) {
356+
void BMI160Class::setFullScaleGyroRange(uint8_t range, float real) {
334357
reg_write_bits(BMI160_RA_GYRO_RANGE, range,
335358
BMI160_GYRO_RANGE_SEL_BIT,
336359
BMI160_GYRO_RANGE_SEL_LEN);
360+
gyro_range = real;
337361
}
338362

339363
/** Get full-scale accelerometer range.
@@ -362,10 +386,11 @@ uint8_t BMI160Class::getFullScaleAccelRange() {
362386
* @see getFullScaleAccelRange()
363387
* @see BMI160AccelRange
364388
*/
365-
void BMI160Class::setFullScaleAccelRange(uint8_t range) {
389+
void BMI160Class::setFullScaleAccelRange(uint8_t range, float real) {
366390
reg_write_bits(BMI160_RA_ACCEL_RANGE, range,
367391
BMI160_ACCEL_RANGE_SEL_BIT,
368392
BMI160_ACCEL_RANGE_SEL_LEN);
393+
accel_range = real;
369394
}
370395

371396
/** Get accelerometer offset compensation enabled value.

libraries/CurieIMU/src/BMI160.h

+15-3
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ THE SOFTWARE.
267267

268268
#define BMI160_RA_CMD 0x7E
269269

270+
/* Bit flags for selecting individual sensors */
271+
typedef enum {
272+
GYRO = 0x1,
273+
ACCEL = 0x2
274+
} CurieIMUSensor;
275+
270276
/**
271277
* Interrupt Latch Mode options
272278
* @see setInterruptLatch()
@@ -471,9 +477,10 @@ typedef enum {
471477

472478
class BMI160Class {
473479
public:
474-
void initialize();
480+
void initialize(unsigned int flags);
475481
bool testConnection();
476482

483+
bool isEnabled(unsigned int sensors);
477484
uint8_t getGyroRate();
478485
void setGyroRate(uint8_t rate);
479486

@@ -487,9 +494,9 @@ class BMI160Class {
487494
void setAccelDLPFMode(uint8_t bandwidth);
488495

489496
uint8_t getFullScaleGyroRange();
490-
void setFullScaleGyroRange(uint8_t range);
497+
void setFullScaleGyroRange(uint8_t range, float real);
491498
uint8_t getFullScaleAccelRange();
492-
void setFullScaleAccelRange(uint8_t range);
499+
void setFullScaleAccelRange(uint8_t range, float real);
493500

494501
void autoCalibrateGyroOffset();
495502
bool getGyroOffsetEnabled();
@@ -656,6 +663,11 @@ class BMI160Class {
656663
bool gyroDataReady();
657664
bool accelDataReady();
658665

666+
/* Use a bitmask to track which sensors are enabled */
667+
unsigned sensors_enabled;
668+
float accel_range;
669+
float gyro_range;
670+
659671
protected:
660672
virtual int serial_buffer_transfer(uint8_t *buf, unsigned tx_cnt, unsigned rx_cnt) = 0;
661673

libraries/CurieIMU/src/CurieIMU.cpp

+58-15
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
* on the Curie module, before calling BMI160::initialize() to activate the
3333
* BMI160 accelerometer and gyroscpoe with default settings.
3434
*/
35-
bool CurieIMUClass::begin()
35+
36+
bool CurieIMUClass::configure_imu(unsigned int sensors)
3637
{
3738
ss_spi_init(SPI_SENSING_1, 2000, SPI_BUSMODE_0, SPI_8_BIT, SPI_SE_1);
3839

@@ -41,7 +42,7 @@ bool CurieIMUClass::begin()
4142
serial_buffer_transfer(&dummy_reg, 1, 1);
4243

4344
/* The SPI interface is ready - now invoke the base class initialization */
44-
BMI160Class::initialize();
45+
initialize(sensors);
4546

4647
/** Verify the SPI connection.
4748
* MakgetGyroRatee sure the device is connected and responds as expected.
@@ -50,16 +51,56 @@ bool CurieIMUClass::begin()
5051
if (CURIE_IMU_CHIP_ID != getDeviceID())
5152
return false;
5253

53-
accel_range = (float) getAccelerometerRange();
54-
gyro_range = (float) getGyroRange();
5554
return true;
5655
}
5756

57+
bool CurieIMUClass::begin()
58+
{
59+
return configure_imu(GYRO | ACCEL);
60+
}
61+
62+
bool CurieIMUClass::begin(unsigned int sensors)
63+
{
64+
return configure_imu(sensors);
65+
}
66+
5867
void CurieIMUClass::end()
5968
{
6069
ss_spi_disable(SPI_SENSING_1);
6170
}
6271

72+
bool CurieIMUClass::dataReady()
73+
{
74+
/* If no sensors are enabled */
75+
if (!isEnabled(0))
76+
return false;
77+
78+
if (isEnabled(GYRO) && !gyroDataReady())
79+
return false;
80+
81+
if (isEnabled(ACCEL) && !accelDataReady())
82+
return false;
83+
84+
return true;
85+
}
86+
87+
bool CurieIMUClass::dataReady(unsigned int sensors)
88+
{
89+
/* If no sensors enabled, or no data requested */
90+
if (sensors == 0 || !isEnabled(0))
91+
return false;
92+
93+
if ((sensors & GYRO) && isEnabled(GYRO) && !gyroDataReady()) {
94+
return false;
95+
}
96+
97+
if ((sensors & ACCEL) && isEnabled(ACCEL) && !accelDataReady()) {
98+
return false;
99+
}
100+
101+
return true;
102+
}
103+
63104
int CurieIMUClass::getGyroRate()
64105
{
65106
int rate;
@@ -227,25 +268,26 @@ int CurieIMUClass::getGyroRange()
227268
void CurieIMUClass::setGyroRange(int range)
228269
{
229270
BMI160GyroRange bmiRange;
271+
float real;
230272

231273
if (range >= 2000) {
232274
bmiRange = BMI160_GYRO_RANGE_2000;
233-
gyro_range = 2000.0f;
275+
real = 2000.0f;
234276
} else if (range >= 1000) {
235277
bmiRange = BMI160_GYRO_RANGE_1000;
236-
gyro_range = 1000.0f;
278+
real = 1000.0f;
237279
} else if (range >= 500) {
238280
bmiRange = BMI160_GYRO_RANGE_500;
239-
gyro_range = 500.0f;
281+
real = 500.0f;
240282
} else if (range >= 250) {
241283
bmiRange = BMI160_GYRO_RANGE_250;
242-
gyro_range = 250.0f;
284+
real = 250.0f;
243285
} else {
244286
bmiRange = BMI160_GYRO_RANGE_125;
245-
gyro_range = 125.0f;
287+
real = 125.0f;
246288
}
247289

248-
setFullScaleGyroRange(bmiRange);
290+
setFullScaleGyroRange(bmiRange, real);
249291
}
250292

251293
int CurieIMUClass::getAccelerometerRange()
@@ -277,22 +319,23 @@ int CurieIMUClass::getAccelerometerRange()
277319
void CurieIMUClass::setAccelerometerRange(int range)
278320
{
279321
BMI160AccelRange bmiRange;
322+
float real;
280323

281324
if (range <= 2) {
282325
bmiRange = BMI160_ACCEL_RANGE_2G;
283-
accel_range = 2.0f;
326+
real = 2.0f;
284327
} else if (range <= 4) {
285328
bmiRange = BMI160_ACCEL_RANGE_4G;
286-
accel_range = 4.0f;
329+
real = 4.0f;
287330
} else if (range <= 8) {
288331
bmiRange = BMI160_ACCEL_RANGE_8G;
289-
accel_range = 8.0f;
332+
real = 8.0f;
290333
} else {
291334
bmiRange = BMI160_ACCEL_RANGE_16G;
292-
accel_range = 16.0f;
335+
real = 16.0f;
293336
}
294337

295-
setFullScaleAccelRange(bmiRange);
338+
setFullScaleAccelRange(bmiRange, real);
296339
}
297340

298341
void CurieIMUClass::autoCalibrateGyroOffset()

libraries/CurieIMU/src/CurieIMU.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,13 @@ class CurieIMUClass : public BMI160Class {
9494
friend void bmi160_pin1_isr(void);
9595

9696
public:
97+
bool begin(unsigned int sensors);
9798
bool begin(void);
9899
void end(void);
99100

101+
bool dataReady();
102+
bool dataReady(unsigned int sensors);
103+
100104
// supported values: 25, 50, 100, 200, 400, 800, 1600, 3200 (Hz)
101105
int getGyroRate();
102106
void setGyroRate(int rate);
@@ -207,11 +211,9 @@ class CurieIMUClass : public BMI160Class {
207211
void detachInterrupt(void);
208212

209213
private:
214+
bool configure_imu(unsigned int sensors);
210215
int serial_buffer_transfer(uint8_t *buf, unsigned tx_cnt, unsigned rx_cnt);
211216

212-
float accel_range;
213-
float gyro_range;
214-
215217
float getFreefallDetectionThreshold();
216218
void setFreefallDetectionThreshold(float threshold);
217219
float getShockDetectionThreshold();

0 commit comments

Comments
 (0)