Statistics
| Branch: | Revision:

adafruit_bno055 / Adafruit_BNO055.cpp @ 312a5b9e

History | View | Annotate | Download (18.621 KB)

1 4bc1c0c1 Kevin Townsend
/***************************************************************************
2
  This is a library for the BNO055 orientation sensor
3

4
  Designed specifically to work with the Adafruit BNO055 Breakout.
5

6
  Pick one up today in the adafruit shop!
7
  ------> http://www.adafruit.com/products
8

9
  These sensors use I2C to communicate, 2 pins are required to interface.
10

11
  Adafruit invests time and resources providing this open source code,
12
  please support Adafruit andopen-source hardware by purchasing products
13
  from Adafruit!
14

15
  Written by KTOWN for Adafruit Industries.
16

17
  MIT license, all text above must be included in any redistribution
18 312a5b9e Wetmelon
  ***************************************************************************/
19 4bc1c0c1 Kevin Townsend
20
#if ARDUINO >= 100
21 312a5b9e Wetmelon
#include "Arduino.h"
22 4bc1c0c1 Kevin Townsend
#else
23 312a5b9e Wetmelon
#include "WProgram.h"
24 4bc1c0c1 Kevin Townsend
#endif
25
26
#include <math.h>
27
#include <limits.h>
28
29
#include "Adafruit_BNO055.h"
30
31
/***************************************************************************
32
 CONSTRUCTOR
33
 ***************************************************************************/
34 40f91f6f Tony DiCola
35 4bc1c0c1 Kevin Townsend
/**************************************************************************/
36
/*!
37 312a5b9e Wetmelon
        @brief  Instantiates a new Adafruit_BNO055 class
38
        */
39 4bc1c0c1 Kevin Townsend
/**************************************************************************/
40
Adafruit_BNO055::Adafruit_BNO055(int32_t sensorID, uint8_t address)
41
{
42 312a5b9e Wetmelon
        _sensorID = sensorID;
43
        _address = address;
44 4bc1c0c1 Kevin Townsend
}
45
46
/***************************************************************************
47
 PUBLIC FUNCTIONS
48
 ***************************************************************************/
49
50
/**************************************************************************/
51
/*!
52 312a5b9e Wetmelon
        @brief  Sets up the HW
53
        */
54 4bc1c0c1 Kevin Townsend
/**************************************************************************/
55
bool Adafruit_BNO055::begin(adafruit_bno055_opmode_t mode)
56
{
57 312a5b9e Wetmelon
        /* Enable I2C */
58
        Wire.begin();
59
60
        /* Make sure we have the right device */
61
        uint8_t id = read8(BNO055_CHIP_ID_ADDR);
62
        if (id != BNO055_ID)
63
        {
64
                delay(1000); // hold on for boot
65
                id = read8(BNO055_CHIP_ID_ADDR);
66
                if (id != BNO055_ID) {
67
                        return false;  // still not? ok bail
68
                }
69
        }
70
71
        /* Switch to config mode (just in case since this is the default) */
72
        setMode(OPERATION_MODE_CONFIG);
73
74
        /* Reset */
75
        write8(BNO055_SYS_TRIGGER_ADDR, 0x20);
76
        while (read8(BNO055_CHIP_ID_ADDR) != BNO055_ID)
77
        {
78
                delay(10);
79
        }
80
        delay(50);
81
82
        /* Set to normal power mode */
83
        write8(BNO055_PWR_MODE_ADDR, POWER_MODE_NORMAL);
84
        delay(10);
85
86
        write8(BNO055_PAGE_ID_ADDR, 0);
87
88
        /* Set the output units */
89
        /*
90
        uint8_t unitsel = (0 << 7) | // Orientation = Android
91
        (0 << 4) | // Temperature = Celsius
92
        (0 << 2) | // Euler = Degrees
93
        (1 << 1) | // Gyro = Rads
94
        (0 << 0);  // Accelerometer = m/s^2
95
        write8(BNO055_UNIT_SEL_ADDR, unitsel);
96
        */
97
98
        write8(BNO055_SYS_TRIGGER_ADDR, 0x0);
99
        delay(10);
100
        /* Set the requested operating mode (see section 3.3) */
101
        setMode(mode);
102
        delay(20);
103
104
        return true;
105 4bc1c0c1 Kevin Townsend
}
106
107
/**************************************************************************/
108
/*!
109 312a5b9e Wetmelon
        @brief  Puts the chip in the specified operating mode
110
        */
