├── DFRobot_BNO055.cpp ├── DFRobot_BNO055.h ├── LICENSE ├── README.md ├── examples ├── config │ └── config.ino ├── imu_show │ └── imu_show.ino ├── interrupt │ └── interrupt.ino └── readData │ └── readData.ino └── keywords.txt /DFRobot_BNO055.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (C) <2019> <@DFRobot Frank> 5 | 6 | ¡¡Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | ¡¡software and associated documentation files (the "Software"), to deal in the Software 8 | ¡¡without restriction, including without limitation the rights to use, copy, modify, 9 | ¡¡merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | ¡¡permit persons to whom the Software is furnished to do so. 11 | 12 | ¡¡The above copyright notice and this permission notice shall be included in all copies or 13 | ¡¡substantial portions of the Software. 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 16 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | */ 20 | #include "DFRobot_BNO055.h" 21 | 22 | // use data struct to map register address 23 | const DFRobot_BNO055::sRegsPage0_t PROGMEM sRegsPage0 = DFRobot_BNO055::sRegsPage0_t(); 24 | const DFRobot_BNO055::sRegsPage1_t PROGMEM sRegsPage1 = DFRobot_BNO055::sRegsPage1_t(); 25 | 26 | #ifdef __AVR__ 27 | typedef uint16_t platformBusWidth_t; 28 | #else 29 | typedef uint32_t platformBusWidth_t; 30 | #endif 31 | 32 | // use regOffset0 to get register offset in reg page0, regOffset1 similar 33 | const platformBusWidth_t regsPage0Addr = (platformBusWidth_t) & sRegsPage0; 34 | const platformBusWidth_t regsPage1Addr = (platformBusWidth_t) & sRegsPage1; 35 | #define regOffset0(reg) ( (platformBusWidth_t) (& (reg)) - regsPage0Addr ) 36 | #define regOffset1(reg) ( (platformBusWidth_t) (& (reg)) - regsPage1Addr ) 37 | 38 | #define __DBG 0 39 | #if __DBG 40 | # define __DBG_CODE(x) Serial.print("__DBG_CODE: "); Serial.print(__FUNCTION__); Serial.print(" "); Serial.print(__LINE__); Serial.print(" "); x; Serial.println() 41 | #else 42 | # define __DBG_CODE(x) 43 | #endif 44 | 45 | #define writeRegBitsHelper(pageId, reg, flied, val) \ 46 | setToPage(pageId); \ 47 | writeRegBits(regOffset##pageId(reg), *(uint8_t*) &(flied), *(uint8_t*) &(val)) 48 | 49 | // main class start ---------------------------------------------------------------- 50 | 51 | DFRobot_BNO055::DFRobot_BNO055() { lastOperateStatus = eStatusOK; _currentPage = 0xff; } 52 | 53 | DFRobot_BNO055::eStatus_t DFRobot_BNO055::begin() 54 | { 55 | uint8_t temp = getReg(regOffset0(sRegsPage0.CHIP_ID), 0); // get chip id 56 | __DBG_CODE(Serial.print("CHIP_ID: "); Serial.print(temp, HEX)); 57 | if((lastOperateStatus == eStatusOK) && (temp == BNO055_REG_CHIP_ID_DEFAULT)) { 58 | uint8_t timeOut = 0; 59 | reset(); 60 | do { 61 | temp = getReg(regOffset0(sRegsPage0.SYS_STATUS), 0); 62 | delay(10); 63 | timeOut ++; 64 | } while((temp != 0) && (timeOut < 100)); 65 | if(timeOut == 100) 66 | lastOperateStatus = eStatusErrDeviceReadyTimeOut; 67 | else { 68 | setOprMode(eOprModeConfig); 69 | setAxisMapConfig(eMapConfig_P1); 70 | delay(50); 71 | setUnit(); 72 | setAccRange(eAccRange_4G); 73 | setGyrRange(eGyrRange_2000); 74 | setPowerMode(ePowerModeNormal); 75 | setOprMode(eOprModeNdof); 76 | delay(50); 77 | } 78 | } else 79 | lastOperateStatus = eStatusErrDeviceNotDetect; 80 | return lastOperateStatus; 81 | } 82 | 83 | 84 | // get data functions ---------------------------------------------------------------- 85 | 86 | // get register offset of raw data 87 | uint8_t getOffsetOfData(DFRobot_BNO055::eAxis_t eAxis) 88 | { 89 | switch(eAxis) { 90 | case DFRobot_BNO055::eAxisAcc: return regOffset0(sRegsPage0.ACC_DATA); 91 | case DFRobot_BNO055::eAxisMag: return regOffset0(sRegsPage0.MAG_DATA); 92 | case DFRobot_BNO055::eAxisGyr: return regOffset0(sRegsPage0.GYR_DATA); 93 | case DFRobot_BNO055::eAxisLia: return regOffset0(sRegsPage0.LIA_DATA); 94 | case DFRobot_BNO055::eAxisGrv: return regOffset0(sRegsPage0.GRV_DATA); 95 | default: return 0; 96 | } 97 | } 98 | 99 | 100 | 101 | DFRobot_BNO055::sAxisAnalog_t DFRobot_BNO055::getAxis(eAxis_t eAxis) 102 | { 103 | sAxisData_t sRaw = getAxisRaw(eAxis); 104 | sAxisAnalog_t sAnalog = {0}; 105 | float factor = 1.0f; 106 | 107 | switch (eAxis) { 108 | // shift accelerometer, gravity vector and linear acceleration data: 1m/s2 = 100lsb, 1mg = 1lsb 109 | case eAxisAcc: factor = 1.0f; break; 110 | case eAxisLia: factor = 1.0f; break; 111 | case eAxisGrv: factor = 1.0f; break; 112 | // shift magnetometer data: 1ut = 16lsb 113 | case eAxisMag: factor = 16.0f; break; 114 | // shift gyroscope data: 1dps = 16lsb, 1rps = 900lsb 115 | case eAxisGyr: factor = 16.0f; break; 116 | default: lastOperateStatus = eStatusErrParameter; break; 117 | } 118 | sAnalog.x = sRaw.x / factor; 119 | sAnalog.y = sRaw.y / factor; 120 | sAnalog.z = sRaw.z / factor; 121 | return sAnalog; 122 | } 123 | 124 | DFRobot_BNO055::sEulAnalog_t DFRobot_BNO055::getEul() 125 | { 126 | sEulData_t sEul = getEulRaw(); 127 | sEulAnalog_t sEulAnalog = {0}; 128 | // shift euler data: 1degree = 16lsb, 1radians = 900lsb 129 | sEulAnalog.head = sEul.head / 16.0f; 130 | sEulAnalog.roll = sEul.roll / 16.0f; 131 | sEulAnalog.pitch = sEul.pitch / 16.0f; 132 | return sEulAnalog; 133 | } 134 | 135 | DFRobot_BNO055::sQuaAnalog_t DFRobot_BNO055::getQua() 136 | { 137 | sQuaData_t sQua = getQuaRaw(); 138 | sQuaAnalog_t sQuaAnalog = {0}; 139 | // shift quaternion data: 1qua = 2^14 lsb 140 | sQuaAnalog.w = sQua.w / 16384.0f; 141 | sQuaAnalog.x = sQua.x / 16384.0f; 142 | sQuaAnalog.y = sQua.y / 16384.0f; 143 | sQuaAnalog.z = sQua.z / 16384.0f; 144 | return sQuaAnalog; 145 | } 146 | 147 | // get register offset of offset 148 | uint8_t getOffsetOfOffset(DFRobot_BNO055::eAxis_t eAxis) 149 | { 150 | switch(eAxis) { 151 | case DFRobot_BNO055::eAxisAcc: return regOffset0(sRegsPage0.ACC_OFFSET); 152 | case DFRobot_BNO055::eAxisMag: return regOffset0(sRegsPage0.MAG_OFFSET); 153 | case DFRobot_BNO055::eAxisGyr: return regOffset0(sRegsPage0.GYR_OFFSET); 154 | default: return 0; 155 | } 156 | } 157 | 158 | // set data functions ---------------------------------------------------------------- 159 | 160 | void DFRobot_BNO055::setAxisOffset(eAxis_t eAxis, sAxisAnalog_t sOffset) 161 | { 162 | uint8_t offset = getOffsetOfOffset(eAxis); 163 | float factor = 0; 164 | uint16_t maxValue = 0; 165 | 166 | switch(eAxis) { 167 | // shift accelerometer data: 1m/s2 = 100lsb, 1mg = 1lsb 168 | case eAxisAcc: { 169 | factor = 1.0f; 170 | switch(_eAccRange) { 171 | case eAccRange_2G: maxValue = 2000; break; 172 | case eAccRange_4G: maxValue = 4000; break; 173 | case eAccRange_8G: maxValue = 8000; break; 174 | case eAccRange_16G: maxValue = 16000; break; 175 | } 176 | } break; 177 | // shift magnetometer data: 1ut = 16lsb 178 | case eAxisMag: factor = 16.0f; maxValue = 1300; break; 179 | // shift gyroscope data: 1dps = 16lsb, 1rps = 900lsb 180 | case eAxisGyr: { 181 | factor = 16.0f; 182 | switch(_eGyrRange) { 183 | case eGyrRange_2000: maxValue = 2000; break; 184 | case eGyrRange_1000: maxValue = 1000; break; 185 | case eGyrRange_500: maxValue = 500; break; 186 | case eGyrRange_250: maxValue = 250; break; 187 | case eGyrRange_125: maxValue = 125; break; 188 | } 189 | } break; 190 | default: lastOperateStatus = eStatusErrParameter; break; 191 | } 192 | if(eAxis == eAxisGyr) { 193 | if((offset == 0) || (abs(sOffset.x) > maxValue) || (abs(sOffset.y) > maxValue) || (abs(sOffset.z) > 2500)) { 194 | lastOperateStatus = eStatusErrParameter; 195 | return; 196 | } 197 | } else if((offset == 0) || (abs(sOffset.x) > maxValue) || (abs(sOffset.y) > maxValue) || (abs(sOffset.z) > maxValue)) { 198 | lastOperateStatus = eStatusErrParameter; 199 | return; 200 | } 201 | sAxisData_t sAxisData; 202 | sAxisData.x = sOffset.x * factor; 203 | sAxisData.y = sOffset.y * factor; 204 | sAxisData.z = sOffset.z * factor; 205 | setToPage(0); 206 | writeReg(offset, (uint8_t*) &sAxisData, sizeof(sAxisData)); 207 | } 208 | 209 | 210 | 211 | void DFRobot_BNO055::setAxisMapSign(eMapSign_t eSign){ 212 | sRegAxisMapSign_t sRegFlied = {0}, sRegVal = {0}; 213 | sRegFlied.remappedAxisSign = 0xff; sRegVal.remappedAxisSign = eSign; 214 | writeRegBitsHelper(0, sRegsPage0.AXIS_MAP_SIGN, sRegFlied, sRegVal); 215 | delay(10); 216 | } 217 | 218 | void DFRobot_BNO055::setAxisMapConfig(eMapConfig_t eConfig){ 219 | sRegAxisMapConfig_t sRegFlied = {0}, sRegVal = {0}; 220 | sRegFlied.remappedAxisConfig = 0xff; sRegVal.remappedAxisConfig = eConfig; 221 | writeRegBitsHelper(0, sRegsPage0.AXIS_MAP_CONFIG, sRegFlied, sRegVal); 222 | delay(10); 223 | } 224 | 225 | void DFRobot_BNO055::setOprMode(eOprMode_t eMode) 226 | { 227 | sRegOprMode_t sRegFlied = {0}, sRegVal = {0}; 228 | sRegFlied.mode = 0xff; sRegVal.mode = eMode; 229 | writeRegBitsHelper(0, sRegsPage0.OPR_MODE, sRegFlied, sRegVal); 230 | delay(50); // wait before operate mode shift done 231 | } 232 | 233 | void DFRobot_BNO055::setPowerMode(ePowerMode_t eMode) 234 | { 235 | sRegPowerMode_t sRegFlied = {0}, sRegVal = {0}; 236 | sRegFlied.mode = 0xff; sRegVal.mode = eMode; 237 | writeRegBitsHelper(0, sRegsPage0.PWR_MODE, sRegFlied, sRegVal); 238 | } 239 | 240 | void DFRobot_BNO055::reset() 241 | { 242 | sRegSysTrigger_t sRegFlied = {0}, sRegVal = {0}; 243 | sRegFlied.RST_SYS = 0xff; sRegVal.RST_SYS = 1; 244 | writeRegBitsHelper(0, sRegsPage0.SYS_TRIGGER, sRegFlied, sRegVal); 245 | } 246 | 247 | void DFRobot_BNO055::setAccRange(eAccRange_t eRange) 248 | { 249 | sRegAccConfig_t sRegFlied = {0}, sRegVal = {0}; 250 | sRegFlied.ACC_RANGE = 0xff; sRegVal.ACC_RANGE = eRange; 251 | writeRegBitsHelper(1, sRegsPage1.ACC_CONFIG, sRegFlied, sRegVal); 252 | if(lastOperateStatus == eStatusOK) 253 | _eAccRange = eRange; 254 | } 255 | 256 | void DFRobot_BNO055::setAccBandWidth(eAccBandWidth_t eBand) 257 | { 258 | sRegAccConfig_t sRegFlied = {0}, sRegVal = {0}; 259 | sRegFlied.ACC_BW = 0xff; sRegVal.ACC_BW = eBand; 260 | writeRegBitsHelper(1, sRegsPage1.ACC_CONFIG, sRegFlied, sRegVal); 261 | } 262 | 263 | void DFRobot_BNO055::setAccPowerMode(eAccPowerMode_t eMode) 264 | { 265 | sRegAccConfig_t sRegFlied = {0}, sRegVal = {0}; 266 | sRegFlied.ACC_PWR_MODE = 0xff; sRegVal.ACC_PWR_MODE = eMode; 267 | writeRegBitsHelper(1, sRegsPage1.ACC_CONFIG, sRegFlied, sRegVal); 268 | } 269 | 270 | void DFRobot_BNO055::setMagDataRate(eMagDataRate_t eRate) 271 | { 272 | sRegMagConfig_t sRegFlied = {0}, sRegVal = {0}; 273 | sRegFlied.MAG_DATA_OUTPUT_RATE = 0xff; sRegVal.MAG_DATA_OUTPUT_RATE = eRate; 274 | writeRegBitsHelper(1, sRegsPage1.MAG_CONFIG, sRegFlied, sRegVal); 275 | } 276 | 277 | void DFRobot_BNO055::setMagOprMode(eMagOprMode_t eMode) 278 | { 279 | sRegMagConfig_t sRegFlied = {0}, sRegVal = {0}; 280 | sRegFlied.MAG_OPR_MODE = 0xff; sRegVal.MAG_OPR_MODE = eMode; 281 | writeRegBitsHelper(1, sRegsPage1.MAG_CONFIG, sRegFlied, sRegVal); 282 | } 283 | 284 | void DFRobot_BNO055::setMagPowerMode(eMagPowerMode_t eMode) 285 | { 286 | sRegMagConfig_t sRegFlied = {0}, sRegVal = {0}; 287 | sRegFlied.MAG_POWER_MODE = 0xff; sRegVal.MAG_POWER_MODE = eMode; 288 | writeRegBitsHelper(1, sRegsPage1.MAG_CONFIG, sRegFlied, sRegVal); 289 | } 290 | 291 | void DFRobot_BNO055::setGyrRange(eGyrRange_t eRange) 292 | { 293 | sRegGyrConfig0_t sRegFlied = {0}, sRegVal = {0}; 294 | sRegFlied.GYR_RANGE = 0xff; sRegVal.GYR_RANGE = eRange; 295 | writeRegBitsHelper(1, sRegsPage1.GYR_CONFIG0, sRegFlied, sRegVal); 296 | if(lastOperateStatus == eStatusOK) 297 | _eGyrRange = eRange; 298 | 299 | #if __DBG 300 | readReg(regOffset1(sRegsPage1.GYR_CONFIG0), (uint8_t*) &sRegFlied, sizeof(sRegFlied)); 301 | __DBG_CODE(Serial.print("gyr range: "); Serial.print(sRegFlied.GYR_RANGE, HEX)); 302 | #endif 303 | } 304 | 305 | void DFRobot_BNO055::setGyrBandWidth(eGyrBandWidth_t eBandWidth) 306 | { 307 | sRegGyrConfig0_t sRegFlied = {0}, sRegVal = {0}; 308 | sRegFlied.GYR_BANDWIDTH = 0xff; sRegVal.GYR_BANDWIDTH = eBandWidth; 309 | writeRegBitsHelper(1, sRegsPage1.GYR_CONFIG0, sRegFlied, sRegVal); 310 | } 311 | 312 | void DFRobot_BNO055::setGyrPowerMode(eGyrPowerMode_t eMode) 313 | { 314 | sRegGyrConfig1_t sRegFlied = {0}, sRegVal = {0}; 315 | sRegFlied.GYR_POWER_MODE = 0xff; sRegVal.GYR_POWER_MODE = eMode; 316 | writeRegBitsHelper(1, sRegsPage1.GYR_CONFIG1, sRegFlied, sRegVal); 317 | } 318 | 319 | uint8_t DFRobot_BNO055::getIntState() 320 | { 321 | sRegIntSta_t sInt; 322 | sRegSysTrigger_t sTrigFlied, sTrigVal; 323 | setToPage(0); 324 | readReg(regOffset0(sRegsPage0.INT_STA), (uint8_t*) &sInt, sizeof(sInt)); 325 | __DBG_CODE(Serial.print("int state: "); Serial.print(*(uint8_t*) &sInt, HEX)); 326 | 327 | sTrigFlied.RST_INT = 0xff; sTrigVal.RST_INT = 1; 328 | writeRegBitsHelper(0, sRegsPage0.SYS_TRIGGER, sTrigFlied, sTrigVal); 329 | return *(uint8_t*) &sInt; 330 | } 331 | 332 | void DFRobot_BNO055::setIntMaskEnable(eInt_t eInt) 333 | { 334 | uint8_t temp; 335 | setToPage(1); 336 | readReg(regOffset1(sRegsPage1.INT_MASK), (uint8_t*) &temp, sizeof(temp)); 337 | temp |= eInt; 338 | writeReg(regOffset1(sRegsPage1.INT_MASK), (uint8_t*) &temp, sizeof(temp)); 339 | } 340 | 341 | void DFRobot_BNO055::setIntMaskDisable(eInt_t eInt) 342 | { 343 | uint8_t temp; 344 | setToPage(1); 345 | readReg(regOffset1(sRegsPage1.INT_MASK), (uint8_t*) &temp, sizeof(temp)); 346 | temp &= ~ eInt; 347 | writeReg(regOffset1(sRegsPage1.INT_MASK), (uint8_t*) &temp, sizeof(temp)); 348 | } 349 | 350 | void DFRobot_BNO055::setIntEnable(eInt_t eInt) 351 | { 352 | uint8_t temp; 353 | setToPage(1); 354 | readReg(regOffset1(sRegsPage1.INT_EN), (uint8_t*) &temp, sizeof(temp)); 355 | temp |= eInt; 356 | writeReg(regOffset1(sRegsPage1.INT_EN), (uint8_t*) &temp, sizeof(temp)); 357 | } 358 | 359 | void DFRobot_BNO055::setIntDisable(eInt_t eInt) 360 | { 361 | uint8_t temp; 362 | setToPage(1); 363 | readReg(regOffset1(sRegsPage1.INT_EN), (uint8_t*) &temp, sizeof(temp)); 364 | temp &= ~ eInt; 365 | writeReg(regOffset1(sRegsPage1.INT_EN), (uint8_t*) &temp, sizeof(temp)); 366 | } 367 | 368 | void DFRobot_BNO055::setAccAmThres(uint16_t thres) 369 | { 370 | uint8_t temp = mapAccThres(thres); 371 | if(lastOperateStatus != eStatusOK) 372 | return; 373 | writeReg(regOffset1(sRegsPage1.ACC_AM_THRES), (uint8_t*) &temp, sizeof(temp)); 374 | } 375 | 376 | void DFRobot_BNO055::setAccIntAmDur(uint8_t dur) 377 | { 378 | sRegAccIntSet_t sRegFleid = {0}, sRegVal = {0}; 379 | if((dur > 4) || (dur << 1)) { 380 | lastOperateStatus = eStatusErrParameter; 381 | return; 382 | } 383 | sRegFleid.AM_DUR = 0xff; sRegVal.AM_DUR = dur - 1; 384 | writeRegBitsHelper(1, sRegsPage1.ACC_INT_SETTINGS, sRegFleid, sRegVal); 385 | } 386 | 387 | void DFRobot_BNO055::setAccIntEnable(eAccIntSet_t eInt) 388 | { 389 | uint8_t temp; 390 | setToPage(1); 391 | readReg(regOffset1(sRegsPage1.ACC_INT_SETTINGS), (uint8_t*) &temp, sizeof(temp)); 392 | temp |= eInt; 393 | writeReg(regOffset1(sRegsPage1.ACC_INT_SETTINGS), (uint8_t*) &temp, sizeof(temp)); 394 | } 395 | 396 | void DFRobot_BNO055::setAccIntDisable(eAccIntSet_t eInt) 397 | { 398 | uint8_t temp; 399 | setToPage(1); 400 | readReg(regOffset1(sRegsPage1.ACC_INT_SETTINGS), (uint8_t*) &temp, sizeof(temp)); 401 | temp &= ~ eInt; 402 | writeReg(regOffset1(sRegsPage1.ACC_INT_SETTINGS), (uint8_t*) &temp, sizeof(temp)); 403 | } 404 | 405 | void DFRobot_BNO055::setAccHighGDuration(uint16_t dur) 406 | { 407 | if((dur < 2) || (dur > 512)) { 408 | lastOperateStatus = eStatusErrParameter; 409 | return; 410 | } 411 | uint8_t temp = dur / 2; 412 | setToPage(1); 413 | writeReg(regOffset1(sRegsPage1.ACC_HG_THRES), (uint8_t*) temp, sizeof(temp)); 414 | } 415 | 416 | void DFRobot_BNO055::setAccHighGThres(uint16_t thres) 417 | { 418 | uint8_t temp = mapAccThres(thres); 419 | if(lastOperateStatus != eStatusOK) 420 | return; 421 | writeReg(regOffset1(sRegsPage1.ACC_HG_THRES), (uint8_t*) &temp, sizeof(temp)); 422 | } 423 | 424 | void DFRobot_BNO055::setAccNmThres(uint16_t thres) 425 | { 426 | uint8_t temp = mapAccThres(thres); 427 | if(lastOperateStatus != eStatusOK) 428 | return; 429 | writeReg(regOffset1(sRegsPage1.ACC_NM_THRES), (uint8_t*) &temp, sizeof(temp)); 430 | } 431 | 432 | void DFRobot_BNO055::setAccNmSet(eAccNmSmnm_t eSmnm, uint16_t dur) 433 | { 434 | sRegAccNmSet_t sReg; 435 | uint8_t temp = 0; 436 | if(dur > 336) { 437 | lastOperateStatus = eStatusErrParameter; 438 | return; 439 | } 440 | sReg.SMNM = eSmnm; 441 | /* 442 | * more detail in datasheet page 85 443 | * 444 | * ACC_NM_SET 445 | * ----------------------------------------- 446 | * | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | 447 | * ----------------------------------------- 448 | * | | slo_no_mot_dur <5:0> |Smnm| 449 | * ----------------------------------------- 450 | * 451 | * slow / no motion duration = snmd (unit seconds) 452 | * if slo_no_mot_dur<5:4> == 0b00, then snmd = slo_no_mot_dur<3:0> + 1 453 | * if slo_no_mot_dur<5:4> == 0b01, then snmd = slo_no_mot_dur<3:0> * 4 + 20 454 | * if slo_no_mot_dur<5:5> == 0b1, then snmd = slo_no_mot_dur<4:0> * 8 + 88 455 | */ 456 | if(dur < 17) { 457 | temp = dur - 1; 458 | } else if(dur < 80) { 459 | temp |= (0x01 << 4); 460 | if(dur > 20) 461 | temp |= (dur - 20) / 4; 462 | } else { 463 | temp |= (0x01 << 5); 464 | if(dur > 88) 465 | temp |= (dur - 88) / 8; 466 | } 467 | sReg.NO_SLOW_MOTION_DURATION = temp; 468 | setToPage(1); 469 | writeReg(regOffset1(sRegsPage1.ACC_NM_SET), (uint8_t*) &sReg, sizeof(sReg)); 470 | } 471 | 472 | void DFRobot_BNO055::setGyrIntEnable(eGyrIntSet_t eInt) 473 | { 474 | uint8_t temp; 475 | setToPage(1); 476 | readReg(regOffset1(sRegsPage1.GYR_INT_SETTING), (uint8_t*) temp, sizeof(temp)); 477 | temp |= eInt; 478 | writeReg(regOffset1(sRegsPage1.GYR_INT_SETTING), (uint8_t*) temp, sizeof(temp)); 479 | } 480 | 481 | void DFRobot_BNO055::setGyrIntDisable(eGyrIntSet_t eInt) 482 | { 483 | uint8_t temp; 484 | setToPage(1); 485 | readReg(regOffset1(sRegsPage1.GYR_INT_SETTING), (uint8_t*) temp, sizeof(temp)); 486 | temp &= ~ eInt; 487 | writeReg(regOffset1(sRegsPage1.GYR_INT_SETTING), (uint8_t*) temp, sizeof(temp)); 488 | } 489 | 490 | void DFRobot_BNO055::setGyrHrSet(eSingleAxis_t eSingleAxis, uint16_t thres, uint16_t dur) 491 | { 492 | uint8_t hysteresis = 1; 493 | mapGyrHrThres(&hysteresis, &thres, &dur); 494 | hysteresis = 0; // function not yet understood, temporarily used 1 495 | if(lastOperateStatus != eStatusOK) 496 | return; 497 | uint8_t reg = regOffset1(sRegsPage1.GYR_HR_X_SET); // get reg offset head 498 | reg += eSingleAxis * 2; // calculate offset 499 | sRegGyrHrSet_t sReg; 500 | uint8_t temp = dur; 501 | sReg.HR_THRESHOLD = thres; 502 | sReg.HR_THRES_HYST = hysteresis; 503 | __DBG_CODE(Serial.print("thresHold: "); Serial.print(sReg.HR_THRESHOLD); Serial.print(" reg addr: "); Serial.print(reg, HEX)); 504 | writeReg(reg, (uint8_t*) &sReg, sizeof(sReg)); 505 | writeReg(reg + 1, (uint8_t*) &temp, sizeof(temp)); 506 | } 507 | 508 | void DFRobot_BNO055::setGyrAmThres(uint8_t thres) 509 | { 510 | mapGyrAmThres(&thres); 511 | if(lastOperateStatus != eStatusOK) 512 | return; 513 | setToPage(1); 514 | writeReg(regOffset1(sRegsPage1.GYR_AM_THRES), (uint8_t*) &thres, sizeof(thres)); 515 | } 516 | 517 | // protected functions ---------------------------------------------------------------- 518 | 519 | uint8_t DFRobot_BNO055::getReg(uint8_t reg, uint8_t pageId) 520 | { 521 | uint8_t temp; 522 | setToPage(pageId); 523 | readReg(reg, &temp, sizeof(temp)); 524 | return temp; 525 | } 526 | 527 | void DFRobot_BNO055::setToPage(uint8_t pageId) 528 | { 529 | if(_currentPage != pageId) { 530 | writeReg(regOffset0(sRegsPage0.PAGE_ID), &pageId, sizeof(pageId)); 531 | if(lastOperateStatus == eStatusOK) { 532 | _currentPage = pageId; 533 | } 534 | } 535 | } 536 | 537 | void DFRobot_BNO055::setUnit() 538 | { 539 | sRegUnitSel_t sReg; 540 | sReg.ACC = 1; // 0: m/s^2, 1: mg 541 | sReg.EUL = 0; // 0: degrees, 1: radians 542 | sReg.GYR = 0; // 0: dps, 1: rps 543 | sReg.ORI_ANDROID_WINDOWS = 1; // 0: windows, 1: android 544 | sReg.TEMP = 0; // 0: celsius, 1: fahrenheit 545 | setToPage(0); 546 | writeReg(regOffset0(sRegsPage0.UNIT_SEL), (uint8_t*) &sReg, sizeof(sReg)); 547 | } 548 | 549 | void DFRobot_BNO055::writeRegBits(uint8_t reg, uint8_t flied, uint8_t val) 550 | { 551 | uint8_t regVal; 552 | readReg(reg, ®Val, sizeof(regVal)); 553 | regVal &= ~flied; 554 | regVal |= val; 555 | writeReg(reg, ®Val, sizeof(regVal)); 556 | } 557 | 558 | /* 559 | * value is dependent on accelerometer range selected 560 | * -------------------------- 561 | * | range | 1lsb = ?mg | 562 | * -------------------------- 563 | * | 2g | 3.91 | 564 | * | 4g | 7.81 | 565 | * | 8g | 15.63 | 566 | * | 16g | 31.25 | 567 | * -------------------------- 568 | */ 569 | uint16_t DFRobot_BNO055::mapAccThres(uint16_t thres) 570 | { 571 | sRegAccConfig_t sReg; 572 | setToPage(1); 573 | readReg(regOffset1(sRegsPage1.ACC_CONFIG), (uint8_t*) &sReg, sizeof(sReg)); 574 | if(lastOperateStatus != eStatusOK) 575 | return 0; 576 | switch(sReg.ACC_RANGE) { 577 | case eAccRange_2G: { 578 | if(thres > (255.0f * 3.91f)) { lastOperateStatus = eStatusErrParameter; } 579 | else { thres /= 3.91f; } 580 | } break; 581 | case eAccRange_4G: { 582 | if(thres > (255.0f * 7.81f)) { lastOperateStatus = eStatusErrParameter; } 583 | else { thres /= 7.81f; } 584 | } break; 585 | case eAccRange_8G: { 586 | if(thres > (255.0f * 15.63f)) { lastOperateStatus = eStatusErrParameter; } 587 | else { thres /= 15.63f; } 588 | } break; 589 | case eAccRange_16G: { 590 | if(thres > (255.0f * 31.25f)) { lastOperateStatus = eStatusErrParameter; } 591 | else { thres /= 31.25f; } 592 | } break; 593 | default: lastOperateStatus = eStatusErrParameter; break; 594 | } 595 | if(lastOperateStatus == eStatusErrParameter) 596 | return 0; 597 | return thres; 598 | } 599 | 600 | /* 601 | * hysteresis value is dependent on gyroscope range selected 602 | * ----------------------------------------- 603 | * | range | 1lsb = ? degree / seconds | 604 | * ----------------------------------------- 605 | * | 2000 | 62.26 | 606 | * | 1000 | 31.13 | 607 | * | 500 | 15.56 | 608 | * | 250 | 7.78 | 609 | * | 125 | 3.89 | 610 | * ----------------------------------------- 611 | * 612 | * threshold value is dependent on gyroscope range selected 613 | * ----------------------------------------- 614 | * | range | 1lsb = ? degree / seconds | 615 | * ----------------------------------------- 616 | * | 2000 | 62.5 | 617 | * | 1000 | 31.25 | 618 | * | 500 | 15.625 | 619 | * | 250 | 7.8125 | 620 | * | 125 | 3.90625 | 621 | * ----------------------------------------- 622 | * 623 | * High rate duration to set, unit ms, duration from 2.5ms to 640ms 624 | */ 625 | void DFRobot_BNO055::mapGyrHrThres(uint8_t *pHysteresis, uint16_t *pThres, uint16_t *pDur) 626 | { 627 | sRegGyrConfig0_t sReg; 628 | setToPage(1); 629 | readReg(regOffset1(sRegsPage1.GYR_CONFIG0), (uint8_t*) &sReg, sizeof(sReg)); 630 | if(lastOperateStatus != eStatusOK) 631 | return; 632 | if((*pDur < 3) || (*pDur > 640)) { 633 | lastOperateStatus = eStatusErrParameter; 634 | return; 635 | } 636 | switch(sReg.GYR_RANGE) { 637 | case eGyrRange_2000: { 638 | if((*pHysteresis > (62.26f * 3.0f)) || (*pThres > (62.5f * 31.0f))) 639 | lastOperateStatus = eStatusErrParameter; 640 | else { 641 | *pHysteresis /= 62.26f; 642 | *pThres /= 62.5f; 643 | } 644 | } break; 645 | case eGyrRange_1000: { 646 | if((*pHysteresis > (31.13f * 3.0f)) || (*pThres > (31.25f * 31.0f))) 647 | lastOperateStatus = eStatusErrParameter; 648 | else { 649 | *pHysteresis /= 31.13f; 650 | *pThres /= 31.25f; 651 | } 652 | } break; 653 | case eGyrRange_500: { 654 | if((*pHysteresis > (15.56f * 3.0f)) || (*pThres > (15.625f * 31.0f))) 655 | lastOperateStatus = eStatusErrParameter; 656 | else { 657 | *pHysteresis /= 15.56f; 658 | *pThres /= 3.0f; 659 | } 660 | } break; 661 | case eGyrRange_250: { 662 | if((*pHysteresis > (7.78f * 3.0f)) || (*pThres > (7.8125f * 31.0f))) 663 | lastOperateStatus = eStatusErrParameter; 664 | else { 665 | *pHysteresis /= 7.78f; 666 | *pThres /= 7.8125f; 667 | } 668 | } break; 669 | case eGyrRange_125: { 670 | if((*pHysteresis > (3.89f * 3.0f)) || (*pThres > (3.90625f * 31.0f))) 671 | lastOperateStatus = eStatusErrParameter; 672 | else { 673 | *pHysteresis /= 3.89f; 674 | *pThres /= 3.0f; 675 | } 676 | } break; 677 | default: lastOperateStatus = eStatusErrParameter; break; 678 | } 679 | if(lastOperateStatus != eStatusErrParameter) 680 | *pDur /= 2.5f; 681 | } 682 | 683 | /* 684 | * threshold value is dependent on gyroscope range selected 685 | * ----------------------------------------- 686 | * | range | 1lsb = ? degree / seconds | 687 | * ----------------------------------------- 688 | * | 2000 | 1 | 689 | * | 1000 | 0.5 | 690 | * | 500 | 0.25 | 691 | * | 250 | 0.125 | 692 | * | 125 | 0.0625 | 693 | * ----------------------------------------- 694 | */ 695 | void DFRobot_BNO055::mapGyrAmThres(uint8_t *pThres) 696 | { 697 | sRegGyrConfig0_t sReg; 698 | setToPage(1); 699 | readReg(regOffset1(sRegsPage1.GYR_CONFIG0), (uint8_t*) &sReg, sizeof(sReg)); 700 | if(lastOperateStatus != eStatusOK) 701 | return; 702 | switch(sReg.GYR_RANGE) { 703 | case eGyrRange_2000: if(*pThres < (128.0f * 1.0f)) { *pThres /= 1.0f; } break; 704 | case eGyrRange_1000: if(*pThres < (128.0f * 0.5f)) { *pThres /= 0.5f; } break; 705 | case eGyrRange_500: if(*pThres < (128.0f * 0.25f)) { *pThres /= 0.25f; } break; 706 | case eGyrRange_250: if(*pThres < (128.0f * 0.125f)) { *pThres /= 0.125f; } break; 707 | case eGyrRange_125: if(*pThres < (128.0f * 0.0625f)) { *pThres /= 0.625f; } break; 708 | } 709 | } 710 | 711 | DFRobot_BNO055::sAxisData_t DFRobot_BNO055::getAxisRaw(eAxis_t eAxis) 712 | { 713 | uint8_t offset = getOffsetOfData(eAxis); 714 | sAxisData_t sAxis = {0}; 715 | setToPage(0); 716 | if(offset == 0) 717 | lastOperateStatus = eStatusErrParameter; 718 | else 719 | readReg(offset, (uint8_t*) &sAxis, sizeof(sAxis)); 720 | return sAxis; 721 | } 722 | 723 | DFRobot_BNO055::sEulData_t DFRobot_BNO055::getEulRaw() 724 | { 725 | sEulData_t sEul = {0}; 726 | setToPage(0); 727 | readReg(regOffset0(sRegsPage0.EUL_DATA), (uint8_t*) &sEul, sizeof(sEul)); 728 | return sEul; 729 | } 730 | 731 | DFRobot_BNO055::sQuaData_t DFRobot_BNO055::getQuaRaw() 732 | { 733 | sQuaData_t sQua; 734 | setToPage(0); 735 | readReg(regOffset0(sRegsPage0.QUA_DATA), (uint8_t*) &sQua, sizeof(sQua)); 736 | return sQua; 737 | } 738 | 739 | // main class end ---------------------------------------------------------------- 740 | 741 | // utils class start ---------------------------------------------------------------- 742 | 743 | DFRobot_BNO055_IIC::DFRobot_BNO055_IIC(TwoWire *pWire, uint8_t addr) 744 | { 745 | _pWire = pWire; 746 | _addr = addr; 747 | } 748 | 749 | void DFRobot_BNO055_IIC::readReg(uint8_t reg, uint8_t *pBuf, uint8_t len) 750 | { 751 | lastOperateStatus = eStatusErrDeviceNotDetect; 752 | _pWire->begin(); 753 | _pWire->beginTransmission(_addr); 754 | _pWire->write(reg); 755 | if(_pWire->endTransmission() != 0) 756 | return; 757 | 758 | _pWire->requestFrom(_addr, len); 759 | for(uint8_t i = 0; i < len; i ++) 760 | pBuf[i] = _pWire->read(); 761 | lastOperateStatus = eStatusOK; 762 | } 763 | 764 | void DFRobot_BNO055_IIC::writeReg(uint8_t reg, uint8_t *pBuf, uint8_t len) 765 | { 766 | lastOperateStatus = eStatusErrDeviceNotDetect; 767 | _pWire->begin(); 768 | _pWire->beginTransmission(_addr); 769 | _pWire->write(reg); 770 | for(uint8_t i = 0; i < len; i ++) 771 | _pWire->write(pBuf[i]); 772 | if(_pWire->endTransmission() != 0) 773 | return; 774 | lastOperateStatus = eStatusOK; 775 | } 776 | 777 | // utils class end ---------------------------------------------------------------- 778 | -------------------------------------------------------------------------------- /DFRobot_BNO055.h: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (C) <2019> <@DFRobot Frank> 5 | 6 | ��Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | ��software and associated documentation files (the "Software"), to deal in the Software 8 | ��without restriction, including without limitation the rights to use, copy, modify, 9 | ��merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | ��permit persons to whom the Software is furnished to do so. 11 | 12 | ��The above copyright notice and this permission notice shall be included in all copies or 13 | ��substantial portions of the Software. 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 16 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | */ 20 | 21 | #ifndef DFROBOT_BNO055_H 22 | #define DFROBOT_BNO055_H 23 | 24 | #include "Arduino.h" 25 | #include "Wire.h" 26 | 27 | #ifndef PROGMEM 28 | #define PROGMEM 29 | #endif 30 | 31 | // main class ---------------------------------------------------------------- 32 | class DFRobot_BNO055 { 33 | 34 | // defines 35 | public: 36 | /** 37 | * @brief global axis declare (excepet eular and quaternion) 38 | */ 39 | typedef enum { 40 | eAxisAcc, 41 | eAxisMag, 42 | eAxisGyr, 43 | eAxisLia, 44 | eAxisGrv 45 | } eAxis_t; 46 | 47 | /** 48 | * @brief global single axis declare 49 | */ 50 | typedef enum { 51 | eSingleAxisX, 52 | eSingleAxisY, 53 | eSingleAxisZ 54 | } eSingleAxis_t; 55 | 56 | // registers ---------------------------------------------------------------- 57 | typedef struct { 58 | uint8_t MAG: 2; 59 | uint8_t ACC: 2; 60 | uint8_t GYR: 2; 61 | uint8_t SYS: 2; 62 | } sRegCalibState_t; 63 | 64 | typedef enum { 65 | eStResultFaild, 66 | eStResultPassed 67 | } eStResult_t; 68 | 69 | typedef struct { 70 | uint8_t ACC: 1; 71 | uint8_t MAG: 1; 72 | uint8_t GYR: 1; 73 | uint8_t MCU: 1; 74 | } sRegStResult_t; 75 | 76 | /** 77 | * @brief enum interrupt 78 | */ 79 | typedef enum { 80 | eIntGyrAm = 0x04, 81 | eIntGyrHighRate = 0x08, 82 | eIntAccHighG = 0x20, 83 | eIntAccAm = 0x40, 84 | eIntAccNm = 0x80, 85 | eIntAll = 0xec 86 | } eInt_t; 87 | 88 | typedef struct { 89 | uint8_t reserved1: 2; 90 | uint8_t GYRO_AM: 1; 91 | uint8_t HYR_HIGH_RATE: 1; 92 | uint8_t reserved2: 1; 93 | uint8_t ACC_HIGH_G: 1; 94 | uint8_t ACC_AM: 1; 95 | uint8_t ACC_NM: 1; 96 | } sRegIntSta_t; 97 | 98 | typedef struct { 99 | uint8_t ST_MAIN_CLK: 1; 100 | } sRegSysClkStatus_t; 101 | 102 | typedef struct { 103 | uint8_t ACC: 1; 104 | uint8_t GYR: 1; 105 | uint8_t EUL: 1; 106 | uint8_t reserved1: 1; 107 | uint8_t TEMP: 1; 108 | uint8_t reserved2: 2; 109 | uint8_t ORI_ANDROID_WINDOWS: 1; 110 | } sRegUnitSel_t; 111 | 112 | /** 113 | * @brief Operation mode enum 114 | */ 115 | typedef enum { 116 | eOprModeConfig, 117 | eOprModeAccOnly, 118 | eOprModeMagOnly, 119 | eOprModeGyroOnly, 120 | eOprModeAccMag, 121 | eOprModeAccGyro, 122 | eOprModeMagGyro, 123 | eOprModeAMG, 124 | eOprModeImu, 125 | eOprModeCompass, 126 | eOprModeM4G, 127 | eOprModeNdofFmcOff, 128 | eOprModeNdof 129 | } eOprMode_t; 130 | 131 | typedef struct { 132 | uint8_t mode: 4; 133 | } sRegOprMode_t; 134 | 135 | /** 136 | * @brief Poewr mode enum 137 | */ 138 | typedef enum { 139 | ePowerModeNormal, 140 | ePowerModeLowPower, 141 | ePowerModeSuspend 142 | } ePowerMode_t; 143 | 144 | typedef struct { 145 | uint8_t mode: 2; 146 | } sRegPowerMode_t; 147 | 148 | typedef struct { 149 | uint8_t SELF_TEST: 1; 150 | uint8_t reserved1: 4; 151 | uint8_t RST_SYS: 1; 152 | uint8_t RST_INT: 1; 153 | uint8_t CLK_SEL: 1; 154 | } sRegSysTrigger_t; 155 | 156 | typedef struct { 157 | uint8_t TEMP_SOURCE: 2; 158 | } sRegTempSource_t; 159 | 160 | typedef struct { 161 | //uint8_t remappedXAxisVal: 2; 162 | //uint8_t remappedYAxisVal: 2; 163 | //uint8_t remappedZAxisVal: 2; 164 | uint8_t remappedAxisConfig: 6; 165 | } sRegAxisMapConfig_t; 166 | 167 | typedef struct { 168 | //uint8_t remappedZAxisSign: 1; 169 | //uint8_t remappedYAxisSign: 1; 170 | //uint8_t remappedXAxisSign: 1; 171 | uint8_t remappedAxisSign: 3; 172 | } sRegAxisMapSign_t; 173 | 174 | typedef struct { 175 | int16_t x, y, z; 176 | } sAxisData_t; 177 | 178 | /** 179 | * @brief axis analog data struct 180 | */ 181 | typedef struct { 182 | float x, y, z; 183 | } sAxisAnalog_t; 184 | 185 | /** 186 | * @brief eular analog data struct 187 | */ 188 | typedef struct { 189 | float head, roll, pitch; 190 | } sEulAnalog_t; 191 | 192 | typedef struct { 193 | int16_t head, roll, pitch; 194 | } sEulData_t; 195 | 196 | /** 197 | * @brief qua analog data struct 198 | */ 199 | typedef struct { 200 | float w, x, y, z; 201 | } sQuaAnalog_t; 202 | 203 | typedef struct { 204 | int16_t w, x, y, z; 205 | } sQuaData_t; 206 | 207 | typedef struct { 208 | uint8_t CHIP_ID; // 0x00 209 | #define BNO055_REG_CHIP_ID_DEFAULT 0xa0 210 | uint8_t ACC_ID; 211 | #define BNO055_REG_ACC_ID_DEFAULT 0xfb 212 | uint8_t MAG_ID; 213 | #define BNO055_REG_MAG_ID_DEFAULT 0x32 214 | uint8_t GYR_ID; 215 | #define BNO055_REG_GYR_ID_DEFAULT 0x0f 216 | uint16_t SW_REV_ID; 217 | #define BNO055_REG_SW_REV_ID_DEFAULT 0x0308 218 | uint8_t BL_REV; 219 | uint8_t PAGE_ID; 220 | sAxisData_t ACC_DATA; 221 | sAxisData_t MAG_DATA; // 0x0f 222 | sAxisData_t GYR_DATA; 223 | sEulData_t EUL_DATA; 224 | sQuaData_t QUA_DATA; // 0x20 225 | sAxisData_t LIA_DATA; 226 | sAxisData_t GRV_DATA; // 0x2f 227 | uint8_t TEMP; 228 | sRegCalibState_t CALIB_STATE; 229 | sRegStResult_t ST_RESULT; 230 | sRegIntSta_t INT_STA; 231 | sRegSysClkStatus_t SYS_CLK_STATUS; 232 | uint8_t SYS_STATUS; 233 | uint8_t SYS_ERR; 234 | sRegUnitSel_t UNIT_SEL; 235 | uint8_t reserved1; 236 | sRegOprMode_t OPR_MODE; 237 | sRegPowerMode_t PWR_MODE; 238 | sRegSysTrigger_t SYS_TRIGGER; 239 | sRegTempSource_t TEMP_SOURCE; // 0x40 240 | sRegAxisMapConfig_t AXIS_MAP_CONFIG; 241 | sRegAxisMapSign_t AXIS_MAP_SIGN; 242 | uint8_t reserved2[(0x54 - 0x43 + 1)]; 243 | sAxisData_t ACC_OFFSET; // 0x55 244 | sAxisData_t MAG_OFFSET; 245 | sAxisData_t GYR_OFFSET; // 0x61 246 | uint16_t ACC_RADIUS; 247 | uint16_t MAG_RADIUS; 248 | } sRegsPage0_t; 249 | 250 | 251 | typedef enum { 252 | eMapSign_P1, 253 | eMapSign_P5, 254 | eMapSign_P3, 255 | eMapSign_P4, 256 | eMapSign_P0, 257 | eMapSign_P7, 258 | eMapSign_P2, 259 | eMapSign_P6, 260 | } eMapSign_t; 261 | 262 | typedef enum { 263 | eMapConfig_P0 = 0x21, 264 | eMapConfig_P1 = 0x24, 265 | eMapConfig_P2 = 0x24, 266 | eMapConfig_P3 = 0x21, 267 | eMapConfig_P4 = 0x24, 268 | eMapConfig_P5 = 0x21, 269 | eMapConfig_P6 = 0x21, 270 | eMapConfig_P7 = 0x24, 271 | } eMapConfig_t; 272 | 273 | /** 274 | * @brief enum accelerometer range, unit G 275 | */ 276 | typedef enum { 277 | eAccRange_2G, 278 | eAccRange_4G, 279 | eAccRange_8G, 280 | eAccRange_16G 281 | } eAccRange_t; 282 | 283 | /** 284 | * @brief enum accelerometer band width, unit HZ 285 | */ 286 | typedef enum { 287 | eAccBandWidth_7_81, // 7.81HZ 288 | eAccBandWidth_15_63, // 16.63HZ 289 | eAccBandWidth_31_25, 290 | eAccBandWidth_62_5, 291 | eAccBandWidth_125, 292 | eAccBandWidth_250, 293 | eAccBandWidth_500, 294 | eAccBandWidth_1000 295 | } eAccBandWidth_t; 296 | 297 | /** 298 | * @brief enum accelerometer power mode 299 | */ 300 | typedef enum { 301 | eAccPowerModeNormal, 302 | eAccPowerModeSuspend, 303 | eAccPowerModeLowPower1, 304 | eAccPowerModeStandby, 305 | eAccPowerModeLowPower2, 306 | eAccPowerModeDeepSuspend 307 | } eAccPowerMode_t; 308 | 309 | typedef struct { 310 | uint8_t ACC_RANGE: 2; 311 | uint8_t ACC_BW: 3; 312 | uint8_t ACC_PWR_MODE: 3; 313 | } sRegAccConfig_t; 314 | 315 | /** 316 | * @brief enum magnetometer data output rate, unit HZ 317 | */ 318 | typedef enum { 319 | eMagDataRate_2, 320 | eMagDataRate_6, 321 | eMagDataRate_8, 322 | eMagDataRate_10, 323 | eMagDataRate_15, 324 | eMagDataRate_20, 325 | eMagDataRate_25, 326 | eMagDataRate_30 327 | } eMagDataRate_t; 328 | 329 | /** 330 | * @brief enum magnetometer operation mode 331 | */ 332 | typedef enum { 333 | eMagOprModeLowPower, 334 | eMagOprModeRegular, 335 | eMagOprModeEnhancedRegular, 336 | eMagOprModeHighAccuracy 337 | } eMagOprMode_t; 338 | 339 | /** 340 | * @brief enum magnetometer power mode 341 | */ 342 | typedef enum { 343 | eMagPowerModeNormal, 344 | eMagPowerModeSleep, 345 | eMagPowerModeSuspend, 346 | eMagPowerModeForce 347 | } eMagPowerMode_t; 348 | 349 | typedef struct { 350 | uint8_t MAG_DATA_OUTPUT_RATE: 3; 351 | uint8_t MAG_OPR_MODE: 2; 352 | uint8_t MAG_POWER_MODE: 2; 353 | } sRegMagConfig_t; 354 | 355 | /** 356 | * @brief enum gyroscope range, unit dps 357 | */ 358 | typedef enum { 359 | eGyrRange_2000, 360 | eGyrRange_1000, 361 | eGyrRange_500, 362 | eGyrRange_250, 363 | eGyrRange_125 364 | } eGyrRange_t; 365 | 366 | /** 367 | * @brief enum gyroscope band width, unit HZ 368 | */ 369 | typedef enum { 370 | eGyrBandWidth_523, 371 | eGyrBandWidth_230, 372 | eGyrBandWidth_116, 373 | eGyrBandWidth_47, 374 | eGyrBandWidth_23, 375 | eGyrBandWidth_12, 376 | eGyrBandWidth_64, 377 | eGyrBandWidth_32 378 | } eGyrBandWidth_t; 379 | 380 | typedef struct { 381 | uint8_t GYR_RANGE: 3; 382 | uint8_t GYR_BANDWIDTH: 3; 383 | } sRegGyrConfig0_t; 384 | 385 | /** 386 | * @brief enum gyroscope power mode 387 | */ 388 | typedef enum { 389 | eGyrPowerModeNormal, 390 | eGyrPowerModeFastPowerUp, 391 | eGyrPowerModeDeepSuspend, 392 | eGyrPowerModeSuspend, 393 | eGyrPowerModeAdvancedPowersave 394 | } eGyrPowerMode_t; 395 | 396 | typedef struct { 397 | uint8_t GYR_POWER_MODE: 3; 398 | } sRegGyrConfig1_t; 399 | 400 | typedef enum { 401 | eAccSleepModeEventDriven, 402 | eAccSleepModeEquidstantSampling 403 | } eAccSleepMode_t; 404 | 405 | typedef enum { 406 | eAccSleepDuration_0_5 = 5, // 0.5 ms 407 | eAccSleepDuration_1, 408 | eAccSleepDuration_2, 409 | eAccSleepDuration_4, 410 | eAccSleepDuration_6, 411 | eAccSleepDuration_10, 412 | eAccSleepDuration_25, 413 | eAccSleepDuration_50, 414 | eAccSleepDuration_100, 415 | eAccSleepDuration_500, 416 | eAccSleepDuration_1000 417 | } eAccSleepDuration_t; 418 | 419 | typedef struct { 420 | uint8_t SLP_MODE: 1; 421 | uint8_t SLP_DURATION: 4; 422 | } sRegAccSleepConfig_t; 423 | 424 | typedef enum { 425 | eGyrSleepDuration_2, 426 | eGyrSleepDuration_4, 427 | eGyrSleepDuration_5, 428 | eGyrSleepDuration_8, 429 | eGyrSleepDuration_10, 430 | eGyrSleepDuration_15, 431 | eGyrSleepDuration_18, 432 | eGyrSleepDuration_20 433 | } eGyrSleepDuration_t; 434 | 435 | typedef enum { 436 | eGyrAutoSleepDuration_No, 437 | eGyrAutoSleepDuration_4, 438 | eGyrAutoSleepDuration_5, 439 | eGyrAutoSleepDuration_8, 440 | eGyrAutoSleepDuration_10, 441 | eGyrAutoSleepDuration_15, 442 | eGyrAutoSleepDuration_20, 443 | eGyrAutoSleepDuration_40 444 | } eGyrAutoSleepDuration_t; 445 | 446 | typedef struct { 447 | uint8_t SLP_DURATION: 3; 448 | uint8_t AUTO_SLP_DURATION: 3; 449 | } sRegGyrSleepConfig_t; 450 | 451 | typedef struct { 452 | uint8_t reserved1: 2; 453 | uint8_t GYRO_AM: 1; 454 | uint8_t GYR_HIGH_RATE: 1; 455 | uint8_t reserved2: 1; 456 | uint8_t ACC_HIGH_G: 1; 457 | uint8_t ACC_AM: 1; 458 | uint8_t ACC_NM: 1; 459 | } sRegIntMask_t; 460 | 461 | typedef struct { 462 | uint8_t reserved1: 2; 463 | uint8_t GYRO_AM: 1; 464 | uint8_t GYR_HIGH_RATE: 1; 465 | uint8_t reserved2: 1; 466 | uint8_t ACC_HIGH_G: 1; 467 | uint8_t ACC_AM: 1; 468 | uint8_t ACC_NM: 1; 469 | } sRegIntEn_t; 470 | 471 | /** 472 | * @brief Enum accelerometer interrupt settings 473 | */ 474 | typedef enum { 475 | eAccIntSetAmnmXAxis = (0x01 << 2), 476 | eAccIntSetAmnmYAxis = (0x01 << 3), 477 | eAccIntSetAmnmZAxis = (0x01 << 4), 478 | eAccIntSetHgXAxis = (0x01 << 5), 479 | eAccIntSetHgYAxis = (0x01 << 6), 480 | eAccIntSetHgZAxis = (0x01 << 7), 481 | eAccIntSetAll = 0xfc 482 | } eAccIntSet_t; 483 | 484 | typedef struct { 485 | uint8_t AM_DUR: 2; 486 | uint8_t AMNM_X_AXIS: 1; 487 | uint8_t AMNM_Y_AXIS: 1; 488 | uint8_t AMNM_Z_AXIS: 1; 489 | uint8_t HG_X_AXIS: 1; 490 | uint8_t HG_Y_AXIS: 1; 491 | uint8_t HG_Z_AXIS: 1; 492 | } sRegAccIntSet_t; 493 | 494 | /** 495 | * @brief Enum accelerometer slow motion mode or no motion mode 496 | */ 497 | typedef enum { 498 | eAccNmSmnmSm, // slow motion mode 499 | eAccNmSmnmNm // no motion mode 500 | } eAccNmSmnm_t; 501 | 502 | typedef struct { 503 | uint8_t SMNM: 2; 504 | uint8_t NO_SLOW_MOTION_DURATION: 5; 505 | } sRegAccNmSet_t; 506 | 507 | /** 508 | * @brief Enum gyroscope interrupt settings 509 | */ 510 | typedef enum { 511 | eGyrIntSetAmXAxis = (0x01 << 0), 512 | eGyrIntSetAmYAxis = (0x01 << 1), 513 | eGyrIntSetAmZAxis = (0x01 << 2), 514 | eGyrIntSetHrXAxis = (0x01 << 3), 515 | eGyrIntSetHrYAxis = (0x01 << 4), 516 | eGyrIntSetHrZAxis = (0x01 << 5), 517 | eGyrIntSetAmFilt = (0x01 << 6), 518 | eGyrIntSetHrFilt = (0x01 << 7), 519 | eGyrIntSetAll = 0x3f 520 | } eGyrIntSet_t; 521 | 522 | typedef struct { 523 | uint8_t AM_X_AXIS: 1; 524 | uint8_t AM_Y_AXIS: 1; 525 | uint8_t AM_Z_AXIS: 1; 526 | uint8_t HR_X_AXIS: 1; 527 | uint8_t HR_Y_AXIS: 1; 528 | uint8_t HR_Z_AXIS: 1; 529 | uint8_t AM_FILT: 1; 530 | uint8_t HR_FILT: 1; 531 | } sRegGyrIntSetting_t; 532 | 533 | typedef struct { 534 | uint8_t HR_THRESHOLD: 5; 535 | uint8_t HR_THRES_HYST: 2; 536 | } sRegGyrHrSet_t; 537 | 538 | typedef struct { 539 | uint8_t GYRO_ANY_MOTION_THRESHOLD: 7; 540 | } sRegGyrAmThres_t; 541 | 542 | typedef struct { 543 | uint8_t SLOPE_SAMPLES: 2; 544 | uint8_t AWAKE_DURATION: 2; 545 | } sRegGyrAmSet_t; 546 | 547 | typedef uint8_t UniqueId_t[(0x5f - 0x50 + 1)]; 548 | 549 | typedef struct { 550 | uint8_t reserved1[(0x06 - 0x00 + 1)]; 551 | uint8_t PAGE_ID; // 0x07 552 | sRegAccConfig_t ACC_CONFIG; 553 | sRegMagConfig_t MAG_CONFIG; 554 | sRegGyrConfig0_t GYR_CONFIG0; 555 | sRegGyrConfig1_t GYR_CONFIG1; 556 | sRegAccSleepConfig_t ACC_SLEEP; 557 | sRegGyrSleepConfig_t GYR_SLEEP; 558 | uint8_t reserved2; 559 | sRegIntMask_t INT_MASK; 560 | sRegIntEn_t INT_EN; // 0x10 561 | uint8_t ACC_AM_THRES; 562 | sRegAccIntSet_t ACC_INT_SETTINGS; 563 | uint8_t ACC_HG_DURATION; 564 | uint8_t ACC_HG_THRES; 565 | uint8_t ACC_NM_THRES; 566 | sRegAccNmSet_t ACC_NM_SET; 567 | sRegGyrIntSetting_t GYR_INT_SETTING; 568 | sRegGyrHrSet_t GYR_HR_X_SET; 569 | uint8_t GYR_DUR_X; 570 | sRegGyrHrSet_t GYR_HR_Y_SET; 571 | uint8_t GYR_DUR_Y; 572 | sRegGyrHrSet_t GYR_HR_Z_SET; 573 | uint8_t GYR_DUR_Z; 574 | sRegGyrAmThres_t GYR_AM_THRES; 575 | sRegGyrAmSet_t GYR_AM_SET; // 0x1f 576 | uint8_t reserved3[(0x4f - 0x20 + 1)]; 577 | UniqueId_t UNIQUE_ID; // 0x5f 578 | } sRegsPage1_t; 579 | 580 | /** 581 | * @brief Declare sensor status 582 | */ 583 | typedef enum { 584 | eStatusOK, // everything OK 585 | eStatusErr, // unknow error 586 | eStatusErrDeviceNotDetect, // device not detected 587 | eStatusErrDeviceReadyTimeOut, // device ready time out 588 | eStatusErrDeviceStatus, // device internal status error 589 | eStatusErrParameter // function parameter error 590 | } eStatus_t; 591 | 592 | 593 | 594 | /** Remap Signs **/ 595 | typedef enum { 596 | REMAP_SIGN_P0 = 0x04, 597 | REMAP_SIGN_P1 = 0x00, // default 598 | REMAP_SIGN_P2 = 0x06, 599 | REMAP_SIGN_P3 = 0x02, 600 | REMAP_SIGN_P4 = 0x03, 601 | REMAP_SIGN_P5 = 0x01, 602 | REMAP_SIGN_P6 = 0x07, 603 | REMAP_SIGN_P7 = 0x05 604 | } eRemap_sign_t; 605 | // functions 606 | public: 607 | 608 | DFRobot_BNO055(); 609 | 610 | /** 611 | * @brief begin Sensor begin 612 | * @return Sensor status 613 | */ 614 | eStatus_t begin(); 615 | 616 | /** 617 | * @brief getAxisAnalog Get axis analog data 618 | * @param eAxis One axis type from eAxis_t 619 | * @return Struct sAxisAnalog_t, contains axis analog data, members unit depend on eAxis: 620 | * case eAxisAcc, unit mg 621 | * case eAxisLia, unit mg 622 | * case eAxisGrv, unit mg 623 | * case eAxisMag, unit ut 624 | * case eAxisGyr, unit dps 625 | */ 626 | sAxisAnalog_t getAxis(eAxis_t eAxis); 627 | 628 | /** 629 | * @brief getEulAnalog Get euler analog data 630 | * @return Struct sEulAnalog_t, contains euler analog data 631 | */ 632 | sEulAnalog_t getEul(); 633 | 634 | /** 635 | * @brief getQuaAnalog Get quaternion analog data 636 | * @return Struct sQuaAnalog_t, contains quaternion analog data 637 | */ 638 | sQuaAnalog_t getQua(); 639 | 640 | 641 | 642 | void setAxisMapSign(eMapSign_t eSign); 643 | 644 | void setAxisMapConfig(eMapConfig_t eConfig); 645 | 646 | /** 647 | * @brief setAccOffset Set axis offset data 648 | * @param eAxis One axis type from eAxis_t, only support accelerometer, magnetometer and gyroscope 649 | * @param sOffset Struct sAxisAnalog_t, contains axis analog data, members unit depend on eAxis: 650 | * case eAxisAcc, unit mg, members can't out of acc range 651 | * case eAxisMag, unit ut, members can't out of mag range 652 | * case eAxisGyr, unit dps, members can't out of gyr range 653 | */ 654 | void setAxisOffset(eAxis_t eAxis, sAxisAnalog_t sOffset); 655 | 656 | /** 657 | * @brief setOprMode Set operation mode 658 | * @param eOpr One operation mode from eOprMode_t 659 | */ 660 | void setOprMode(eOprMode_t eMode); 661 | 662 | /** 663 | * @brief setPowerMode Set power mode 664 | * @param eMode One power mode from ePowerMode_t 665 | */ 666 | void setPowerMode(ePowerMode_t eMode); 667 | 668 | /** 669 | * @brief Reset sensor 670 | */ 671 | void reset(); 672 | 673 | /** 674 | * @brief setAccRange Set accelerometer measurement range, default value is 4g 675 | * @param eRange One range enum from eAccRange_t 676 | */ 677 | void setAccRange(eAccRange_t eRange); 678 | 679 | /** 680 | * @brief setAccBandWidth Set accelerometer band width, default value is 62.5hz 681 | * @param eBand One band enum from eAccBandWidth_t 682 | */ 683 | void setAccBandWidth(eAccBandWidth_t eBand); 684 | 685 | /** 686 | * @brief setAccPowerMode Set accelerometer power mode, default value is eAccPowerModeNormal 687 | * @param eMode One mode enum from eAccPowerMode_t 688 | */ 689 | void setAccPowerMode(eAccPowerMode_t eMode); 690 | 691 | /** 692 | * @brief setMagDataRate Set magnetometer data output rate, default value is 20hz 693 | * @param eRate One rate enum from eMagDataRate_t 694 | */ 695 | void setMagDataRate(eMagDataRate_t eRate); 696 | 697 | /** 698 | * @brief setMagOprMode Set magnetometer operation mode, default value is eMagOprModeRegular 699 | * @param eMode One mode enum from eMagOprMode_t 700 | */ 701 | void setMagOprMode(eMagOprMode_t eMode); 702 | 703 | /** 704 | * @brief setMagPowerMode Set magnetometer power mode, default value is eMagePowerModeForce 705 | * @param eMode One mode enum from eMagPowerMode_t 706 | */ 707 | void setMagPowerMode(eMagPowerMode_t eMode); 708 | 709 | /** 710 | * @brief setGyrRange Set gyroscope range, default value is 2000 711 | * @param eRange One range enum from eGyrRange_t 712 | */ 713 | void setGyrRange(eGyrRange_t eRange); 714 | 715 | /** 716 | * @brief setGyrBandWidth Set gyroscope band width, default value is 32HZ 717 | * @param eBandWidth One band width enum from eGyrBandWidth_t 718 | */ 719 | void setGyrBandWidth(eGyrBandWidth_t eBandWidth); 720 | 721 | /** 722 | * @brief setGyrPowerMode Set gyroscope power mode, default value is eGyrPowerModeNormal 723 | * @param eMode One power mode enum from eGyrPowerMode_t 724 | */ 725 | void setGyrPowerMode(eGyrPowerMode_t eMode); 726 | 727 | /** 728 | * @brief getIntState Get interrupt state, interrupt auto clear after read 729 | * @return If result > 0, at least one interrupt triggered. Result & eIntXXX (from eInt_t) to test is triggered 730 | */ 731 | uint8_t getIntState(); 732 | 733 | /** 734 | * @brief setIntMask Set interrupt mask enable, there will generate a interrupt signal (raising) on INT pin if corresponding interrupt enabled 735 | * @param eInt One or more interrupt flags to set, input them through operate or 736 | */ 737 | void setIntMaskEnable(eInt_t eInt); 738 | 739 | /** 740 | * @brief setIntMaskDisable Set corresponding interrupt mask disable 741 | * @param eInt One or more interrupt flags to set, input them through operate or 742 | */ 743 | void setIntMaskDisable(eInt_t eInt); 744 | 745 | /** 746 | * @brief setIntEnEnable Set corresponding interrupt enable 747 | * @param eInt One or more interrupt flags to set, input them through operate or 748 | */ 749 | void setIntEnable(eInt_t eInt); 750 | 751 | /** 752 | * @brief setIntEnDisable Set corresponding interrupt disable 753 | * @param eInt One or more interrupt flags to set, input them through operate or 754 | */ 755 | void setIntDisable(eInt_t eInt); 756 | 757 | /** 758 | * @brief setAccAmThres Set accelerometer any motion threshold 759 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 760 | * case 2g, no more than 1991 761 | * case 4g, no more than 3985 762 | * case 8g, no more than 7968 763 | * case 16g, no more than 15937 764 | * Attenion: The set value will be slightly biased according to datasheet 765 | */ 766 | void setAccAmThres(uint16_t thres); 767 | 768 | /** 769 | * @brief setAccIntDur Set accelerometer interrupt duration, 770 | * any motion interrupt triggers if duration (dur + 1) consecutive data points are above the any motion interrupt 771 | * threshold define in any motion threshold 772 | * @param dur Duration to set, range form 1 to 4 773 | */ 774 | void setAccIntAmDur(uint8_t dur); 775 | 776 | /** 777 | * @brief setAccIntEnable Set accelerometer interrupt enable 778 | * @param eInt One or more interrupt flags to set, input them through operate or 779 | */ 780 | void setAccIntEnable(eAccIntSet_t eInt); 781 | 782 | /** 783 | * @brief setAccIntDisable Set accelerometer interrupt disable 784 | * @param eInt One or more interrupt flags to set, input them through operate or 785 | */ 786 | void setAccIntDisable(eAccIntSet_t eInt); 787 | 788 | /** 789 | * @brief setAccHighGDuration Set accelerometer high-g interrupt, the high-g interrupt delay according to [dur + 1] * 2 ms 790 | * @param dur Duration from 2ms to 512ms 791 | */ 792 | void setAccHighGDuration(uint16_t dur); 793 | 794 | /** 795 | * @brief setAccHighGThres Set accelerometer high-g threshold 796 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 797 | * case 2g, no more than 1991 798 | * case 4g, no more than 3985 799 | * case 8g, no more than 7968 800 | * case 16g, no more than 15937 801 | * Attenion: The set value will be slightly biased according to datasheet 802 | */ 803 | void setAccHighGThres(uint16_t thres); 804 | 805 | /** 806 | * @brief setAccNmThres Set accelerometer no motion threshold 807 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 808 | * case 2g, no more than 1991 809 | * case 4g, no more than 3985 810 | * case 8g, no more than 7968 811 | * case 16g, no more than 15937 812 | * Attenion: The set value will be slightly biased according to datasheet 813 | */ 814 | void setAccNmThres(uint16_t thres); 815 | 816 | /** 817 | * @brief setAccNmSet Set accelerometer slow motion or no motion mode and duration 818 | * @param eSmnm Enum of eAccNmSmnm_t 819 | * @param dur Interrupt trigger delay (unit seconds), no more than 344. 820 | * Attenion: The set value will be slightly biased according to datasheet 821 | */ 822 | void setAccNmSet(eAccNmSmnm_t eSmnm, uint16_t dur); 823 | 824 | /** 825 | * @brief setGyrIntEnable Set corresponding gyroscope interrupt enable 826 | * @param eInt One or more interrupt flags to set, input them through operate or 827 | */ 828 | void setGyrIntEnable(eGyrIntSet_t eInt); 829 | 830 | /** 831 | * @brief setGyrIntDisable Set corresponding gyroscope interrupt disable 832 | * @param eInt One or more interrupt flags to set, input them through operate or 833 | */ 834 | void setGyrIntDisable(eGyrIntSet_t eInt); 835 | 836 | /** 837 | * @brief setGyrHrSet Set gyroscope high rate settings 838 | * @param eSingleAxis Single axis to set 839 | * @param thres High rate threshold to set, unit degree/seconds, value is dependent on gyroscope range selected, 840 | * case 2000, no more than 1937 841 | * case 1000, no more than 968 842 | * case 500, no more than 484 843 | * case 250, no more than 242 844 | * case 125, no more than 121 845 | * Attenion: The set value will be slightly biased according to datasheet 846 | * @param dur High rate duration to set, unit ms, duration from 2.5ms to 640ms 847 | * Attenion: The set value will be slightly biased according to datasheet 848 | */ 849 | void setGyrHrSet(eSingleAxis_t eSingleAxis, uint16_t thres, uint16_t dur); 850 | 851 | /** 852 | * @brief setGyrAmThres Set gyroscope any motion threshold 853 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 854 | * case 2000, no more than 128 855 | * case 1000, no more than 64 856 | * case 500, no more than 32 857 | * case 250, no more than 16 858 | * case 125, no more than 8 859 | * Attenion: The set value will be slightly biased according to datasheet 860 | */ 861 | void setGyrAmThres(uint8_t thres); 862 | 863 | protected: 864 | virtual void readReg(uint8_t reg, uint8_t *pBuf, uint8_t len) = 0; 865 | virtual void writeReg(uint8_t reg, uint8_t *pBuf, uint8_t len) = 0; 866 | 867 | uint8_t getReg(uint8_t reg, uint8_t pageId); 868 | void setToPage(uint8_t pageId); 869 | void setUnit(); 870 | void writeRegBits(uint8_t reg, uint8_t flied, uint8_t val); 871 | uint16_t mapAccThres(uint16_t thres); 872 | void mapGyrHrThres(uint8_t *pHysteresis, uint16_t *pThres, uint16_t *pDur); 873 | void mapGyrAmThres(uint8_t *pThres); 874 | 875 | sAxisData_t getAxisRaw(eAxis_t eAxis); 876 | sEulData_t getEulRaw(); 877 | sQuaData_t getQuaRaw(); 878 | 879 | // variables ---------------------------------------------------------------- 880 | public: 881 | /** 882 | * @brief lastOpreateStatus Show last operate status 883 | */ 884 | eStatus_t lastOperateStatus; 885 | 886 | protected: 887 | uint8_t _currentPage; 888 | eAccRange_t _eAccRange; 889 | eGyrRange_t _eGyrRange; 890 | 891 | }; 892 | 893 | 894 | // utils class ---------------------------------------------------------------- 895 | 896 | class DFRobot_BNO055_IIC : public DFRobot_BNO055 { 897 | public: 898 | /** 899 | * @brief The eCom3State enum, sensor address is according to pin(com3) state 900 | */ 901 | typedef enum { 902 | eCom3Low, 903 | eCom3High 904 | } eCom3State_t; 905 | 906 | /** 907 | * @brief DFRobot_BNO055_IIC class constructor 908 | * @param pWire select One TwoWire peripheral 909 | * @param addr Sensor address 910 | */ 911 | DFRobot_BNO055_IIC(TwoWire *pWire, uint8_t addr); 912 | 913 | protected: 914 | void readReg(uint8_t reg, uint8_t *pBuf, uint8_t len); 915 | void writeReg(uint8_t reg, uint8_t *pBuf, uint8_t len); 916 | 917 | protected: 918 | TwoWire *_pWire; 919 | uint8_t _addr; 920 | 921 | }; 922 | 923 | #endif 924 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DFRobot_BNO055 Intelligent 10DOF AHRS 2 | 3 | The BNO055 is a System in Package (SiP), integrating a triaxial 14-bit accelerometer,
4 | a triaxial 16-bit gyroscope with a range of ±2000 degrees per second, a triaxial geomagnetic sensor
5 | and a 32-bit cortex M0+ microcontroller running Bosch Sensortec sensor fusion software, in a single package.
6 | 7 | 8 | ## DFRobot_BNO055 Library for Arduino 9 | --------------------------------------------------------- 10 | Provides an Arduino library for reading and interpreting Bosch BNO055 data over I2C.Used to read the current pose and calculate the Euler angles. 11 | 12 | ## Table of Contents 13 | 14 | * [Installation](#installation) 15 | * [Methods](#methods) 16 | * [Compatibility](#compatibility) 17 | * [History](#history) 18 | * [Credits](#credits) 19 | 20 | 21 | 22 | 23 | ## Installation 24 | 25 | To use this library download the zip file, uncompress it to a folder named DFRobot_BNO055.
26 | Download the zip file first to use this library and uncompress it to a folder named DFRobot_BNO055.
27 | If you want to see the graphical interface using imu_show.ino,
28 | you can download IMU_show.exe at https://github.com/DFRobot/DFRobot_IMU_Show/releases.
29 | 30 | ## Methods 31 | 32 | ```C++ 33 | 34 | class DFRobot_BNO055 { 35 | 36 | public: 37 | /** 38 | * @brief global axis declare (excepet eular and quaternion) 39 | */ 40 | typedef enum { 41 | eAxisAcc, 42 | eAxisMag, 43 | eAxisGyr, 44 | eAxisLia, 45 | eAxisGrv 46 | } eAxis_t; 47 | 48 | /** 49 | * @brief global single axis declare 50 | */ 51 | typedef enum { 52 | eSingleAxisX, 53 | eSingleAxisY, 54 | eSingleAxisZ 55 | } eSingleAxis_t; 56 | 57 | /** 58 | * @brief enum interrupt 59 | */ 60 | typedef enum { 61 | eIntGyrAm = 0x04, 62 | eIntGyrHighRate = 0x08, 63 | eIntAccHighG = 0x20, 64 | eIntAccAm = 0x40, 65 | eIntAccNm = 0x80, 66 | eIntAll = 0xec 67 | } eInt_t; 68 | 69 | /** 70 | * @brief Operation mode enum 71 | */ 72 | typedef enum { 73 | eOprModeConfig, 74 | eOprModeAccOnly, 75 | eOprModeMagOnly, 76 | eOprModeGyroOnly, 77 | eOprModeAccMag, 78 | eOprModeAccGyro, 79 | eOprModeMagGyro, 80 | eOprModeAMG, 81 | eOprModeImu, 82 | eOprModeCompass, 83 | eOprModeM4G, 84 | eOprModeNdofFmcOff, 85 | eOprModeNdof 86 | } eOprMode_t; 87 | 88 | /** 89 | * @brief Poewr mode enum 90 | */ 91 | typedef enum { 92 | ePowerModeNormal, 93 | ePowerModeLowPower, 94 | ePowerModeSuspend 95 | } ePowerMode_t; 96 | 97 | /** 98 | * @brief axis analog data struct 99 | */ 100 | typedef struct { 101 | float x, y, z; 102 | } sAxisAnalog_t; 103 | 104 | /** 105 | * @brief eular analog data struct 106 | */ 107 | typedef struct { 108 | float head, roll, pitch; 109 | } sEulAnalog_t; 110 | 111 | /** 112 | * @brief qua analog data struct 113 | */ 114 | typedef struct { 115 | float w, x, y, z; 116 | } sQuaAnalog_t; 117 | 118 | /** 119 | * @brief enum accelerometer range, unit G 120 | */ 121 | typedef enum { 122 | eAccRange_2G, 123 | eAccRange_4G, 124 | eAccRange_8G, 125 | eAccRange_16G 126 | } eAccRange_t; 127 | 128 | /** 129 | * @brief enum accelerometer band width, unit HZ 130 | */ 131 | typedef enum { 132 | eAccBandWidth_7_81, // 7.81HZ 133 | eAccBandWidth_15_63, // 16.63HZ 134 | eAccBandWidth_31_25, 135 | eAccBandWidth_62_5, 136 | eAccBandWidth_125, 137 | eAccBandWidth_250, 138 | eAccBandWidth_500, 139 | eAccBandWidth_1000 140 | } eAccBandWidth_t; 141 | 142 | /** 143 | * @brief enum accelerometer power mode 144 | */ 145 | typedef enum { 146 | eAccPowerModeNormal, 147 | eAccPowerModeSuspend, 148 | eAccPowerModeLowPower1, 149 | eAccPowerModeStandby, 150 | eAccPowerModeLowPower2, 151 | eAccPowerModeDeepSuspend 152 | } eAccPowerMode_t; 153 | 154 | /** 155 | * @brief enum magnetometer data output rate, unit HZ 156 | */ 157 | typedef enum { 158 | eMagDataRate_2, 159 | eMagDataRate_6, 160 | eMagDataRate_8, 161 | eMagDataRate_10, 162 | eMagDataRate_15, 163 | eMagDataRate_20, 164 | eMagDataRate_25, 165 | eMagDataRate_30 166 | } eMagDataRate_t; 167 | 168 | /** 169 | * @brief enum magnetometer operation mode 170 | */ 171 | typedef enum { 172 | eMagOprModeLowPower, 173 | eMagOprModeRegular, 174 | eMagOprModeEnhancedRegular, 175 | eMagOprModeHighAccuracy 176 | } eMagOprMode_t; 177 | 178 | /** 179 | * @brief enum magnetometer power mode 180 | */ 181 | typedef enum { 182 | eMagPowerModeNormal, 183 | eMagPowerModeSleep, 184 | eMagPowerModeSuspend, 185 | eMagPowerModeForce 186 | } eMagPowerMode_t; 187 | 188 | /** 189 | * @brief enum gyroscope range, unit dps 190 | */ 191 | typedef enum { 192 | eGyrRange_2000, 193 | eGyrRange_1000, 194 | eGyrRange_500, 195 | eGyrRange_250, 196 | eGyrRange_125 197 | } eGyrRange_t; 198 | 199 | /** 200 | * @brief enum gyroscope band width, unit HZ 201 | */ 202 | typedef enum { 203 | eGyrBandWidth_523, 204 | eGyrBandWidth_230, 205 | eGyrBandWidth_116, 206 | eGyrBandWidth_47, 207 | eGyrBandWidth_23, 208 | eGyrBandWidth_12, 209 | eGyrBandWidth_64, 210 | eGyrBandWidth_32 211 | } eGyrBandWidth_t; 212 | 213 | /** 214 | * @brief enum gyroscope power mode 215 | */ 216 | typedef enum { 217 | eGyrPowerModeNormal, 218 | eGyrPowerModeFastPowerUp, 219 | eGyrPowerModeDeepSuspend, 220 | eGyrPowerModeSuspend, 221 | eGyrPowerModeAdvancedPowersave 222 | } eGyrPowerMode_t; 223 | 224 | /** 225 | * @brief Enum accelerometer interrupt settings 226 | */ 227 | typedef enum { 228 | eAccIntSetAmnmXAxis = (0x01 << 2), 229 | eAccIntSetAmnmYAxis = (0x01 << 3), 230 | eAccIntSetAmnmZAxis = (0x01 << 4), 231 | eAccIntSetHgXAxis = (0x01 << 5), 232 | eAccIntSetHgYAxis = (0x01 << 6), 233 | eAccIntSetHgZAxis = (0x01 << 7), 234 | eAccIntSetAll = 0xfc 235 | } eAccIntSet_t; 236 | 237 | /** 238 | * @brief Enum accelerometer slow motion mode or no motion mode 239 | */ 240 | typedef enum { 241 | eAccNmSmnmSm, // slow motion mode 242 | eAccNmSmnmNm // no motion mode 243 | } eAccNmSmnm_t; 244 | 245 | /** 246 | * @brief Enum gyroscope interrupt settings 247 | */ 248 | typedef enum { 249 | eGyrIntSetAmXAxis = (0x01 << 0), 250 | eGyrIntSetAmYAxis = (0x01 << 1), 251 | eGyrIntSetAmZAxis = (0x01 << 2), 252 | eGyrIntSetHrXAxis = (0x01 << 3), 253 | eGyrIntSetHrYAxis = (0x01 << 4), 254 | eGyrIntSetHrZAxis = (0x01 << 5), 255 | eGyrIntSetAmFilt = (0x01 << 6), 256 | eGyrIntSetHrFilt = (0x01 << 7), 257 | eGyrIntSetAll = 0x3f 258 | } eGyrIntSet_t; 259 | 260 | /** 261 | * @brief Declare sensor status 262 | */ 263 | typedef enum { 264 | eStatusOK, // everything OK 265 | eStatusErr, // unknow error 266 | eStatusErrDeviceNotDetect, // device not detected 267 | eStatusErrDeviceReadyTimeOut, // device ready time out 268 | eStatusErrDeviceStatus, // device internal status error 269 | eStatusErrParameter // function parameter error 270 | } eStatus_t; 271 | 272 | /** 273 | * @brief begin Sensor begin 274 | * @return Sensor status 275 | */ 276 | eStatus_t begin(); 277 | 278 | /** 279 | * @brief getAxisAnalog Get axis analog data 280 | * @param eAxis One axis type from eAxis_t 281 | * @return Struct sAxisAnalog_t, contains axis analog data, members unit depend on eAxis: 282 | * case eAxisAcc, unit mg 283 | * case eAxisLia, unit mg 284 | * case eAxisGrv, unit mg 285 | * case eAxisMag, unit ut 286 | * case eAxisGyr, unit dps 287 | */ 288 | sAxisAnalog_t getAxis(eAxis_t eAxis); 289 | 290 | /** 291 | * @brief getEulAnalog Get euler analog data 292 | * @return Struct sEulAnalog_t, contains euler analog data 293 | */ 294 | sEulAnalog_t getEul(); 295 | 296 | /** 297 | * @brief getQuaAnalog Get quaternion analog data 298 | * @return Struct sQuaAnalog_t, contains quaternion analog data 299 | */ 300 | sQuaAnalog_t getQua(); 301 | 302 | /** 303 | * @brief setAccOffset Set axis offset data 304 | * @param eAxis One axis type from eAxis_t, only support accelerometer, magnetometer and gyroscope 305 | * @param sOffset Struct sAxisAnalog_t, contains axis analog data, members unit depend on eAxis: 306 | * case eAxisAcc, unit mg, members can't out of acc range 307 | * case eAxisMag, unit ut, members can't out of mag range 308 | * case eAxisGyr, unit dps, members can't out of gyr range 309 | */ 310 | void setAxisOffset(eAxis_t eAxis, sAxisAnalog_t sOffset); 311 | 312 | /** 313 | * @brief setOprMode Set operation mode 314 | * @param eOpr One operation mode from eOprMode_t 315 | */ 316 | void setOprMode(eOprMode_t eMode); 317 | 318 | /** 319 | * @brief setPowerMode Set power mode 320 | * @param eMode One power mode from ePowerMode_t 321 | */ 322 | void setPowerMode(ePowerMode_t eMode); 323 | 324 | /** 325 | * @brief Reset sensor 326 | */ 327 | void reset(); 328 | 329 | /** 330 | * @brief setAccRange Set accelerometer measurement range, default value is 4g 331 | * @param eRange One range enum from eAccRange_t 332 | */ 333 | void setAccRange(eAccRange_t eRange); 334 | 335 | /** 336 | * @brief setAccBandWidth Set accelerometer band width, default value is 62.5hz 337 | * @param eBand One band enum from eAccBandWidth_t 338 | */ 339 | void setAccBandWidth(eAccBandWidth_t eBand); 340 | 341 | /** 342 | * @brief setAccPowerMode Set accelerometer power mode, default value is eAccPowerModeNormal 343 | * @param eMode One mode enum from eAccPowerMode_t 344 | */ 345 | void setAccPowerMode(eAccPowerMode_t eMode); 346 | 347 | /** 348 | * @brief setMagDataRate Set magnetometer data output rate, default value is 20hz 349 | * @param eRate One rate enum from eMagDataRate_t 350 | */ 351 | void setMagDataRate(eMagDataRate_t eRate); 352 | 353 | /** 354 | * @brief setMagOprMode Set magnetometer operation mode, default value is eMagOprModeRegular 355 | * @param eMode One mode enum from eMagOprMode_t 356 | */ 357 | void setMagOprMode(eMagOprMode_t eMode); 358 | 359 | /** 360 | * @brief setMagPowerMode Set magnetometer power mode, default value is eMagePowerModeForce 361 | * @param eMode One mode enum from eMagPowerMode_t 362 | */ 363 | void setMagPowerMode(eMagPowerMode_t eMode); 364 | 365 | /** 366 | * @brief setGyrRange Set gyroscope range, default value is 2000 367 | * @param eRange One range enum from eGyrRange_t 368 | */ 369 | void setGyrRange(eGyrRange_t eRange); 370 | 371 | /** 372 | * @brief setGyrBandWidth Set gyroscope band width, default value is 32HZ 373 | * @param eBandWidth One band width enum from eGyrBandWidth_t 374 | */ 375 | void setGyrBandWidth(eGyrBandWidth_t eBandWidth); 376 | 377 | /** 378 | * @brief setGyrPowerMode Set gyroscope power mode, default value is eGyrPowerModeNormal 379 | * @param eMode One power mode enum from eGyrPowerMode_t 380 | */ 381 | void setGyrPowerMode(eGyrPowerMode_t eMode); 382 | 383 | /** 384 | * @brief getIntState Get interrupt state, interrupt auto clear after read 385 | * @return If result > 0, at least one interrupt triggered. Result & eIntXXX (from eInt_t) to test is triggered 386 | */ 387 | uint8_t getIntState(); 388 | 389 | /** 390 | * @brief setIntMask Set interrupt mask enable, there will generate a interrupt signal (raising) on INT pin if corresponding interrupt enabled 391 | * @param eInt One or more interrupt flags to set, input them through operate or 392 | */ 393 | void setIntMaskEnable(eInt_t eInt); 394 | 395 | /** 396 | * @brief setIntMaskDisable Set corresponding interrupt mask disable 397 | * @param eInt One or more interrupt flags to set, input them through operate or 398 | */ 399 | void setIntMaskDisable(eInt_t eInt); 400 | 401 | /** 402 | * @brief setIntEnEnable Set corresponding interrupt enable 403 | * @param eInt One or more interrupt flags to set, input them through operate or 404 | */ 405 | void setIntEnable(eInt_t eInt); 406 | 407 | /** 408 | * @brief setIntEnDisable Set corresponding interrupt disable 409 | * @param eInt One or more interrupt flags to set, input them through operate or 410 | */ 411 | void setIntDisable(eInt_t eInt); 412 | 413 | /** 414 | * @brief setAccAmThres Set accelerometer any motion threshold 415 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 416 | * case 2g, no more than 1991 417 | * case 4g, no more than 3985 418 | * case 8g, no more than 7968 419 | * case 16g, no more than 15937 420 | * Attenion: The set value will be slightly biased according to datasheet 421 | */ 422 | void setAccAmThres(uint16_t thres); 423 | 424 | /** 425 | * @brief setAccIntDur Set accelerometer interrupt duration, 426 | * any motion interrupt triggers if duration (dur + 1) consecutive data points are above the any motion interrupt 427 | * threshold define in any motion threshold 428 | * @param dur Duration to set, range form 1 to 4 429 | */ 430 | void setAccIntAmDur(uint8_t dur); 431 | 432 | /** 433 | * @brief setAccIntEnable Set accelerometer interrupt enable 434 | * @param eInt One or more interrupt flags to set, input them through operate or 435 | */ 436 | void setAccIntEnable(eAccIntSet_t eInt); 437 | 438 | /** 439 | * @brief setAccIntDisable Set accelerometer interrupt disable 440 | * @param eInt One or more interrupt flags to set, input them through operate or 441 | */ 442 | void setAccIntDisable(eAccIntSet_t eInt); 443 | 444 | /** 445 | * @brief setAccHighGDuration Set accelerometer high-g interrupt, the high-g interrupt delay according to [dur + 1] * 2 ms 446 | * @param dur Duration from 2ms to 512ms 447 | */ 448 | void setAccHighGDuration(uint16_t dur); 449 | 450 | /** 451 | * @brief setAccHighGThres Set accelerometer high-g threshold 452 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 453 | * case 2g, no more than 1991 454 | * case 4g, no more than 3985 455 | * case 8g, no more than 7968 456 | * case 16g, no more than 15937 457 | * Attenion: The set value will be slightly biased according to datasheet 458 | */ 459 | void setAccHighGThres(uint16_t thres); 460 | 461 | /** 462 | * @brief setAccNmThres Set accelerometer no motion threshold 463 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 464 | * case 2g, no more than 1991 465 | * case 4g, no more than 3985 466 | * case 8g, no more than 7968 467 | * case 16g, no more than 15937 468 | * Attenion: The set value will be slightly biased according to datasheet 469 | */ 470 | void setAccNmThres(uint16_t thres); 471 | 472 | /** 473 | * @brief setAccNmSet Set accelerometer slow motion or no motion mode and duration 474 | * @param eSmnm Enum of eAccNmSmnm_t 475 | * @param dur Interrupt trigger delay (unit seconds), no more than 344. 476 | * Attenion: The set value will be slightly biased according to datasheet 477 | */ 478 | void setAccNmSet(eAccNmSmnm_t eSmnm, uint16_t dur); 479 | 480 | /** 481 | * @brief setGyrIntEnable Set corresponding gyroscope interrupt enable 482 | * @param eInt One or more interrupt flags to set, input them through operate or 483 | */ 484 | void setGyrIntEnable(eGyrIntSet_t eInt); 485 | 486 | /** 487 | * @brief setGyrIntDisable Set corresponding gyroscope interrupt disable 488 | * @param eInt One or more interrupt flags to set, input them through operate or 489 | */ 490 | void setGyrIntDisable(eGyrIntSet_t eInt); 491 | 492 | /** 493 | * @brief setGyrHrSet Set gyroscope high rate settings 494 | * @param eSingleAxis Single axis to set 495 | * @param thres High rate threshold to set, unit degree/seconds, value is dependent on gyroscope range selected, 496 | * case 2000, no more than 1937 497 | * case 1000, no more than 968 498 | * case 500, no more than 484 499 | * case 250, no more than 242 500 | * case 125, no more than 121 501 | * Attenion: The set value will be slightly biased according to datasheet 502 | * @param dur High rate duration to set, unit ms, duration from 2.5ms to 640ms 503 | * Attenion: The set value will be slightly biased according to datasheet 504 | */ 505 | void setGyrHrSet(eSingleAxis_t eSingleAxis, uint16_t thres, uint16_t dur); 506 | 507 | /** 508 | * @brief setGyrAmThres Set gyroscope any motion threshold 509 | * @param thres Threshold to set, unit mg, value is dependent on accelerometer range selected, 510 | * case 2000, no more than 128 511 | * case 1000, no more than 64 512 | * case 500, no more than 32 513 | * case 250, no more than 16 514 | * case 125, no more than 8 515 | * Attenion: The set value will be slightly biased according to datasheet 516 | */ 517 | void setGyrAmThres(uint8_t thres); 518 | 519 | /** 520 | * @brief lastOpreateStatus Show last operate status 521 | */ 522 | eStatus_t lastOpreateStatus; 523 | }; 524 | 525 | class DFRobot_BNO055_IIC : public DFRobot_BNO055 { 526 | public: 527 | 528 | /** 529 | * @brief DFRobot_BNO055_IIC class constructor 530 | * @param pWire select One TwoWire peripheral 531 | * @param addr Sensor address 532 | */ 533 | DFRobot_BNO055_IIC(TwoWire *pWire, uint8_t addr); 534 | }; 535 | 536 | ``` 537 | 538 | ## Compatibility 539 | 540 | MCU | Work Well | Work Wrong | Untested | Remarks 541 | ------------------ | :----------: | :----------: | :---------: | ----- 542 | FireBeetle-ESP32 | √ | | | 543 | FireBeetle-ESP8266 | √ | | | 544 | Arduino uno | √ | | | 545 | 546 | ## History 547 | 548 | - 07/03/2019 - Version 0.2 released. 549 | ## About this Driver ## 550 | 551 | Written by Frank [jiehan.guo@dfrobot.com](#jiehan.guo@dfrobot.com) 552 | -------------------------------------------------------------------------------- /examples/config/config.ino: -------------------------------------------------------------------------------- 1 | /*! 2 | * config.ino 3 | * 4 | * Download this demo to test config to bno055 5 | * Data will print on your serial monitor 6 | * 7 | * Product: http://www.dfrobot.com.cn/goods-1860.html 8 | * Copyright [DFRobot](http://www.dfrobot.com), 2016 9 | * Copyright GNU Lesser General Public License 10 | * 11 | * version V1.0 12 | * date 07/03/2019 13 | */ 14 | 15 | #include "DFRobot_BNO055.h" 16 | #include "Wire.h" 17 | 18 | typedef DFRobot_BNO055_IIC BNO; // ******** use abbreviations instead of full names ******** 19 | 20 | BNO bno(&Wire, 0x28); // input TwoWire interface and IIC address 21 | 22 | // show last sensor operate status 23 | void printLastOperateStatus(BNO::eStatus_t eStatus) 24 | { 25 | switch(eStatus) { 26 | case BNO::eStatusOK: Serial.println("everything ok"); break; 27 | case BNO::eStatusErr: Serial.println("unknow error"); break; 28 | case BNO::eStatusErrDeviceNotDetect: Serial.println("device not detected"); break; 29 | case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break; 30 | case BNO::eStatusErrDeviceStatus: Serial.println("device internal status error"); break; 31 | default: Serial.println("unknow status"); break; 32 | } 33 | } 34 | 35 | void setup() 36 | { 37 | Serial.begin(115200); 38 | bno.reset(); 39 | while(bno.begin() != BNO::eStatusOK) { 40 | Serial.println("bno begin faild"); 41 | printLastOperateStatus(bno.lastOperateStatus); 42 | delay(2000); 43 | } 44 | Serial.println("bno begin success"); 45 | 46 | bno.setPowerMode(BNO::ePowerModeNormal); // set to normal power mode 47 | bno.setOprMode(BNO::eOprModeConfig); // must set sensor to config-mode before configure 48 | bno.setAccPowerMode(BNO::eAccPowerModeNormal); // set acc to normal power mode 49 | bno.setGyrPowerMode(BNO::eGyrPowerModeNormal); // set gyr to normal power mode 50 | bno.setMagPowerMode(BNO::eMagPowerModeForce); // set mag to force power mode 51 | 52 | // accelerometer normal configure 53 | bno.setAccRange(BNO::eAccRange_4G); // set range to 4g 54 | bno.setAccBandWidth(BNO::eAccBandWidth_62_5); // set band width 62.5HZ 55 | bno.setAccPowerMode(BNO::eAccPowerModeNormal); // set accelerometer power mode 56 | 57 | // magnetometer normal configure 58 | bno.setMagDataRate(BNO::eMagDataRate_20); // set output data rate 20HZ 59 | bno.setMagPowerMode(BNO::eMagPowerModeForce); // set power mode 60 | bno.setMagOprMode(BNO::eMagOprModeRegular); // set operate mode 61 | 62 | // gyroscope normal configure 63 | bno.setGyrRange(BNO::eGyrRange_2000); // set range 64 | bno.setGyrBandWidth(BNO::eGyrBandWidth_32); // set band width 65 | bno.setGyrPowerMode(BNO::eGyrPowerModeNormal); // set power mode 66 | 67 | BNO::sAxisAnalog_t sOffsetAcc; // unit mg, members can't out of acc range 68 | BNO::sAxisAnalog_t sOffsetMag; // unit ut, members can't out of mag range 69 | BNO::sAxisAnalog_t sOffsetGyr; // unit dps, members can't out of gyr range 70 | sOffsetAcc.x = 1; 71 | sOffsetAcc.y = 1; 72 | sOffsetAcc.z = 1; 73 | sOffsetMag.x = 1; 74 | sOffsetMag.y = 1; 75 | sOffsetMag.z = 1; 76 | sOffsetGyr.x = 1; 77 | sOffsetGyr.y = 1; 78 | sOffsetGyr.z = 1; 79 | bno.setAxisOffset(BNO::eAxisAcc, sOffsetAcc); // set offset 80 | bno.setAxisOffset(BNO::eAxisMag, sOffsetMag); 81 | bno.setAxisOffset(BNO::eAxisGyr, sOffsetGyr); 82 | 83 | bno.setOprMode(BNO::eOprModeNdof); // shift to other operate mode, reference datasheet for more detail 84 | } 85 | 86 | #define printAxisData(sAxis) \ 87 | Serial.print(" x: "); \ 88 | Serial.print(sAxis.x); \ 89 | Serial.print(" y: "); \ 90 | Serial.print(sAxis.y); \ 91 | Serial.print(" z: "); \ 92 | Serial.println(sAxis.z) 93 | 94 | void loop() 95 | { 96 | BNO::sAxisAnalog_t sAccAnalog, sMagAnalog, sGyrAnalog, sLiaAnalog, sGrvAnalog; 97 | BNO::sEulAnalog_t sEulAnalog; 98 | BNO::sQuaAnalog_t sQuaAnalog; 99 | sAccAnalog = bno.getAxis(BNO::eAxisAcc); 100 | sMagAnalog = bno.getAxis(BNO::eAxisMag); 101 | sGyrAnalog = bno.getAxis(BNO::eAxisGyr); 102 | sLiaAnalog = bno.getAxis(BNO::eAxisLia); 103 | sGrvAnalog = bno.getAxis(BNO::eAxisGrv); 104 | sEulAnalog = bno.getEul(); 105 | sQuaAnalog = bno.getQua(); 106 | Serial.println(); 107 | Serial.println("======== analog data print start ========"); 108 | Serial.print("acc analog: (unit mg) "); printAxisData(sAccAnalog); 109 | Serial.print("mag analog: (unit ut) "); printAxisData(sMagAnalog); 110 | Serial.print("gyr analog: (unit dps) "); printAxisData(sGyrAnalog); 111 | Serial.print("lia analog: (unit mg) "); printAxisData(sLiaAnalog); 112 | Serial.print("grv analog: (unit mg) "); printAxisData(sGrvAnalog); 113 | Serial.print("eul analog: (unit degree) "); Serial.print(" head: "); Serial.print(sEulAnalog.head); Serial.print(" roll: "); Serial.print(sEulAnalog.roll); Serial.print(" pitch: "); Serial.println(sEulAnalog.pitch); 114 | Serial.print("qua analog: (no unit) "); Serial.print(" w: "); Serial.print(sQuaAnalog.w); printAxisData(sQuaAnalog); 115 | Serial.println("======== analog data print end ========"); 116 | 117 | delay(1000); 118 | } 119 | -------------------------------------------------------------------------------- /examples/imu_show/imu_show.ino: -------------------------------------------------------------------------------- 1 | /*! 2 | * imu_show.ino 3 | * 4 | * Download this demo to show attitude on [imu_show](https://github.com/DFRobot/DFRobot_IMU_Show) 5 | * Attitude will show on imu_show 6 | * 7 | * Product: http://www.dfrobot.com.cn/goods-1860.html 8 | * Copyright [DFRobot](http://www.dfrobot.com), 2016 9 | * Copyright GNU Lesser General Public License 10 | * 11 | * version V1.0 12 | * date 07/03/2019 13 | */ 14 | 15 | #include "DFRobot_BNO055.h" 16 | #include "Wire.h" 17 | 18 | typedef DFRobot_BNO055_IIC BNO; // ******** use abbreviations instead of full names ******** 19 | 20 | BNO bno(&Wire, 0x28); // input TwoWire interface and IIC address 21 | 22 | // show last sensor operate status 23 | void printLastOperateStatus(BNO::eStatus_t eStatus) 24 | { 25 | switch(eStatus) { 26 | case BNO::eStatusOK: Serial.println("everything ok"); break; 27 | case BNO::eStatusErr: Serial.println("unknow error"); break; 28 | case BNO::eStatusErrDeviceNotDetect: Serial.println("device not detected"); break; 29 | case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break; 30 | case BNO::eStatusErrDeviceStatus: Serial.println("device internal status error"); break; 31 | default: Serial.println("unknow status"); break; 32 | } 33 | } 34 | 35 | void setup() 36 | { 37 | Serial.begin(115200); 38 | bno.reset(); 39 | while(bno.begin() != BNO::eStatusOK) { 40 | Serial.println("bno begin faild"); 41 | printLastOperateStatus(bno.lastOperateStatus); 42 | delay(2000); 43 | } 44 | Serial.println("bno begin success"); 45 | } 46 | 47 | void loop() 48 | { 49 | BNO::sEulAnalog_t sEul; 50 | sEul = bno.getEul(); 51 | Serial.print("pitch:"); 52 | Serial.print(sEul.pitch, 3); 53 | Serial.print(" "); 54 | Serial.print("roll:"); 55 | Serial.print(sEul.roll, 3); 56 | Serial.print(" "); 57 | Serial.print("yaw:"); 58 | Serial.print(sEul.head, 3); 59 | Serial.println(" "); 60 | delay(80); 61 | } 62 | -------------------------------------------------------------------------------- /examples/interrupt/interrupt.ino: -------------------------------------------------------------------------------- 1 | /*! 2 | * interrupt.ino 3 | * 4 | * Download this demo to test bno055 interrupt 5 | * Connect bno055 int pin to arduino pin 2 6 | * If there occurs interrupt, it will printr on you serial monitor, more detail please reference comment 7 | * 8 | * Product: http://www.dfrobot.com.cn/goods-1860.html 9 | * Copyright [DFRobot](http://www.dfrobot.com), 2016 10 | * Copyright GNU Lesser General Public License 11 | * 12 | * version V1.0 13 | * date 07/03/2019 14 | */ 15 | 16 | #include "DFRobot_BNO055.h" 17 | #include "Wire.h" 18 | 19 | typedef DFRobot_BNO055_IIC BNO; // ******** use abbreviations instead of full names ******** 20 | 21 | BNO bno(&Wire, 0x28); // input TwoWire interface and IIC address 22 | 23 | // show last sensor operate status 24 | void printLastOperateStatus(BNO::eStatus_t eStatus) 25 | { 26 | switch(eStatus) { 27 | case BNO::eStatusOK: Serial.println("everything ok"); break; 28 | case BNO::eStatusErr: Serial.println("unknow error"); break; 29 | case BNO::eStatusErrDeviceNotDetect: Serial.println("device not detected"); break; 30 | case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break; 31 | case BNO::eStatusErrDeviceStatus: Serial.println("device internal status error"); break; 32 | default: Serial.println("unknow status"); break; 33 | } 34 | } 35 | 36 | bool intFlag = false; 37 | 38 | void intHandle() 39 | { 40 | intFlag = true; 41 | } 42 | 43 | void setup() 44 | { 45 | Serial.begin(115200); 46 | bno.reset(); 47 | while(bno.begin() != BNO::eStatusOK) { 48 | Serial.println("bno begin faild"); 49 | printLastOperateStatus(bno.lastOperateStatus); 50 | delay(2000); 51 | } 52 | Serial.println("bno begin success"); 53 | 54 | bno.setOprMode(BNO::eOprModeConfig); // set to config mode 55 | 56 | bno.setIntMaskEnable(BNO::eIntAll); // set interrupt mask enable, signal to int pin when interrupt 57 | // bno.setIntMaskDisable(BNO::eIntAccAm | BNO::eIntAccNm); // set interrupt mask disable, no signal to int pin when interrupt 58 | 59 | bno.setIntEnable(BNO::eIntAll); // set interrupt enable 60 | // bno.setIntDisable(BNO::eIntAccAm | BNO::eIntAccNm); // set interrupt disable 61 | 62 | bno.setAccIntEnable(BNO::eAccIntSetAll); // set accelerometer interrupt enable 63 | // bno.setAccIntDisable(BNO::eAccIntSetAmnmXAxis | BNO::eAccIntSetHgXAxis); // set accelerometer interrupt disable 64 | 65 | /* accelerometer any motion threshold to set, unit mg, value is dependent on accelerometer range selected, 66 | * case 2g, no more than 1991 67 | * case 4g, no more than 3985 68 | * case 8g, no more than 7968 69 | * case 16g, no more than 15937 70 | * attenion: The set value will be slightly biased according to datasheet 71 | * tips: default accelerometer range is 4g 72 | */ 73 | // how to trig this: still --> fast move 74 | bno.setAccAmThres(200); 75 | // any motion interrupt triggers if duration consecutive data points are above the any motion interrupt 76 | // threshold define in any motion threshold 77 | bno.setAccIntAmDur(1); 78 | // set high-g duration, value from 2ms to 512ms 79 | bno.setAccHighGDuration(80); 80 | /* 81 | * accelerometer high-g threshold to set, unit mg, value is dependent on accelerometer range selected, 82 | * case 2g, no more than 1991 83 | * case 4g, no more than 3985 84 | * case 8g, no more than 7968 85 | * case 16g, no more than 15937 86 | * Attenion: The set value will be slightly biased according to datasheet 87 | */ 88 | // how to trig this: still --> (very) fast move 89 | bno.setAccHighGThres(900); 90 | // accelerometer (no motion) / (slow motion) settings, 2nd parameter unit seconds, no more than 344 91 | bno.setAccNmSet(BNO::eAccNmSmnmNm, 4); 92 | /* 93 | * accelerometer no motion threshold to set, unit mg, value is dependent on accelerometer range selected, 94 | * case 2g, no more than 1991 95 | * case 4g, no more than 3985 96 | * case 8g, no more than 7968 97 | * case 16g, no more than 15937 98 | * Attenion: The set value will be slightly biased according to datasheet 99 | */ 100 | // hot to trig this: any motion --> still --> still 101 | bno.setAccNmThres(100); 102 | 103 | bno.setGyrIntEnable((BNO::eGyrIntSet_t) (BNO::eGyrIntSetHrXAxis | BNO::eGyrIntSetHrYAxis | BNO::eGyrIntSetHrZAxis)); // set gyroscope interrupt enable, in most cases, this is enough. 104 | // bno.setGyrIntEnable(BNO::eGyrIntSetAmYAxis | BNO::eGyrIntSetAmYAxis | BNO::eGyrIntSetAmZAxis); // set gyroscope interrupt enable 105 | // bno.setGyrIntDisable(BNO::eGyrIntSetHrXAxis | BNO::eGyrIntSetAmXAxis); // set gyroscope interrupt disable 106 | 107 | /* 108 | * 2nd parameter, high rate threshold to set, unit degree/seconds, value is dependent on gyroscope range selected, 109 | * case 2000, no more than 1937 110 | * case 1000, no more than 968 111 | * case 500, no more than 484 112 | * case 250, no more than 242 113 | * case 125, no more than 121 114 | * Attenion: The set value will be slightly biased according to datasheet 115 | * 3rd parameter, high rate duration to set, unit ms, duration from 2.5ms to 640ms 116 | * Attenion: The set value will be slightly biased according to datasheet 117 | */ 118 | // how to trigger this: still --> fast tilt 119 | bno.setGyrHrSet(BNO::eSingleAxisX, 300, 80); 120 | bno.setGyrHrSet(BNO::eSingleAxisY, 300, 80); 121 | bno.setGyrHrSet(BNO::eSingleAxisZ, 300, 80); 122 | /* 123 | * gyroscope any motion threshold to set, unit mg, value is dependent on accelerometer range selected, 124 | * case 2000, no more than 128 125 | * case 1000, no more than 64 126 | * case 500, no more than 32 127 | * case 250, no more than 16 128 | * case 125, no more than 8 129 | * Attenion: The set value will be slightly biased according to datasheet 130 | * tips: default range is 2000 131 | */ 132 | // how to trigger this: still --> fast tilt 133 | bno.setGyrAmThres(20); 134 | 135 | bno.setOprMode(BNO::eOprModeNdof); // configure done 136 | 137 | attachInterrupt(0, intHandle, RISING); // attach interrupt 138 | bno.getIntState(); // clear unexpected interrupt 139 | intFlag = false; 140 | } 141 | 142 | void loop() 143 | { 144 | if(intFlag) { 145 | intFlag = false; 146 | uint8_t intSta = bno.getIntState(); // interrupt auto clear after read 147 | 148 | Serial.println("interrupt detected"); 149 | if(intSta & BNO::eIntAccAm) 150 | Serial.println("accelerometer any motion detected"); 151 | if(intSta & BNO::eIntAccNm) 152 | Serial.println("accelerometer no motion detected"); 153 | if(intSta & BNO::eIntAccHighG) 154 | Serial.println("acceleromter high-g detected"); 155 | if(intSta & BNO::eIntGyrHighRate) 156 | Serial.println("gyroscope high rate detected"); 157 | if(intSta & BNO::eIntGyrAm) 158 | Serial.println("gyroscope any motion detected"); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /examples/readData/readData.ino: -------------------------------------------------------------------------------- 1 | /*! 2 | * read_data.ino 3 | * 4 | * Download this demo to test read data from bno055 5 | * Data will print on your serial monitor 6 | * 7 | * Product: http://www.dfrobot.com.cn/goods-1860.html 8 | * Copyright [DFRobot](http://www.dfrobot.com), 2016 9 | * Copyright GNU Lesser General Public License 10 | * 11 | * version V1.0 12 | * date 07/03/2019 13 | */ 14 | 15 | #include "DFRobot_BNO055.h" 16 | #include "Wire.h" 17 | 18 | typedef DFRobot_BNO055_IIC BNO; // ******** use abbreviations instead of full names ******** 19 | 20 | BNO bno(&Wire, 0x28); // input TwoWire interface and IIC address 21 | 22 | // show last sensor operate status 23 | void printLastOperateStatus(BNO::eStatus_t eStatus) 24 | { 25 | switch(eStatus) { 26 | case BNO::eStatusOK: Serial.println("everything ok"); break; 27 | case BNO::eStatusErr: Serial.println("unknow error"); break; 28 | case BNO::eStatusErrDeviceNotDetect: Serial.println("device not detected"); break; 29 | case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break; 30 | case BNO::eStatusErrDeviceStatus: Serial.println("device internal status error"); break; 31 | default: Serial.println("unknow status"); break; 32 | } 33 | } 34 | 35 | void setup() 36 | { 37 | Serial.begin(115200); 38 | bno.reset(); 39 | while(bno.begin() != BNO::eStatusOK) { 40 | Serial.println("bno begin faild"); 41 | printLastOperateStatus(bno.lastOperateStatus); 42 | delay(2000); 43 | } 44 | Serial.println("bno begin success"); 45 | } 46 | 47 | #define printAxisData(sAxis) \ 48 | Serial.print(" x: "); \ 49 | Serial.print(sAxis.x); \ 50 | Serial.print(" y: "); \ 51 | Serial.print(sAxis.y); \ 52 | Serial.print(" z: "); \ 53 | Serial.println(sAxis.z) 54 | 55 | void loop() 56 | { 57 | BNO::sAxisAnalog_t sAccAnalog, sMagAnalog, sGyrAnalog, sLiaAnalog, sGrvAnalog; 58 | BNO::sEulAnalog_t sEulAnalog; 59 | BNO::sQuaAnalog_t sQuaAnalog; 60 | sAccAnalog = bno.getAxis(BNO::eAxisAcc); // read acceleration 61 | sMagAnalog = bno.getAxis(BNO::eAxisMag); // read geomagnetic 62 | sGyrAnalog = bno.getAxis(BNO::eAxisGyr); // read gyroscope 63 | sLiaAnalog = bno.getAxis(BNO::eAxisLia); // read linear acceleration 64 | sGrvAnalog = bno.getAxis(BNO::eAxisGrv); // read gravity vector 65 | sEulAnalog = bno.getEul(); // read euler angle 66 | sQuaAnalog = bno.getQua(); // read quaternion 67 | Serial.println(); 68 | Serial.println("======== analog data print start ========"); 69 | Serial.print("acc analog: (unit mg) "); printAxisData(sAccAnalog); 70 | Serial.print("mag analog: (unit ut) "); printAxisData(sMagAnalog); 71 | Serial.print("gyr analog: (unit dps) "); printAxisData(sGyrAnalog); 72 | Serial.print("lia analog: (unit mg) "); printAxisData(sLiaAnalog); 73 | Serial.print("grv analog: (unit mg) "); printAxisData(sGrvAnalog); 74 | Serial.print("eul analog: (unit degree) "); Serial.print(" head: "); Serial.print(sEulAnalog.head); Serial.print(" roll: "); Serial.print(sEulAnalog.roll); Serial.print(" pitch: "); Serial.println(sEulAnalog.pitch); 75 | Serial.print("qua analog: (no unit) "); Serial.print(" w: "); Serial.print(sQuaAnalog.w); printAxisData(sQuaAnalog); 76 | Serial.println("======== analog data print end ========"); 77 | 78 | delay(1000); 79 | } 80 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | 2 | eAxisAcc LITERAL1 3 | eAxisMag LITERAL1 4 | eAxisGyr LITERAL1 5 | eAxisLia LITERAL1 6 | eAxisGrv LITERAL1 7 | eAxis_t LITERAL1 8 | 9 | eSingleAxisX LITERAL1 10 | eSingleAxisY LITERAL1 11 | eSingleAxisZ LITERAL1 12 | eSingleAxis_t LITERAL1 13 | 14 | eIntGyrAm LITERAL1 15 | eIntGyrHighRate LITERAL1 16 | eIntAccHighG LITERAL1 17 | eIntAccAm LITERAL1 18 | eIntAccNm LITERAL1 19 | eIntAll LITERAL1 20 | 21 | eOprModeConfig LITERAL1 22 | eOprModeAccOnly LITERAL1 23 | eOprModeMagOnly LITERAL1 24 | eOprModeGyroOnly LITERAL1 25 | eOprModeAccMag LITERAL1 26 | eOprModeAccGyro LITERAL1 27 | eOprModeMagGyro LITERAL1 28 | eOprModeAMG LITERAL1 29 | eOprModeImu LITERAL1 30 | eOprModeCompass LITERAL1 31 | eOprModeM4G LITERAL1 32 | eOprModeNdofFmcOff LITERAL1 33 | eOprModeNdof LITERAL1 34 | eOprMode_t LITERAL1 35 | 36 | ePowerModeNormal LITERAL1 37 | ePowerModeLowPower LITERAL1 38 | ePowerModeSuspend LITERAL1 39 | ePowerMode_t LITERAL1 40 | 41 | x KEYWORD1 42 | y KEYWORD1 43 | z KEYWORD1 44 | sAxisAnalog_t KEYWORD1 45 | 46 | head KEYWORD1 47 | roll KEYWORD1 48 | pitch KEYWORD1 49 | sEulAnalog_t KEYWORD1 50 | 51 | w KEYWORD1 52 | sQuaAnalog_t KEYWORD1 53 | 54 | eAccRange_2G LITERAL1 55 | eAccRange_4G LITERAL1 56 | eAccRange_8G LITERAL1 57 | eAccRange_16G LITERAL1 58 | eAccRange_t LITERAL1 59 | 60 | eAccBandWidth_7_81 LITERAL1 61 | eAccBandWidth_15_63 LITERAL1 62 | eAccBandWidth_31_25 LITERAL1 63 | eAccBandWidth_62_5 LITERAL1 64 | eAccBandWidth_125 LITERAL1 65 | eAccBandWidth_250 LITERAL1 66 | eAccBandWidth_500 LITERAL1 67 | eAccBandWidth_1000 LITERAL1 68 | eAccBandWidth_t LITERAL1 69 | 70 | eAccPowerModeNormal LITERAL1 71 | eAccPowerModeSuspend LITERAL1 72 | eAccPowerModeLowPower1 LITERAL1 73 | eAccPowerModeStandby LITERAL1 74 | eAccPowerModeLowPower2 LITERAL1 75 | eAccPowerModeDeepSuspend LITERAL1 76 | eAccPowerMode_t 77 | 78 | eMagDataRate_2 LITERAL1 79 | eMagDataRate_6 LITERAL1 80 | eMagDataRate_8 LITERAL1 81 | eMagDataRate_10 LITERAL1 82 | eMagDataRate_15 LITERAL1 83 | eMagDataRate_20 LITERAL1 84 | eMagDataRate_25 LITERAL1 85 | eMagDataRate_30 LITERAL1 86 | eMagDataRate_t LITERAL1 87 | 88 | eMagOprModeLowPower LITERAL1 89 | eMagOprModeRegular LITERAL1 90 | eMagOprModeEnhancedRegular LITERAL1 91 | eMagOprModeHighAccuracy LITERAL1 92 | eMagOprMode_t LITERAL1 93 | 94 | eMagPowerModeNormal LITERAL1 95 | eMagPowerModeSleep LITERAL1 96 | eMagPowerModeSuspend LITERAL1 97 | eMagPowerModeForce LITERAL1 98 | eMagPowerMode_t LITERAL1 99 | 100 | eGyrRange_2000 LITERAL1 101 | eGyrRange_1000 LITERAL1 102 | eGyrRange_500 LITERAL1 103 | eGyrRange_250 LITERAL1 104 | eGyrRange_125 LITERAL1 105 | eGyrRange_t LITERAL1 106 | 107 | eGyrBandWidth_523 LITERAL1 108 | eGyrBandWidth_230 LITERAL1 109 | eGyrBandWidth_116 LITERAL1 110 | eGyrBandWidth_47 LITERAL1 111 | eGyrBandWidth_23 LITERAL1 112 | eGyrBandWidth_12 LITERAL1 113 | eGyrBandWidth_64 LITERAL1 114 | eGyrBandWidth_32 LITERAL1 115 | eGyrBandWidth_t LITERAL1 116 | 117 | eGyrPowerModeNormal LITERAL1 118 | eGyrPowerModeFastPowerUp LITERAL1 119 | eGyrPowerModeDeepSuspend LITERAL1 120 | eGyrPowerModeSuspend LITERAL1 121 | eGyrPowerModeAdvancedPowersave LITERAL1 122 | eGyrPowerMode_t LITERAL1 123 | 124 | eAccIntSetAmnmXAxis LITERAL1 125 | eAccIntSetAmnmYAxis LITERAL1 126 | eAccIntSetAmnmZAxis LITERAL1 127 | eAccIntSetHgXAxis LITERAL1 128 | eAccIntSetHgYAxis LITERAL1 129 | eAccIntSetHgZAxis LITERAL1 130 | eAccIntSetAll LITERAL1 131 | eAccIntSet_t LITERAL1 132 | 133 | eAccNmSmnmSm LITERAL1 134 | eAccNmSmnmNm LITERAL1 135 | eAccNmSmnm_t LITERAL1 136 | 137 | eGyrIntSetAmXAxis LITERAL1 138 | eGyrIntSetAmYAxis LITERAL1 139 | eGyrIntSetAmZAxis LITERAL1 140 | eGyrIntSetHrXAxis LITERAL1 141 | eGyrIntSetHrYAxis LITERAL1 142 | eGyrIntSetHrZAxis LITERAL1 143 | eGyrIntSetAmFilt LITERAL1 144 | eGyrIntSetHrFilt LITERAL1 145 | eGyrIntSetAll LITERAL1 146 | eGyrIntSet_t LITERAL1 147 | 148 | eStatusOK LITERAL1 149 | eStatusErr LITERAL1 150 | eStatusErrDeviceNotDetect LITERAL1 151 | eStatusErrDeviceReadyTimeOut LITERAL1 152 | eStatusErrDeviceStatus LITERAL1 153 | eStatusErrParameter LITERAL1 154 | eStatus_t LITERAL1 155 | 156 | eCom3Low LITERAL1 157 | eCom3High LITERAL1 158 | eCom3State_t LITERAL1 159 | 160 | DFRobot_BNO055_IIC KEYWORD1 161 | BNO KEYWORD1 162 | lastOperateStatus KEYWORD1 163 | 164 | begin KEYWORD1 165 | getAxis KEYWORD1 166 | getEul KEYWORD1 167 | getQua KEYWORD1 168 | setAxisOffset KEYWORD1 169 | setOprMode KEYWORD1 170 | setPowerMode KEYWORD1 171 | reset KEYWORD1 172 | setAccRange KEYWORD1 173 | setAccBandWidth KEYWORD1 174 | setAccPowerMode KEYWORD1 175 | setMagDataRate KEYWORD1 176 | setMagOprMode KEYWORD1 177 | setMagPowerMode KEYWORD1 178 | setGyrRange KEYWORD1 179 | setGyrBandWidth KEYWORD1 180 | setGyrPowerMode KEYWORD1 181 | getIntState KEYWORD1 182 | setIntMaskEnable KEYWORD1 183 | setIntMaskDisable KEYWORD1 184 | setIntEnable KEYWORD1 185 | setIntDisable KEYWORD1 186 | setAccAmThres KEYWORD1 187 | setAccIntAmDur KEYWORD1 188 | setAccIntEnable KEYWORD1 189 | setAccIntDisable KEYWORD1 190 | setAccHighGDuration KEYWORD1 191 | setAccHighGThres KEYWORD1 192 | setAccNmThres KEYWORD1 193 | setAccNmSet KEYWORD1 194 | setGyrIntEnable KEYWORD1 195 | setGyrIntDisable KEYWORD1 196 | setGyrHrSet KEYWORD1 197 | setGyrAmThres KEYWORD1 --------------------------------------------------------------------------------