Statistics
| Branch: | Revision:

adafruit_bno055 / Adafruit_BNO055.cpp @ 463eabf7

History | View | Annotate | Download (19.454 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 463eabf7 Wetmelon
 ***************************************************************************/
19 4bc1c0c1 Kevin Townsend
20
#if ARDUINO >= 100
21 463eabf7 Wetmelon
 #include "Arduino.h"
22 4bc1c0c1 Kevin Townsend
#else
23 463eabf7 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 463eabf7 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 463eabf7 Wetmelon
  _sensorID = sensorID;
43
  _address = address;
44 4bc1c0c1 Kevin Townsend
}
45
46
/***************************************************************************
47
 PUBLIC FUNCTIONS
48
 ***************************************************************************/
49
50
/**************************************************************************/
51
/*!
52 463eabf7 Wetmelon
    @brief  Sets up the HW
53
*/
54 4bc1c0c1 Kevin Townsend
/**************************************************************************/
55
bool Adafruit_BNO055::begin(adafruit_bno055_opmode_t mode)
56
{
57 463eabf7 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 463eabf7 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 463eabf7 Wetmelon
  _mode = mode;
115
  write8(BNO055_OPR_MODE_ADDR, _mode);
116
  delay(30);
117 4bc1c0c1 Kevin Townsend
}
118
119
/**************************************************************************/
120
/*!
121 463eabf7 Wetmelon
    @brief  Use the external 32.768KHz crystal
122
*/
123 c4f272e1 ladyada
/**************************************************************************/
124
void Adafruit_BNO055::setExtCrystalUse(boolean usextal)
125
{
126 463eabf7 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
  } else {
135
    write8(BNO055_SYS_TRIGGER_ADDR, 0x00);
136
  }
137
  delay(10);
138
  /* Set the requested operating mode (see section 3.3) */
139
  setMode(modeback);
140
  delay(20);
141 c4f272e1 ladyada
}
142
143
144
/**************************************************************************/
145
/*!
146 463eabf7 Wetmelon
    @brief  Gets the latest system status info
147
*/
148 4bc1c0c1 Kevin Townsend
/**************************************************************************/
149 3b2655dc ladyada
void Adafruit_BNO055::getSystemStatus(uint8_t *system_status, uint8_t *self_test_result, uint8_t *system_error)
150 4bc1c0c1 Kevin Townsend
{
151 463eabf7 Wetmelon
  write8(BNO055_PAGE_ID_ADDR, 0);
152
153
  /* System Status (see section 4.3.58)
154
     ---------------------------------
155
     0 = Idle
156
     1 = System Error
157
     2 = Initializing Peripherals
158
     3 = System Iniitalization
159
     4 = Executing Self-Test
160
     5 = Sensor fusio algorithm running
161
     6 = System running without fusion algorithms */
162
163
  if (system_status != 0)
164
    *system_status    = read8(BNO055_SYS_STAT_ADDR);
165
166
  /* Self Test Results (see section )
167
     --------------------------------
168
     1 = test passed, 0 = test failed
169

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

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