111 4bc1c0c1 Kevin Townsend
/**************************************************************************/
112
void Adafruit_BNO055::setMode(adafruit_bno055_opmode_t mode)
113
{
114 312a5b9e Wetmelon
        _mode = mode;
115
        write8(BNO055_OPR_MODE_ADDR, _mode);
116
        delay(30);
117 4bc1c0c1 Kevin Townsend
}
118
119
/**************************************************************************/
120
/*!
121 312a5b9e Wetmelon
        @brief  Use the external 32.768KHz crystal
122
        */
123 c4f272e1 ladyada
/**************************************************************************/
124
void Adafruit_BNO055::setExtCrystalUse(boolean usextal)
125
{
126 312a5b9e Wetmelon
        adafruit_bno055_opmode_t modeback = _mode;
127
128
        /* Switch to config mode (just in case since this is the default) */
129
        setMode(OPERATION_MODE_CONFIG);
130
        delay(25);
131
        write8(BNO055_PAGE_ID_ADDR, 0);
132
        if (usextal) {
133
                write8(BNO055_SYS_TRIGGER_ADDR, 0x80);
134
        }
135
        else {
136
                write8(BNO055_SYS_TRIGGER_ADDR, 0x00);
137
        }
138
        delay(10);
139
        /* Set the requested operating mode (see section 3.3) */
140
        setMode(modeback);
141
        delay(20);
142 c4f272e1 ladyada
}
143
144
145
/**************************************************************************/
146
/*!
147 312a5b9e Wetmelon
        @brief  Gets the latest system status info
148
        */
149 4bc1c0c1 Kevin Townsend
/**************************************************************************/
150 3b2655dc ladyada
void Adafruit_BNO055::getSystemStatus(uint8_t *system_status, uint8_t *self_test_result, uint8_t *system_error)
151 4bc1c0c1 Kevin Townsend
{
152 312a5b9e Wetmelon
        write8(BNO055_PAGE_ID_ADDR, 0);
153
154
        /* System Status (see section 4.3.58)
155
           ---------------------------------
156
           0 = Idle
157
           1 = System Error
158
           2 = Initializing Peripherals
159
           3 = System Iniitalization
160
           4 = Executing Self-Test
161
           5 = Sensor fusio algorithm running
162
           6 = System running without fusion algorithms */
163
164
        if (system_status != 0)
165
                *system_status = read8(BNO055_SYS_STAT_ADDR);
166
167
        /* Self Test Results (see section )
168
           --------------------------------
169
           1 = test passed, 0 = test failed
170

171
           Bit 0 = Accelerometer self test
172
           Bit 1 = Magnetometer self test
173
           Bit 2 = Gyroscope self test
174
           Bit 3 = MCU self test
175

176
           0x0F = all good! */
177
178
        if (self_test_result != 0)
179
                *self_test_result = read8(BNO055_SELFTEST_RESULT_ADDR);
180
181
        /* System Error (see section 4.3.59)
182
           ---------------------------------
183
           0 = No error
184
           1 = Peripheral initialization error
185
           2 = System initialization error
186
           3 = Self test result failed
187
           4 = Register map value out of range
188
           5 = Register map address out of range
189
           6 = Register map write error
190
           7 = BNO low power mode not available for selected operat ion mode
191
           8 = Accelerometer power mode not available
192
           9 = Fusion algorithm configuration error
193
           A = Sensor configuration error */
194
195
        if (system_error != 0)
196
                *system_error = read8(BNO055_SYS_ERR_ADDR);
197
198
        delay(200);
199 4bc1c0c1 Kevin Townsend
}
200
201
/**************************************************************************/
202
/*!
203 312a5b9e Wetmelon
        @brief  Gets the chip revision numbers
204
        */
