Revision 312a5b9e

View differences:

Adafruit_BNO055.cpp
15 15
  Written by KTOWN for Adafruit Industries.
16 16

  
17 17
  MIT license, all text above must be included in any redistribution
18
 ***************************************************************************/
18
  ***************************************************************************/
19 19

  
20 20
#if ARDUINO >= 100
21
 #include "Arduino.h"
21
#include "Arduino.h"
22 22
#else
23
 #include "WProgram.h"
23
#include "WProgram.h"
24 24
#endif
25 25

  
26 26
#include <math.h>
......
34 34

  
35 35
/**************************************************************************/
36 36
/*!
37
    @brief  Instantiates a new Adafruit_BNO055 class
38
*/
37
	@brief  Instantiates a new Adafruit_BNO055 class
38
	*/
39 39
/**************************************************************************/
40 40
Adafruit_BNO055::Adafruit_BNO055(int32_t sensorID, uint8_t address)
41 41
{
42
  _sensorID = sensorID;
43
  _address = address;
42
	_sensorID = sensorID;
43
	_address = address;
44 44
}
45 45

  
46 46
/***************************************************************************
......
49 49

  
50 50
/**************************************************************************/
51 51
/*!
52
    @brief  Sets up the HW
53
*/
52
	@brief  Sets up the HW
53
	*/
54 54
/**************************************************************************/
55 55
bool Adafruit_BNO055::begin(adafruit_bno055_opmode_t mode)
56 56
{
57
  /* 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;
57
	/* 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 105
}
106 106

  
107 107
/**************************************************************************/
108 108
/*!
109
    @brief  Puts the chip in the specified operating mode
110
*/
109
	@brief  Puts the chip in the specified operating mode
110
	*/
111 111
/**************************************************************************/
112 112
void Adafruit_BNO055::setMode(adafruit_bno055_opmode_t mode)
113 113
{
114
  _mode = mode;
115
  write8(BNO055_OPR_MODE_ADDR, _mode);
116
  delay(30);
114
	_mode = mode;
115
	write8(BNO055_OPR_MODE_ADDR, _mode);
116
	delay(30);
117 117
}
118 118

  
119 119
/**************************************************************************/
120 120
/*!
121
    @brief  Use the external 32.768KHz crystal
122
*/
121
	@brief  Use the external 32.768KHz crystal
122
	*/
123 123
/**************************************************************************/
124 124
void Adafruit_BNO055::setExtCrystalUse(boolean usextal)
125 125
{
126
  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);
126
	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);
141 142
}
142 143

  
143 144

  
144 145
/**************************************************************************/
145 146
/*!
146
    @brief  Gets the latest system status info
147
*/
147
	@brief  Gets the latest system status info
148
	*/
148 149
/**************************************************************************/
149 150
void Adafruit_BNO055::getSystemStatus(uint8_t *system_status, uint8_t *self_test_result, uint8_t *system_error)
150 151
{
151
  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);
152
	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);
198 199
}
199 200

  
200 201
/**************************************************************************/
201 202
/*!
202
    @brief  Gets the chip revision numbers
203
*/
203
	@brief  Gets the chip revision numbers
204
	*/
204 205
/**************************************************************************/
205 206
void Adafruit_BNO055::getRevInfo(adafruit_bno055_rev_info_t* info)
206 207
{
207
  uint8_t a, b;
208
	uint8_t a, b;
208 209

  
209
  memset(info, 0, sizeof(adafruit_bno055_rev_info_t));
210
	memset(info, 0, sizeof(adafruit_bno055_rev_info_t));
210 211

  
211
  /* Check the accelerometer revision */
212
  info->accel_rev = read8(BNO055_ACCEL_REV_ID_ADDR);
212
	/* Check the accelerometer revision */
213
	info->accel_rev = read8(BNO055_ACCEL_REV_ID_ADDR);
213 214

  
214
  /* Check the magnetometer revision */
215
  info->mag_rev   = read8(BNO055_MAG_REV_ID_ADDR);
215
	/* Check the magnetometer revision */
216
	info->mag_rev = read8(BNO055_MAG_REV_ID_ADDR);
216 217

  
217
  /* Check the gyroscope revision */
218
  info->gyro_rev  = read8(BNO055_GYRO_REV_ID_ADDR);
218
	/* Check the gyroscope revision */
219
	info->gyro_rev = read8(BNO055_GYRO_REV_ID_ADDR);
219 220

  
220
  /* Check the SW revision */
221
  info->bl_rev    = read8(BNO055_BL_REV_ID_ADDR);
221
	/* Check the SW revision */
222
	info->bl_rev = read8(BNO055_BL_REV_ID_ADDR);
222 223

  
223
  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);
224
	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);
226 227
}
227 228

  
228 229
/**************************************************************************/
229 230
/*!
230
    @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
*/
231
	@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
	*/
234 235
/**************************************************************************/
235 236
void Adafruit_BNO055::getCalibration(uint8_t* sys, uint8_t* gyro, uint8_t* accel, uint8_t* mag) {
236
  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
  }
237
	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
	}
249 250
}
250 251

  
251 252
/**************************************************************************/
252 253
/*!
253
    @brief  Gets the temperature in degrees celsius
254
*/
254
	@brief  Gets the temperature in degrees celsius
255
	*/
255 256
/**************************************************************************/
256 257
int8_t Adafruit_BNO055::getTemp(void)
257 258
{
258
  int8_t temp = (int8_t)(read8(BNO055_TEMP_ADDR));
259
  return temp;
259
	int8_t temp = (int8_t)(read8(BNO055_TEMP_ADDR));
260
	return temp;
260 261
}
261 262

  
262 263
/**************************************************************************/
263 264
/*!
264
    @brief  Gets a vector reading from the specified source
265
*/
265
	@brief  Gets a vector reading from the specified source
266
	*/
266 267
/**************************************************************************/
267 268
imu::Vector<3> Adafruit_BNO055::getVector(adafruit_vector_type_t vector_type)
268 269
{
269
  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