205 4bc1c0c1 Kevin Townsend
/**************************************************************************/
206
void Adafruit_BNO055::getRevInfo(adafruit_bno055_rev_info_t* info)
207
{
208 312a5b9e Wetmelon
        uint8_t a, b;
209 4bc1c0c1 Kevin Townsend
210 312a5b9e Wetmelon
        memset(info, 0, sizeof(adafruit_bno055_rev_info_t));
211 4bc1c0c1 Kevin Townsend
212 312a5b9e Wetmelon
        /* Check the accelerometer revision */
213
        info->accel_rev = read8(BNO055_ACCEL_REV_ID_ADDR);
214 67f3cff5 Kevin Townsend
215 312a5b9e Wetmelon
        /* Check the magnetometer revision */
216
        info->mag_rev = read8(BNO055_MAG_REV_ID_ADDR);
217 67f3cff5 Kevin Townsend
218 312a5b9e Wetmelon
        /* Check the gyroscope revision */
219
        info->gyro_rev = read8(BNO055_GYRO_REV_ID_ADDR);
220 67f3cff5 Kevin Townsend
221 312a5b9e Wetmelon
        /* Check the SW revision */
222
        info->bl_rev = read8(BNO055_BL_REV_ID_ADDR);
223 40f91f6f Tony DiCola
224 312a5b9e Wetmelon
        a = read8(BNO055_SW_REV_ID_LSB_ADDR);
225
        b = read8(BNO055_SW_REV_ID_MSB_ADDR);
226
        info->sw_rev = (((uint16_t)b) << 8) | ((uint16_t)a);
227 4bc1c0c1 Kevin Townsend
}
228
229
/**************************************************************************/
230
/*!
231 312a5b9e Wetmelon
        @brief  Gets current calibration state.  Each value should be a uint8_t
232
        pointer and it will be set to 0 if not calibrated and 3 if
233
        fully calibrated.
234
        */
235 40f91f6f Tony DiCola
/**************************************************************************/
236
void Adafruit_BNO055::getCalibration(uint8_t* sys, uint8_t* gyro, uint8_t* accel, uint8_t* mag) {
237 312a5b9e Wetmelon
        uint8_t calData = read8(BNO055_CALIB_STAT_ADDR);
238
        if (sys != NULL) {
239
                *sys = (calData >> 6) & 0x03;
240
        }
241
        if (gyro != NULL) {
242
                *gyro = (calData >> 4) & 0x03;
243
        }
244
        if (accel != NULL) {
245
                *accel = (calData >> 2) & 0x03;
246
        }
247
        if (mag != NULL) {
248
                *mag = calData & 0x03;
249
        }
250 40f91f6f Tony DiCola
}
251
252
/**************************************************************************/
253
/*!
254 312a5b9e Wetmelon
        @brief  Gets the temperature in degrees celsius
255
        */
256 0e2e2723 Kevin Townsend
/**************************************************************************/
257
int8_t Adafruit_BNO055::getTemp(void)
258
{
259 312a5b9e Wetmelon
        int8_t temp = (int8_t)(read8(BNO055_TEMP_ADDR));
260
        return temp;
261 0e2e2723 Kevin Townsend
}
262
263
/**************************************************************************/
264
/*!
265 312a5b9e Wetmelon
        @brief  Gets a vector reading from the specified source
266
        */
267 4bc1c0c1 Kevin Townsend
/**************************************************************************/
268 48741e1f Kevin Townsend
imu::Vector<3> Adafruit_BNO055::getVector(adafruit_vector_type_t vector_type)
269 4bc1c0c1 Kevin Townsend
{
270 312a5b9e Wetmelon
        imu::Vector<3> xyz;
271
        uint8_t buffer[6];
272
        memset(buffer, 0, 6);
273
274
        int16_t x, y, z;
275
        x = y = z = 0;
276
277
        /* Read vector data (6 bytes) */
278
        readLen((adafruit_bno055_reg_t)vector_type, buffer, 6);
279
280
        x = ((int16_t)buffer[0]) | (((int16_t)buffer[1]) << 8);
281
        y = ((int16_t)buffer[2]) | (((int16_t)buffer[3]) << 8);
282
        z = ((int16_t)buffer[4]) | (((int16_t)buffer[5]) << 8);
283
284
        /* Convert the value to an appropriate range (section 3.6.4) */
285
        /* and assign the value to the Vector type */
286
        switch (vector_type)
287
        {
288
        case VECTOR_MAGNETOMETER:
289
                /* 1uT = 16 LSB */
290
                xyz[0] = ((double)x) / 16.0;
291
                xyz[1] = ((double)y) / 16.0;
292
                xyz[2] = ((double)z) / 16.0;
293
                break;
294
        case VECTOR_GYROSCOPE:
295
                /* 1rps = 900 LSB */
296
                xyz[0] = ((double)x) / 900.0;
297
                xyz[1] = ((double)y) / 900.0;
298
                xyz[2] = ((double)z) / 900.0;
299
                break;
300
        case VECTOR_EULER:
301
                /* 1 degree = 16 LSB */
302
                xyz[0] = ((double)x) / 16.0;
303
                xyz[1] = ((double)y) / 16.0;
304
                xyz[2] = ((double)z) / 16.0;
305
                break;
306
        case VECTOR_ACCELEROMETER:
307
        case VECTOR_LINEARACCEL:
308
        case VECTOR_GRAVITY:
309
                /* 1m/s^2 = 100 LSB */
310
                xyz[0] = ((double)x) / 100.0;
311
                xyz[1] = ((double)y) / 100.0;
312
                xyz[2] = ((double)z) / 100.0;
313
                break;
314
        }
315
316
        return xyz;
317 4bc1c0c1 Kevin Townsend
}
318
319
/**************************************************************************/
320
/*!
321 312a5b9e Wetmelon
        @brief  Gets a quaternion reading from the specified source
322
        */
323 48741e1f Kevin Townsend
/**************************************************************************/
324
imu::Quaternion Adafruit_BNO055::getQuat(void)
325
{
326 312a5b9e Wetmelon
        uint8_t buffer[8];
327
        memset(buffer, 0, 8);
328
329
        int16_t x, y, z, w;
330
        x = y = z = w = 0;
331
332
        /* Read quat data (8 bytes) */
333
        readLen(BNO055_QUATERNION_DATA_W_LSB_ADDR, buffer, 8);
334
        w = (((uint16_t)buffer[1]) << 8) | ((uint16_t)buffer[0]);
335
        x = (((uint16_t)buffer[3]) << 8) | ((uint16_t)buffer[2]);
336
        y = (((uint16_t)buffer[5]) << 8) | ((uint16_t)buffer[4]);
337
        z = (((uint16_t)buffer[7]) << 8) | ((uint16_t)buffer[6]);
338
339
        /* Assign to Quaternion */
340
        /* See http://ae-bst.resource.bosch.com/media/products/dokumente/bno055/BST_BNO055_DS000_12~1.pdf
341
           3.6.5.5 Orientation (Quaternion)  */
342
        const double scale = (1.0 / (1 << 14));
343
        imu::Quaternion quat(scale * w, scale * x, scale * y, scale * z);
344
        return quat;
345 48741e1f Kevin Townsend
}
346
347
/**************************************************************************/
348
/*!
349 312a5b9e Wetmelon
        @brief  Provides the sensor_t data for this sensor
350
        */
351 4bc1c0c1 Kevin Townsend
/**************************************************************************/
352
void Adafruit_BNO055::getSensor(sensor_t *sensor)
353
{
354 312a5b9e Wetmelon
        /* Clear the sensor_t object */
355
        memset(sensor, 0, sizeof(sensor_t));
356
357
        /* Insert the sensor name in the fixed length char array */
358
        strncpy(sensor->name, "BNO055", sizeof(sensor->name) - 1);
359
        sensor->name[sizeof(sensor->name) - 1] = 0;
360
        sensor->version = 1;
361
        sensor->sensor_id = _sensorID;
362
        sensor->type = SENSOR_TYPE_ORIENTATION;
363
        sensor->min_delay = 0;
364
        sensor->max_value = 0.0F;
365
        sensor->min_value = 0.0F;
366
        sensor->resolution = 0.01F;
367 4bc1c0c1 Kevin Townsend
}
368
369
/**************************************************************************/
370
/*!
371 312a5b9e Wetmelon
        @brief  Reads the sensor and returns the data as a sensors_event_t
372
        */
373 4bc1c0c1 Kevin Townsend
/**************************************************************************/
374
bool Adafruit_BNO055::getEvent(sensors_event_t *event)
375
{
376 312a5b9e Wetmelon
        /* Clear the event */
377
        memset(event, 0, sizeof(sensors_event_t));
378 4bc1c0c1 Kevin Townsend
379 312a5b9e Wetmelon
        event->version = sizeof(sensors_event_t);
380
        event->sensor_id = _sensorID;
381
        event->type = SENSOR_TYPE_ORIENTATION;
382
        event->timestamp = millis();
383 fcd68623 Kevin Townsend
384 312a5b9e Wetmelon
        /* Get a Euler angle sample for orientation */
385
        imu::Vector<3> euler = getVector(Adafruit_BNO055::VECTOR_EULER);
386
        event->orientation.x = euler.x();
387
        event->orientation.y = euler.y();
388
        event->orientation.z = euler.z();
389
390
        return true;
391
}
392 fcd68623 Kevin Townsend
393 312a5b9e Wetmelon
/**************************************************************************/
394
/*!
395
@brief  Reads the sensor's offset registers into a byte array
396
*/
397
/**************************************************************************/
398
bool Adafruit_BNO055::getSensorOffsets(int8_t* calibData)
399
{
400
        if (isFullyCalibrated())
401
        {
402
                adafruit_bno055_opmode_t lastMode = _mode;
403
                setMode(OPERATION_MODE_CONFIG);
404
405
                readLen(ACCEL_OFFSET_X_LSB_ADDR, calibData, NUM_BNO055_OFFSET_REGISTERS);
406
407
                setMode(lastMode);
408
                return true;
409
        }
410
        return false;
411
}
412
413
/**************************************************************************/
414
/*!
415
@brief  Reads the sensor's offset registers into an offset struct
416
*/
417
/**************************************************************************/
418
bool Adafruit_BNO055::getSensorOffsets(adafruit_bno055_offsets_t &offsets_type)
419
{
420
        if (isFullyCalibrated())
421
        {
422
                adafruit_bno055_opmode_t lastMode = _mode;
423
                setMode(OPERATION_MODE_CONFIG);
424
                delay(25);
425
426
                offsets_type.accel_offset_x = (read8(ACCEL_OFFSET_X_MSB_ADDR) << 8) | (read8(ACCEL_OFFSET_X_LSB_ADDR));
427
                offsets_type.accel_offset_y = (read8(ACCEL_OFFSET_Y_MSB_ADDR) << 8) | (read8(ACCEL_OFFSET_Y_LSB_ADDR));
428
                offsets_type.accel_offset_z = (read8(ACCEL_OFFSET_Z_MSB_ADDR) << 8) | (read8(ACCEL_OFFSET_Z_LSB_ADDR));
429
430
                offsets_type.gyro_offset_x = (read8(GYRO_OFFSET_X_MSB_ADDR) << 8) | (read8(GYRO_OFFSET_X_LSB_ADDR));
431
                offsets_type.gyro_offset_y = (read8(GYRO_OFFSET_Y_MSB_ADDR) << 8) | (read8(GYRO_OFFSET_Y_LSB_ADDR));
432
                offsets_type.gyro_offset_z = (read8(GYRO_OFFSET_Z_MSB_ADDR) << 8) | (read8(GYRO_OFFSET_Z_LSB_ADDR));
433
434
                offsets_type.mag_offset_x = (read8(MAG_OFFSET_X_MSB_ADDR) << 8) | (read8(MAG_OFFSET_X_LSB_ADDR));
435
                offsets_type.mag_offset_y = (read8(MAG_OFFSET_Y_MSB_ADDR) << 8) | (read8(MAG_OFFSET_Y_LSB_ADDR));
436
                offsets_type.mag_offset_z = (read8(MAG_OFFSET_Z_MSB_ADDR) << 8) | (read8(MAG_OFFSET_Z_LSB_ADDR));
437
438
                offsets_type.accel_radius = (read8(ACCEL_RADIUS_MSB_ADDR) << 8) | (read8(ACCEL_RADIUS_LSB_ADDR));
439
                offsets_type.mag_radius = (read8(MAG_RADIUS_MSB_ADDR) << 8) | (read8(MAG_RADIUS_LSB_ADDR));
440
441
                setMode(lastMode);
442
                return true;
443
        }
444
        return false;
445
}
446
447
448
/**************************************************************************/
449
/*!
450
@brief  Writes an array of calibration values to the sensor's offset registers
451
*/
452
/**************************************************************************/
453
void Adafruit_BNO055::setSensorOffsets(const int8_t* calibData)
454
{
455
        adafruit_bno055_opmode_t lastMode = _mode;
456
        setMode(OPERATION_MODE_CONFIG);
457
        delay(25);
458
459
        /* A writeLen() would make this much cleaner */
460
        write8(ACCEL_OFFSET_X_LSB_ADDR, calibData[0]);
461
        write8(ACCEL_OFFSET_X_MSB_ADDR, calibData[1]);
462
        write8(ACCEL_OFFSET_Y_LSB_ADDR, calibData[2]);
463
        write8(ACCEL_OFFSET_Y_MSB_ADDR, calibData[3]);
464
        write8(ACCEL_OFFSET_Z_LSB_ADDR, calibData[4]);
465
        write8(ACCEL_OFFSET_Z_MSB_ADDR, calibData[5]);
466
467
        write8(GYRO_OFFSET_X_LSB_ADDR, calibData[6]);
468
        write8(GYRO_OFFSET_X_MSB_ADDR, calibData[7]);
469
        write8(GYRO_OFFSET_Y_LSB_ADDR, calibData[8]);
470
        write8(GYRO_OFFSET_Y_MSB_ADDR, calibData[9]);
471
        write8(GYRO_OFFSET_Z_LSB_ADDR, calibData[10]);
472
        write8(GYRO_OFFSET_Z_MSB_ADDR, calibData[11]);
473
474
        write8(MAG_OFFSET_X_LSB_ADDR, calibData[12]);
475
        write8(MAG_OFFSET_X_MSB_ADDR, calibData[13]);
476
        write8(MAG_OFFSET_Y_LSB_ADDR, calibData[14]);
477
        write8(MAG_OFFSET_Y_MSB_ADDR, calibData[15]);
478
        write8(MAG_OFFSET_Z_LSB_ADDR, calibData[16]);
479
        write8(MAG_OFFSET_Z_MSB_ADDR, calibData[17]);
480
481
        write8(ACCEL_RADIUS_LSB_ADDR, calibData[18]);
482
        write8(ACCEL_RADIUS_MSB_ADDR, calibData[19]);
483
484
        write8(MAG_RADIUS_LSB_ADDR, calibData[20]);
485
        write8(MAG_RADIUS_MSB_ADDR, calibData[21]);
486
487
        setMode(lastMode);
488 4bc1c0c1 Kevin Townsend
}
489
490 312a5b9e Wetmelon
/**************************************************************************/
491
/*!
492
@brief  Writes to the sensor's offset registers from an offset struct
493
*/
494
/**************************************************************************/
495
void Adafruit_BNO055::setSensorOffsets(const adafruit_bno055_offsets_t &offsets_type)
496
{
497
        adafruit_bno055_opmode_t lastMode = _mode;
498
        setMode(OPERATION_MODE_CONFIG);
499
        delay(25);
500
501
        write8(ACCEL_OFFSET_X_LSB_ADDR, (offsets_type.accel_offset_x) & 0x0FF);
502
        write8(ACCEL_OFFSET_X_MSB_ADDR, (offsets_type.accel_offset_x >> 8) & 0x0FF);
503
        write8(ACCEL_OFFSET_Y_LSB_ADDR, (offsets_type.accel_offset_y) & 0x0FF);
504
        write8(ACCEL_OFFSET_Y_MSB_ADDR, (offsets_type.accel_offset_y >> 8) & 0x0FF);
505
        write8(ACCEL_OFFSET_Z_LSB_ADDR, (offsets_type.accel_offset_z) & 0x0FF);
506
        write8(ACCEL_OFFSET_Z_MSB_ADDR, (offsets_type.accel_offset_z >> 8) & 0x0FF);
507
508
        write8(GYRO_OFFSET_X_LSB_ADDR, (offsets_type.gyro_offset_x) & 0x0FF);
509
        write8(GYRO_OFFSET_X_MSB_ADDR, (offsets_type.gyro_offset_x >> 8) & 0x0FF);
510
        write8(GYRO_OFFSET_Y_LSB_ADDR, (offsets_type.gyro_offset_y) & 0x0FF);
511
        write8(GYRO_OFFSET_Y_MSB_ADDR, (offsets_type.gyro_offset_y >> 8) & 0x0FF);
512
        write8(GYRO_OFFSET_Z_LSB_ADDR, (offsets_type.gyro_offset_z) & 0x0FF);
513
        write8(GYRO_OFFSET_Z_MSB_ADDR, (offsets_type.gyro_offset_z >> 8) & 0x0FF);
514
515
        write8(MAG_OFFSET_X_LSB_ADDR, (offsets_type.mag_offset_x) & 0x0FF);
516
        write8(MAG_OFFSET_X_MSB_ADDR, (offsets_type.mag_offset_x >> 8) & 0x0FF);
517
        write8(MAG_OFFSET_Y_LSB_ADDR, (offsets_type.mag_offset_y) & 0x0FF);
518
        write8(MAG_OFFSET_Y_MSB_ADDR, (offsets_type.mag_offset_y >> 8) & 0x0FF);
519
        write8(MAG_OFFSET_Z_LSB_ADDR, (offsets_type.mag_offset_z) & 0x0FF);
520
        write8(MAG_OFFSET_Z_MSB_ADDR, (offsets_type.mag_offset_z >> 8) & 0x0FF);
521
522
        write8(ACCEL_RADIUS_LSB_ADDR, (offsets_type.accel_radius) & 0x0FF);
523
        write8(ACCEL_RADIUS_MSB_ADDR, (offsets_type.accel_radius >> 8) & 0x0FF);
524
525
        write8(MAG_RADIUS_LSB_ADDR, (offsets_type.mag_radius) & 0x0FF);
526
        write8(MAG_RADIUS_MSB_ADDR, (offsets_type.mag_radius >> 8) & 0x0FF);
527
528
        setMode(lastMode);
529
}
530
531
bool Adafruit_BNO055::isFullyCalibrated(void)
532
{
533
        uint8_t system, gyro, accel, mag;
534
        getCalibration(&system, &gyro, &accel, &mag);
535
        if (system < 3 || gyro < 3 || accel < 3 || mag < 3)
536
                return false;
537
        return true;
538
}
539
540
541
542 4bc1c0c1 Kevin Townsend
/***************************************************************************
543
 PRIVATE FUNCTIONS
544
 ***************************************************************************/
545
546
/**************************************************************************/
547
/*!
548 312a5b9e Wetmelon
        @brief  Writes an 8 bit value over I2C
549
        */
550 4bc1c0c1 Kevin Townsend
/**************************************************************************/
551
bool Adafruit_BNO055::write8(adafruit_bno055_reg_t reg, byte value)
552
{
553 312a5b9e Wetmelon
        Wire.beginTransmission(_address);
554
#if ARDUINO >= 100
555
        Wire.write((uint8_t)reg);
556
        Wire.write((uint8_t)value);
557
#else
558
        Wire.send(reg);
559
        Wire.send(value);
560
#endif
561
        Wire.endTransmission();
562
563
        /* ToDo: Check for error! */
564
        return true;
565 4bc1c0c1 Kevin Townsend
}
566
567
/**************************************************************************/
568
/*!
569 312a5b9e Wetmelon
        @brief  Reads an 8 bit value over I2C
570
        */
571 4bc1c0c1 Kevin Townsend
/**************************************************************************/
572 312a5b9e Wetmelon
byte Adafruit_BNO055::read8(adafruit_bno055_reg_t reg)
573 4bc1c0c1 Kevin Townsend
{
574 312a5b9e Wetmelon
        byte value = 0;
575
576
        Wire.beginTransmission(_address);
577
#if ARDUINO >= 100
578
        Wire.write((uint8_t)reg);
579
#else
580
        Wire.send(reg);
581
#endif
582
        Wire.endTransmission();
583
        Wire.requestFrom(_address, (byte)1);
584
#if ARDUINO >= 100
585
        value = Wire.read();
586
#else
587
        value = Wire.receive();
588
#endif
589
590
        return value;
591 4bc1c0c1 Kevin Townsend
}
592
593
/**************************************************************************/
594
/*!
595 312a5b9e Wetmelon
        @brief  Reads the specified number of bytes over I2C
596
        */
597 4bc1c0c1 Kevin Townsend
/**************************************************************************/
598
bool Adafruit_BNO055::readLen(adafruit_bno055_reg_t reg, byte * buffer, uint8_t len)
599
{
600 312a5b9e Wetmelon
        Wire.beginTransmission(_address);
601
#if ARDUINO >= 100
602
        Wire.write((uint8_t)reg);
603
#else
604
        Wire.send(reg);
605
#endif
606
        Wire.endTransmission();
607
        Wire.requestFrom(_address, (byte)len);
608
609
        for (uint8_t i = 0; i < len; i++)
610
        {
611
#if ARDUINO >= 100
612
                buffer[i] = Wire.read();
613
#else
614
                buffer[i] = Wire.receive();
615
#endif
616
        }
617
618
        /* ToDo: Check for errors! */
619
        return true;
620
}