diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/Adafruit_BNO055.cpp b/Adafruit_BNO055.cpp index 7273ebc..d83bb72 100644 --- a/Adafruit_BNO055.cpp +++ b/Adafruit_BNO055.cpp @@ -88,7 +88,7 @@ bool Adafruit_BNO055::begin(adafruit_bno055_opmode_t mode) write8(BNO055_PWR_MODE_ADDR, POWER_MODE_NORMAL); delay(10); - write8(BNO055_PAGE_ID_ADDR, 0); + setPage(PAGE_0); /* Set the output units */ /* @@ -117,6 +117,18 @@ bool Adafruit_BNO055::begin(adafruit_bno055_opmode_t mode) return true; } +/**************************************************************************/ +/*! + @brief Puts the chip on the specified register page + */ +/**************************************************************************/ +void Adafruit_BNO055::setPage(adafruit_bno055_page_t page) +{ + _page = page; + write8(BNO055_PAGE_ID_ADDR, _page); + delay(30); +} + /**************************************************************************/ /*! @brief Puts the chip in the specified operating mode @@ -141,7 +153,7 @@ void Adafruit_BNO055::setExtCrystalUse(boolean usextal) /* Switch to config mode (just in case since this is the default) */ setMode(OPERATION_MODE_CONFIG); delay(25); - write8(BNO055_PAGE_ID_ADDR, 0); + setPage(PAGE_0); if (usextal) { write8(BNO055_SYS_TRIGGER_ADDR, 0x80); } else { @@ -153,6 +165,282 @@ void Adafruit_BNO055::setExtCrystalUse(boolean usextal) delay(20); } +/**************************************************************************/ +/*! + @brief Resets all interrupts + */ +/**************************************************************************/ +void Adafruit_BNO055::resetInterrupts() +{ + // Read to get the current settings + int8_t sysTrigger = (int8_t)(read8(BNO055_SYS_TRIGGER_ADDR)); + + // Set the flags as requested + sysTrigger = sliceValueIntoRegister(0x01, sysTrigger, BNO055_SYS_TRIGGER_ADDR_RST_INT_MSK, BNO055_SYS_TRIGGER_ADDR_RST_INT_POS); + + // Write back the entire register + write8(BNO055_SYS_TRIGGER_ADDR, sysTrigger); + delay(30); +} + +/**************************************************************************/ +/*! + @brief Enables the interrupts on specific axes + */ +/**************************************************************************/ +void Adafruit_BNO055::enableInterruptsOnXYZ(uint8_t x, uint8_t y, uint8_t z) +{ + // TODO: this may be a good flow for any config register setting methods, + // so could be worth a look at the those methods for rework + + // Need to be on page 0 to get into config mode + adafruit_bno055_page_t lastPage = _page; + if (lastPage != PAGE_0) setPage(PAGE_0); + + // Must be in config mode, so force it + adafruit_bno055_opmode_t lastMode = _mode; + setMode(OPERATION_MODE_CONFIG); + + // Change to page 1 for interrupt settings + setPage(PAGE_1); + + // Read to get the current settings + int8_t intSettings = (int8_t)(read8(ACC_INT_Settings_ADDR)); + + // Set the flags as requested--binary choice, so set or unset + intSettings = sliceValueIntoRegister(x ? 0x01 : 0x00, intSettings, ACC_INT_Settings_ACC_X_MSK, ACC_INT_Settings_ACC_X_POS); + intSettings = sliceValueIntoRegister(y ? 0x01 : 0x00, intSettings, ACC_INT_Settings_ACC_Y_MSK, ACC_INT_Settings_ACC_Y_POS); + intSettings = sliceValueIntoRegister(z ? 0x01 : 0x00, intSettings, ACC_INT_Settings_ACC_Z_MSK, ACC_INT_Settings_ACC_Z_POS); + + // Write back the entire register + write8(ACC_INT_Settings_ADDR, intSettings); + delay(30); + + // Return the mode to the last mode + setPage(PAGE_0); + setMode(lastMode); + + // Change the page back to whichever it was initially + if (lastPage != PAGE_0) setPage(lastPage); +} + +/**************************************************************************/ +/*! + @brief Enables the the slow/no motion interrupt, specifying settings + */ +/**************************************************************************/ +void Adafruit_BNO055::enableSlowNoMotion(uint8_t threshold, uint8_t duration, uint8_t motionType) +{ + // TODO: this may be a good flow for any config register setting methods, + // so could be worth a look at the those methods for rework + + // Need to be on page 0 to get into config mode + adafruit_bno055_page_t lastPage = _page; + if (lastPage != PAGE_0) setPage(PAGE_0); + + // Must be in config mode, so force it + adafruit_bno055_opmode_t lastMode = _mode; + setMode(OPERATION_MODE_CONFIG); + + // Change to page 1 for interrupt settings + setPage(PAGE_1); + + // Enable which one: slow motion or no motion + // Set duration (bits 1-6), first + int8_t smnmSettings = (int8_t)(read8(ACC_NM_SET_ADDR)); + smnmSettings = sliceValueIntoRegister(motionType, smnmSettings, ACC_NM_SET_SLOWNO_MSK, ACC_NM_SET_SLOWNO_POS); + smnmSettings = sliceValueIntoRegister(duration, smnmSettings, ACC_NM_SET_DUR_MSK, ACC_NM_SET_DUR_POS); + write8(ACC_NM_SET_ADDR, smnmSettings); + + // Set the threshold (full byte) + int8_t threshSettings = (int8_t)(read8(ACC_NM_THRES_ADDR)); + threshSettings = sliceValueIntoRegister(threshold, threshSettings, ACC_NM_THRES_MSK, ACC_NM_THRES_POS); + write8(ACC_NM_THRES_ADDR, threshSettings); + + // Enable the interrupt + setInterruptEnableAccelNM(ENABLE); + + // Fire on the pin + setInterruptMaskAccelNM(ENABLE); + + delay(30); + + // Return the mode to the last mode + setPage(PAGE_0); + setMode(lastMode); + + // Change the page back to whichever it was initially + if (lastPage != PAGE_0) setPage(lastPage); +} + +/**************************************************************************/ +/*! + @brief Disable the the slow/no motion interrupt + */ +/**************************************************************************/ +void Adafruit_BNO055::disableSlowNoMotion() +{ + // TODO: this may be a good flow for any config register setting methods, + // so could be worth a look at the those methods for rework + + // Need to be on page 0 to get into config mode + adafruit_bno055_page_t lastPage = _page; + if (lastPage != PAGE_0) setPage(PAGE_0); + + // Must be in config mode, so force it + adafruit_bno055_opmode_t lastMode = _mode; + setMode(OPERATION_MODE_CONFIG); + + // Change to page 1 for interrupt settings + setPage(PAGE_1); + + // Disable the interrupt + setInterruptEnableAccelNM(DISABLE); + + // Stop firing on the pin + setInterruptMaskAccelNM(DISABLE); + + delay(30); + + // Return the mode to the last mode + setPage(PAGE_0); + setMode(lastMode); + + // Change the page back to whichever it was initially + if (lastPage != PAGE_0) setPage(lastPage); +} + +/**************************************************************************/ +/*! + @brief Enables the the any motion interrupt, specifying settings + */ +/**************************************************************************/ +void Adafruit_BNO055::enableAnyMotion(uint8_t threshold, uint8_t duration) +{ + // TODO: this may be a good flow for any config register setting methods, + // so could be worth a look at the those methods for rework + + // Need to be on page 0 to get into config mode + adafruit_bno055_page_t lastPage = _page; + if (lastPage != PAGE_0) setPage(PAGE_0); + + // Must be in config mode, so force it + adafruit_bno055_opmode_t lastMode = _mode; + setMode(OPERATION_MODE_CONFIG); + + // Change to page 1 for interrupt settings + setPage(PAGE_1); + + // Set duration (bits 1-6) + int8_t intSettings = (int8_t)(read8(ACC_INT_Settings_ADDR)); + intSettings = sliceValueIntoRegister(duration, intSettings, ACC_INT_Settings_AM_DUR_MSK, ACC_INT_Settings_AM_DUR_POS); + write8(ACC_INT_Settings_ADDR, intSettings); + + // Set the threshold (full byte) + int8_t threshSettings = (int8_t)(read8(ACC_AM_THRES_ADDR)); + threshSettings = sliceValueIntoRegister(threshold, threshSettings, ACC_AM_THRES_MSK, ACC_AM_THRES_POS); + write8(ACC_AM_THRES_ADDR, threshSettings); + + // Enable the interrupt + setInterruptEnableAccelAM(ENABLE); + + // Fire on the pin + setInterruptMaskAccelAM(ENABLE); + + delay(30); + + // Return the mode to the last mode + setPage(PAGE_0); + setMode(lastMode); + + // Change the page back to whichever it was initially + if (lastPage != PAGE_0) setPage(lastPage); +} + +/**************************************************************************/ +/*! + @brief Disable the the any motion interrupt + */ +/**************************************************************************/ +void Adafruit_BNO055::disableAnyMotion() +{ + // TODO: this may be a good flow for any config register setting methods, + // so could be worth a look at the those methods for rework + + // Need to be on page 0 to get into config mode + adafruit_bno055_page_t lastPage = _page; + if (lastPage != PAGE_0) setPage(PAGE_0); + + // Must be in config mode, so force it + adafruit_bno055_opmode_t lastMode = _mode; + setMode(OPERATION_MODE_CONFIG); + + // Change to page 1 for interrupt settings + setPage(PAGE_1); + + // Disable the interrupt + setInterruptEnableAccelAM(DISABLE); + + // Stop firing on the pin + setInterruptMaskAccelAM(DISABLE); + + delay(30); + + // Return the mode to the last mode + setPage(PAGE_0); + setMode(lastMode); + + // Change the page back to whichever it was initially + if (lastPage != PAGE_0) setPage(lastPage); +} + +/**************************************************************************/ +/*! + @brief Enable or disable the slow/no motion interrupt entirely + */ +/**************************************************************************/ +// WARNING: ONLY CALL INSIDE PAGE/CONFIG WRAPPER +void Adafruit_BNO055::setInterruptEnableAccelNM(uint8_t enable) { + int8_t intEnable = (int8_t)(read8(INT_EN_ADDR)); + intEnable = sliceValueIntoRegister(enable, intEnable, INT_EN_ACC_NM_MSK, INT_EN_ACC_NM_POS); + write8(INT_EN_ADDR, intEnable); +} + +/**************************************************************************/ +/*! + @brief Tell slow/no interrupt to set pin and output or just set the output + */ +/**************************************************************************/ +// WARNING: ONLY CALL INSIDE PAGE/CONFIG WRAPPER +void Adafruit_BNO055::setInterruptMaskAccelNM(uint8_t enable) { + int8_t intMask = (int8_t)(read8(INT_MSK_ADDR)); + intMask = sliceValueIntoRegister(enable, intMask, INT_MSK_ACC_NM_MSK, INT_MSK_ACC_NM_POS); + write8(INT_MSK_ADDR, intMask); +} + +/**************************************************************************/ +/*! + @brief Enable or disable the any motion interrupt entirely + */ +/**************************************************************************/ +// WARNING: ONLY CALL INSIDE PAGE/CONFIG WRAPPER +void Adafruit_BNO055::setInterruptEnableAccelAM(uint8_t enable) { + int8_t intEnable = (int8_t)(read8(INT_EN_ADDR)); + intEnable = sliceValueIntoRegister(enable, intEnable, INT_EN_ACC_AM_MSK, INT_EN_ACC_AM_POS); + write8(INT_EN_ADDR, intEnable); +} + +/**************************************************************************/ +/*! + @brief Tell any motion interrupt to set pin and output or just set the output + */ +/**************************************************************************/ +// WARNING: ONLY CALL INSIDE PAGE/CONFIG WRAPPER +void Adafruit_BNO055::setInterruptMaskAccelAM(uint8_t enable) { + int8_t intMask = (int8_t)(read8(INT_MSK_ADDR)); + intMask = sliceValueIntoRegister(enable, intMask, INT_MSK_ACC_AM_MSK, INT_MSK_ACC_AM_POS); + write8(INT_MSK_ADDR, intMask); +} /**************************************************************************/ /*! @@ -161,7 +449,7 @@ void Adafruit_BNO055::setExtCrystalUse(boolean usextal) /**************************************************************************/ void Adafruit_BNO055::getSystemStatus(uint8_t *system_status, uint8_t *self_test_result, uint8_t *system_error) { - write8(BNO055_PAGE_ID_ADDR, 0); + setPage(PAGE_0); /* System Status (see section 4.3.58) --------------------------------- @@ -570,7 +858,8 @@ bool Adafruit_BNO055::write8(adafruit_bno055_reg_t reg, byte value) Wire.send(value); #endif Wire.endTransmission(); - + delayMicroseconds(150); + /* ToDo: Check for error! */ return true; } @@ -629,3 +918,13 @@ bool Adafruit_BNO055::readLen(adafruit_bno055_reg_t reg, byte * buffer, uint8_t /* ToDo: Check for errors! */ return true; } + +/**************************************************************************/ +/*! + @brief Sets the value of the partial (or full) register + */ +/**************************************************************************/ +uint8_t Adafruit_BNO055::sliceValueIntoRegister(uint8_t value, uint8_t reg, uint8_t mask, uint8_t position) { + return (reg & ~mask) | ((value << position) & mask); +} + diff --git a/Adafruit_BNO055.h b/Adafruit_BNO055.h index 36ba836..e0363ab 100644 --- a/Adafruit_BNO055.h +++ b/Adafruit_BNO055.h @@ -1,36 +1,36 @@ /*************************************************************************** - This is a library for the BNO055 orientation sensor - - Designed specifically to work with the Adafruit BNO055 Breakout. - - Pick one up today in the adafruit shop! - ------> http://www.adafruit.com/products - - These sensors use I2C to communicate, 2 pins are required to interface. - - Adafruit invests time and resources providing this open source code, - please support Adafruit andopen-source hardware by purchasing products - from Adafruit! - - Written by KTOWN for Adafruit Industries. - - MIT license, all text above must be included in any redistribution + This is a library for the BNO055 orientation sensor + + Designed specifically to work with the Adafruit BNO055 Breakout. + + Pick one up today in the adafruit shop! + ------> http://www.adafruit.com/products + + These sensors use I2C to communicate, 2 pins are required to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit andopen-source hardware by purchasing products + from Adafruit! + + Written by KTOWN for Adafruit Industries. + + MIT license, all text above must be included in any redistribution ***************************************************************************/ #ifndef __ADAFRUIT_BNO055_H__ #define __ADAFRUIT_BNO055_H__ #if (ARDUINO >= 100) - #include "Arduino.h" +#include "Arduino.h" #else - #include "WProgram.h" +#include "WProgram.h" #endif #ifdef __AVR_ATtiny85__ - #include - #define Wire TinyWireM +#include +#define Wire TinyWireM #else - #include +#include #endif #include @@ -40,6 +40,14 @@ #define BNO055_ADDRESS_B (0x29) #define BNO055_ID (0xA0) +// For register flags +#define ENABLE 1 +#define DISABLE 0 + +// For slo/no motion interrupt flag +#define NO_MOTION 1 +#define SLOW_MOTION 0 + #define NUM_BNO055_OFFSET_REGISTERS (22) typedef struct @@ -53,232 +61,284 @@ typedef struct uint16_t mag_offset_x; uint16_t mag_offset_y; uint16_t mag_offset_z; - + uint16_t accel_radius; uint16_t mag_radius; } adafruit_bno055_offsets_t; class Adafruit_BNO055 : public Adafruit_Sensor { - public: +public: typedef enum { - /* Page id register definition */ - BNO055_PAGE_ID_ADDR = 0X07, - - /* PAGE0 REGISTER DEFINITION START*/ - BNO055_CHIP_ID_ADDR = 0x00, - BNO055_ACCEL_REV_ID_ADDR = 0x01, - BNO055_MAG_REV_ID_ADDR = 0x02, - BNO055_GYRO_REV_ID_ADDR = 0x03, - BNO055_SW_REV_ID_LSB_ADDR = 0x04, - BNO055_SW_REV_ID_MSB_ADDR = 0x05, - BNO055_BL_REV_ID_ADDR = 0X06, - - /* Accel data register */ - BNO055_ACCEL_DATA_X_LSB_ADDR = 0X08, - BNO055_ACCEL_DATA_X_MSB_ADDR = 0X09, - BNO055_ACCEL_DATA_Y_LSB_ADDR = 0X0A, - BNO055_ACCEL_DATA_Y_MSB_ADDR = 0X0B, - BNO055_ACCEL_DATA_Z_LSB_ADDR = 0X0C, - BNO055_ACCEL_DATA_Z_MSB_ADDR = 0X0D, - - /* Mag data register */ - BNO055_MAG_DATA_X_LSB_ADDR = 0X0E, - BNO055_MAG_DATA_X_MSB_ADDR = 0X0F, - BNO055_MAG_DATA_Y_LSB_ADDR = 0X10, - BNO055_MAG_DATA_Y_MSB_ADDR = 0X11, - BNO055_MAG_DATA_Z_LSB_ADDR = 0X12, - BNO055_MAG_DATA_Z_MSB_ADDR = 0X13, - - /* Gyro data registers */ - BNO055_GYRO_DATA_X_LSB_ADDR = 0X14, - BNO055_GYRO_DATA_X_MSB_ADDR = 0X15, - BNO055_GYRO_DATA_Y_LSB_ADDR = 0X16, - BNO055_GYRO_DATA_Y_MSB_ADDR = 0X17, - BNO055_GYRO_DATA_Z_LSB_ADDR = 0X18, - BNO055_GYRO_DATA_Z_MSB_ADDR = 0X19, - - /* Euler data registers */ - BNO055_EULER_H_LSB_ADDR = 0X1A, - BNO055_EULER_H_MSB_ADDR = 0X1B, - BNO055_EULER_R_LSB_ADDR = 0X1C, - BNO055_EULER_R_MSB_ADDR = 0X1D, - BNO055_EULER_P_LSB_ADDR = 0X1E, - BNO055_EULER_P_MSB_ADDR = 0X1F, - - /* Quaternion data registers */ - BNO055_QUATERNION_DATA_W_LSB_ADDR = 0X20, - BNO055_QUATERNION_DATA_W_MSB_ADDR = 0X21, - BNO055_QUATERNION_DATA_X_LSB_ADDR = 0X22, - BNO055_QUATERNION_DATA_X_MSB_ADDR = 0X23, - BNO055_QUATERNION_DATA_Y_LSB_ADDR = 0X24, - BNO055_QUATERNION_DATA_Y_MSB_ADDR = 0X25, - BNO055_QUATERNION_DATA_Z_LSB_ADDR = 0X26, - BNO055_QUATERNION_DATA_Z_MSB_ADDR = 0X27, - - /* Linear acceleration data registers */ - BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR = 0X28, - BNO055_LINEAR_ACCEL_DATA_X_MSB_ADDR = 0X29, - BNO055_LINEAR_ACCEL_DATA_Y_LSB_ADDR = 0X2A, - BNO055_LINEAR_ACCEL_DATA_Y_MSB_ADDR = 0X2B, - BNO055_LINEAR_ACCEL_DATA_Z_LSB_ADDR = 0X2C, - BNO055_LINEAR_ACCEL_DATA_Z_MSB_ADDR = 0X2D, - - /* Gravity data registers */ - BNO055_GRAVITY_DATA_X_LSB_ADDR = 0X2E, - BNO055_GRAVITY_DATA_X_MSB_ADDR = 0X2F, - BNO055_GRAVITY_DATA_Y_LSB_ADDR = 0X30, - BNO055_GRAVITY_DATA_Y_MSB_ADDR = 0X31, - BNO055_GRAVITY_DATA_Z_LSB_ADDR = 0X32, - BNO055_GRAVITY_DATA_Z_MSB_ADDR = 0X33, - - /* Temperature data register */ - BNO055_TEMP_ADDR = 0X34, - - /* Status registers */ - BNO055_CALIB_STAT_ADDR = 0X35, - BNO055_SELFTEST_RESULT_ADDR = 0X36, - BNO055_INTR_STAT_ADDR = 0X37, - - BNO055_SYS_CLK_STAT_ADDR = 0X38, - BNO055_SYS_STAT_ADDR = 0X39, - BNO055_SYS_ERR_ADDR = 0X3A, - - /* Unit selection register */ - BNO055_UNIT_SEL_ADDR = 0X3B, - BNO055_DATA_SELECT_ADDR = 0X3C, - - /* Mode registers */ - BNO055_OPR_MODE_ADDR = 0X3D, - BNO055_PWR_MODE_ADDR = 0X3E, - - BNO055_SYS_TRIGGER_ADDR = 0X3F, - BNO055_TEMP_SOURCE_ADDR = 0X40, - - /* Axis remap registers */ - BNO055_AXIS_MAP_CONFIG_ADDR = 0X41, - BNO055_AXIS_MAP_SIGN_ADDR = 0X42, - - /* SIC registers */ - BNO055_SIC_MATRIX_0_LSB_ADDR = 0X43, - BNO055_SIC_MATRIX_0_MSB_ADDR = 0X44, - BNO055_SIC_MATRIX_1_LSB_ADDR = 0X45, - BNO055_SIC_MATRIX_1_MSB_ADDR = 0X46, - BNO055_SIC_MATRIX_2_LSB_ADDR = 0X47, - BNO055_SIC_MATRIX_2_MSB_ADDR = 0X48, - BNO055_SIC_MATRIX_3_LSB_ADDR = 0X49, - BNO055_SIC_MATRIX_3_MSB_ADDR = 0X4A, - BNO055_SIC_MATRIX_4_LSB_ADDR = 0X4B, - BNO055_SIC_MATRIX_4_MSB_ADDR = 0X4C, - BNO055_SIC_MATRIX_5_LSB_ADDR = 0X4D, - BNO055_SIC_MATRIX_5_MSB_ADDR = 0X4E, - BNO055_SIC_MATRIX_6_LSB_ADDR = 0X4F, - BNO055_SIC_MATRIX_6_MSB_ADDR = 0X50, - BNO055_SIC_MATRIX_7_LSB_ADDR = 0X51, - BNO055_SIC_MATRIX_7_MSB_ADDR = 0X52, - BNO055_SIC_MATRIX_8_LSB_ADDR = 0X53, - BNO055_SIC_MATRIX_8_MSB_ADDR = 0X54, - - /* Accelerometer Offset registers */ - ACCEL_OFFSET_X_LSB_ADDR = 0X55, - ACCEL_OFFSET_X_MSB_ADDR = 0X56, - ACCEL_OFFSET_Y_LSB_ADDR = 0X57, - ACCEL_OFFSET_Y_MSB_ADDR = 0X58, - ACCEL_OFFSET_Z_LSB_ADDR = 0X59, - ACCEL_OFFSET_Z_MSB_ADDR = 0X5A, - - /* Magnetometer Offset registers */ - MAG_OFFSET_X_LSB_ADDR = 0X5B, - MAG_OFFSET_X_MSB_ADDR = 0X5C, - MAG_OFFSET_Y_LSB_ADDR = 0X5D, - MAG_OFFSET_Y_MSB_ADDR = 0X5E, - MAG_OFFSET_Z_LSB_ADDR = 0X5F, - MAG_OFFSET_Z_MSB_ADDR = 0X60, - - /* Gyroscope Offset register s*/ - GYRO_OFFSET_X_LSB_ADDR = 0X61, - GYRO_OFFSET_X_MSB_ADDR = 0X62, - GYRO_OFFSET_Y_LSB_ADDR = 0X63, - GYRO_OFFSET_Y_MSB_ADDR = 0X64, - GYRO_OFFSET_Z_LSB_ADDR = 0X65, - GYRO_OFFSET_Z_MSB_ADDR = 0X66, - - /* Radius registers */ - ACCEL_RADIUS_LSB_ADDR = 0X67, - ACCEL_RADIUS_MSB_ADDR = 0X68, - MAG_RADIUS_LSB_ADDR = 0X69, - MAG_RADIUS_MSB_ADDR = 0X6A + /* Page id register definition */ + BNO055_PAGE_ID_ADDR = 0X07, + + /* PAGE0 REGISTER DEFINITION START*/ + BNO055_CHIP_ID_ADDR = 0x00, + BNO055_ACCEL_REV_ID_ADDR = 0x01, + BNO055_MAG_REV_ID_ADDR = 0x02, + BNO055_GYRO_REV_ID_ADDR = 0x03, + BNO055_SW_REV_ID_LSB_ADDR = 0x04, + BNO055_SW_REV_ID_MSB_ADDR = 0x05, + BNO055_BL_REV_ID_ADDR = 0X06, + + /* Accel data register */ + BNO055_ACCEL_DATA_X_LSB_ADDR = 0X08, + BNO055_ACCEL_DATA_X_MSB_ADDR = 0X09, + BNO055_ACCEL_DATA_Y_LSB_ADDR = 0X0A, + BNO055_ACCEL_DATA_Y_MSB_ADDR = 0X0B, + BNO055_ACCEL_DATA_Z_LSB_ADDR = 0X0C, + BNO055_ACCEL_DATA_Z_MSB_ADDR = 0X0D, + + /* Mag data register */ + BNO055_MAG_DATA_X_LSB_ADDR = 0X0E, + BNO055_MAG_DATA_X_MSB_ADDR = 0X0F, + BNO055_MAG_DATA_Y_LSB_ADDR = 0X10, + BNO055_MAG_DATA_Y_MSB_ADDR = 0X11, + BNO055_MAG_DATA_Z_LSB_ADDR = 0X12, + BNO055_MAG_DATA_Z_MSB_ADDR = 0X13, + + /* Gyro data registers */ + BNO055_GYRO_DATA_X_LSB_ADDR = 0X14, + BNO055_GYRO_DATA_X_MSB_ADDR = 0X15, + BNO055_GYRO_DATA_Y_LSB_ADDR = 0X16, + BNO055_GYRO_DATA_Y_MSB_ADDR = 0X17, + BNO055_GYRO_DATA_Z_LSB_ADDR = 0X18, + BNO055_GYRO_DATA_Z_MSB_ADDR = 0X19, + + /* Euler data registers */ + BNO055_EULER_H_LSB_ADDR = 0X1A, + BNO055_EULER_H_MSB_ADDR = 0X1B, + BNO055_EULER_R_LSB_ADDR = 0X1C, + BNO055_EULER_R_MSB_ADDR = 0X1D, + BNO055_EULER_P_LSB_ADDR = 0X1E, + BNO055_EULER_P_MSB_ADDR = 0X1F, + + /* Quaternion data registers */ + BNO055_QUATERNION_DATA_W_LSB_ADDR = 0X20, + BNO055_QUATERNION_DATA_W_MSB_ADDR = 0X21, + BNO055_QUATERNION_DATA_X_LSB_ADDR = 0X22, + BNO055_QUATERNION_DATA_X_MSB_ADDR = 0X23, + BNO055_QUATERNION_DATA_Y_LSB_ADDR = 0X24, + BNO055_QUATERNION_DATA_Y_MSB_ADDR = 0X25, + BNO055_QUATERNION_DATA_Z_LSB_ADDR = 0X26, + BNO055_QUATERNION_DATA_Z_MSB_ADDR = 0X27, + + /* Linear acceleration data registers */ + BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR = 0X28, + BNO055_LINEAR_ACCEL_DATA_X_MSB_ADDR = 0X29, + BNO055_LINEAR_ACCEL_DATA_Y_LSB_ADDR = 0X2A, + BNO055_LINEAR_ACCEL_DATA_Y_MSB_ADDR = 0X2B, + BNO055_LINEAR_ACCEL_DATA_Z_LSB_ADDR = 0X2C, + BNO055_LINEAR_ACCEL_DATA_Z_MSB_ADDR = 0X2D, + + /* Gravity data registers */ + BNO055_GRAVITY_DATA_X_LSB_ADDR = 0X2E, + BNO055_GRAVITY_DATA_X_MSB_ADDR = 0X2F, + BNO055_GRAVITY_DATA_Y_LSB_ADDR = 0X30, + BNO055_GRAVITY_DATA_Y_MSB_ADDR = 0X31, + BNO055_GRAVITY_DATA_Z_LSB_ADDR = 0X32, + BNO055_GRAVITY_DATA_Z_MSB_ADDR = 0X33, + + /* Temperature data register */ + BNO055_TEMP_ADDR = 0X34, + + /* Status registers */ + BNO055_CALIB_STAT_ADDR = 0X35, + BNO055_SELFTEST_RESULT_ADDR = 0X36, + BNO055_INTR_STAT_ADDR = 0X37, + + BNO055_SYS_CLK_STAT_ADDR = 0X38, + BNO055_SYS_STAT_ADDR = 0X39, + BNO055_SYS_ERR_ADDR = 0X3A, + + /* Unit selection register */ + BNO055_UNIT_SEL_ADDR = 0X3B, + BNO055_DATA_SELECT_ADDR = 0X3C, + + /* Mode registers */ + BNO055_OPR_MODE_ADDR = 0X3D, + BNO055_PWR_MODE_ADDR = 0X3E, + + BNO055_SYS_TRIGGER_ADDR = 0X3F, + BNO055_SYS_TRIGGER_ADDR_RST_INT_MSK = 0X40, + BNO055_SYS_TRIGGER_ADDR_RST_INT_POS = 6, + BNO055_TEMP_SOURCE_ADDR = 0X40, + + /* Axis remap registers */ + BNO055_AXIS_MAP_CONFIG_ADDR = 0X41, + BNO055_AXIS_MAP_SIGN_ADDR = 0X42, + + /* SIC registers */ + BNO055_SIC_MATRIX_0_LSB_ADDR = 0X43, + BNO055_SIC_MATRIX_0_MSB_ADDR = 0X44, + BNO055_SIC_MATRIX_1_LSB_ADDR = 0X45, + BNO055_SIC_MATRIX_1_MSB_ADDR = 0X46, + BNO055_SIC_MATRIX_2_LSB_ADDR = 0X47, + BNO055_SIC_MATRIX_2_MSB_ADDR = 0X48, + BNO055_SIC_MATRIX_3_LSB_ADDR = 0X49, + BNO055_SIC_MATRIX_3_MSB_ADDR = 0X4A, + BNO055_SIC_MATRIX_4_LSB_ADDR = 0X4B, + BNO055_SIC_MATRIX_4_MSB_ADDR = 0X4C, + BNO055_SIC_MATRIX_5_LSB_ADDR = 0X4D, + BNO055_SIC_MATRIX_5_MSB_ADDR = 0X4E, + BNO055_SIC_MATRIX_6_LSB_ADDR = 0X4F, + BNO055_SIC_MATRIX_6_MSB_ADDR = 0X50, + BNO055_SIC_MATRIX_7_LSB_ADDR = 0X51, + BNO055_SIC_MATRIX_7_MSB_ADDR = 0X52, + BNO055_SIC_MATRIX_8_LSB_ADDR = 0X53, + BNO055_SIC_MATRIX_8_MSB_ADDR = 0X54, + + /* Accelerometer Offset registers */ + ACCEL_OFFSET_X_LSB_ADDR = 0X55, + ACCEL_OFFSET_X_MSB_ADDR = 0X56, + ACCEL_OFFSET_Y_LSB_ADDR = 0X57, + ACCEL_OFFSET_Y_MSB_ADDR = 0X58, + ACCEL_OFFSET_Z_LSB_ADDR = 0X59, + ACCEL_OFFSET_Z_MSB_ADDR = 0X5A, + + /* Magnetometer Offset registers */ + MAG_OFFSET_X_LSB_ADDR = 0X5B, + MAG_OFFSET_X_MSB_ADDR = 0X5C, + MAG_OFFSET_Y_LSB_ADDR = 0X5D, + MAG_OFFSET_Y_MSB_ADDR = 0X5E, + MAG_OFFSET_Z_LSB_ADDR = 0X5F, + MAG_OFFSET_Z_MSB_ADDR = 0X60, + + /* Gyroscope Offset register s*/ + GYRO_OFFSET_X_LSB_ADDR = 0X61, + GYRO_OFFSET_X_MSB_ADDR = 0X62, + GYRO_OFFSET_Y_LSB_ADDR = 0X63, + GYRO_OFFSET_Y_MSB_ADDR = 0X64, + GYRO_OFFSET_Z_LSB_ADDR = 0X65, + GYRO_OFFSET_Z_MSB_ADDR = 0X66, + + /* Radius registers */ + ACCEL_RADIUS_LSB_ADDR = 0X67, + ACCEL_RADIUS_MSB_ADDR = 0X68, + MAG_RADIUS_LSB_ADDR = 0X69, + MAG_RADIUS_MSB_ADDR = 0X6A, + + /* PAGE1 REGISTER DEFINITION START*/ + /* Interrupt mask register */ + INT_MSK_ADDR = 0X0F, + INT_MSK_ACC_NM_MSK = 0X80, + INT_MSK_ACC_NM_POS = 7, + INT_MSK_ACC_AM_MSK = 0X40, + INT_MSK_ACC_AM_POS = 6, + + /* Interrupt enabled register */ + INT_EN_ADDR = 0X10, + INT_EN_ACC_NM_MSK = 0X80, + INT_EN_ACC_NM_POS = 7, + INT_EN_ACC_AM_MSK = 0X40, + INT_EN_ACC_AM_POS = 6, + + /* Any Motion interrupt threshold register */ + ACC_AM_THRES_ADDR = 0X11, + ACC_AM_THRES_MSK = 0XFF, + ACC_AM_THRES_POS = 0, + + /* Acceleration interrupt settings register */ + ACC_INT_Settings_ADDR = 0X12, + ACC_INT_Settings_ACC_X_MSK = 0X04, + ACC_INT_Settings_ACC_X_POS = 2, + ACC_INT_Settings_ACC_Y_MSK = 0X08, + ACC_INT_Settings_ACC_Y_POS = 3, + ACC_INT_Settings_ACC_Z_MSK = 0X10, + ACC_INT_Settings_ACC_Z_POS = 4, + ACC_INT_Settings_AM_DUR_MSK = 0x03, + ACC_INT_Settings_AM_DUR_POS = 0, + + /* Slo/no motion interrupt threshold register */ + ACC_NM_THRES_ADDR = 0X15, + ACC_NM_THRES_MSK = 0XFF, + ACC_NM_THRES_POS = 0, + + /* Acceleration slo/mo interrupt settings register */ + ACC_NM_SET_ADDR = 0X16, + ACC_NM_SET_SLOWNO_MSK = 0x01, + ACC_NM_SET_SLOWNO_POS = 0, + ACC_NM_SET_DUR_MSK = 0x7E, + ACC_NM_SET_DUR_POS = 1 } adafruit_bno055_reg_t; - + typedef enum { - POWER_MODE_NORMAL = 0X00, - POWER_MODE_LOWPOWER = 0X01, - POWER_MODE_SUSPEND = 0X02 + POWER_MODE_NORMAL = 0X00, + POWER_MODE_LOWPOWER = 0X01, + POWER_MODE_SUSPEND = 0X02 } adafruit_bno055_powermode_t; - + typedef enum { - /* Operation mode settings*/ - OPERATION_MODE_CONFIG = 0X00, - OPERATION_MODE_ACCONLY = 0X01, - OPERATION_MODE_MAGONLY = 0X02, - OPERATION_MODE_GYRONLY = 0X03, - OPERATION_MODE_ACCMAG = 0X04, - OPERATION_MODE_ACCGYRO = 0X05, - OPERATION_MODE_MAGGYRO = 0X06, - OPERATION_MODE_AMG = 0X07, - OPERATION_MODE_IMUPLUS = 0X08, - OPERATION_MODE_COMPASS = 0X09, - OPERATION_MODE_M4G = 0X0A, - OPERATION_MODE_NDOF_FMC_OFF = 0X0B, - OPERATION_MODE_NDOF = 0X0C + /* Operation mode settings*/ + PAGE_0 = 0X00, + PAGE_1 = 0X01 + } adafruit_bno055_page_t; + + typedef enum + { + /* Operation mode settings*/ + OPERATION_MODE_CONFIG = 0X00, + OPERATION_MODE_ACCONLY = 0X01, + OPERATION_MODE_MAGONLY = 0X02, + OPERATION_MODE_GYRONLY = 0X03, + OPERATION_MODE_ACCMAG = 0X04, + OPERATION_MODE_ACCGYRO = 0X05, + OPERATION_MODE_MAGGYRO = 0X06, + OPERATION_MODE_AMG = 0X07, + OPERATION_MODE_IMUPLUS = 0X08, + OPERATION_MODE_COMPASS = 0X09, + OPERATION_MODE_M4G = 0X0A, + OPERATION_MODE_NDOF_FMC_OFF = 0X0B, + OPERATION_MODE_NDOF = 0X0C } adafruit_bno055_opmode_t; - + typedef enum { - REMAP_CONFIG_P0 = 0x21, - REMAP_CONFIG_P1 = 0x24, // default - REMAP_CONFIG_P2 = 0x24, - REMAP_CONFIG_P3 = 0x21, - REMAP_CONFIG_P4 = 0x24, - REMAP_CONFIG_P5 = 0x21, - REMAP_CONFIG_P6 = 0x21, - REMAP_CONFIG_P7 = 0x24 + REMAP_CONFIG_P0 = 0x21, + REMAP_CONFIG_P1 = 0x24, // default + REMAP_CONFIG_P2 = 0x24, + REMAP_CONFIG_P3 = 0x21, + REMAP_CONFIG_P4 = 0x24, + REMAP_CONFIG_P5 = 0x21, + REMAP_CONFIG_P6 = 0x21, + REMAP_CONFIG_P7 = 0x24 } adafruit_bno055_axis_remap_config_t; - + typedef enum { - REMAP_SIGN_P0 = 0x04, - REMAP_SIGN_P1 = 0x00, // default - REMAP_SIGN_P2 = 0x06, - REMAP_SIGN_P3 = 0x02, - REMAP_SIGN_P4 = 0x03, - REMAP_SIGN_P5 = 0x01, - REMAP_SIGN_P6 = 0x07, - REMAP_SIGN_P7 = 0x05 + REMAP_SIGN_P0 = 0x04, + REMAP_SIGN_P1 = 0x00, // default + REMAP_SIGN_P2 = 0x06, + REMAP_SIGN_P3 = 0x02, + REMAP_SIGN_P4 = 0x03, + REMAP_SIGN_P5 = 0x01, + REMAP_SIGN_P6 = 0x07, + REMAP_SIGN_P7 = 0x05 } adafruit_bno055_axis_remap_sign_t; - + typedef struct { - uint8_t accel_rev; - uint8_t mag_rev; - uint8_t gyro_rev; - uint16_t sw_rev; - uint8_t bl_rev; + uint8_t accel_rev; + uint8_t mag_rev; + uint8_t gyro_rev; + uint16_t sw_rev; + uint8_t bl_rev; } adafruit_bno055_rev_info_t; - + typedef enum { - VECTOR_ACCELEROMETER = BNO055_ACCEL_DATA_X_LSB_ADDR, - VECTOR_MAGNETOMETER = BNO055_MAG_DATA_X_LSB_ADDR, - VECTOR_GYROSCOPE = BNO055_GYRO_DATA_X_LSB_ADDR, - VECTOR_EULER = BNO055_EULER_H_LSB_ADDR, - VECTOR_LINEARACCEL = BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR, - VECTOR_GRAVITY = BNO055_GRAVITY_DATA_X_LSB_ADDR + VECTOR_ACCELEROMETER = BNO055_ACCEL_DATA_X_LSB_ADDR, + VECTOR_MAGNETOMETER = BNO055_MAG_DATA_X_LSB_ADDR, + VECTOR_GYROSCOPE = BNO055_GYRO_DATA_X_LSB_ADDR, + VECTOR_EULER = BNO055_EULER_H_LSB_ADDR, + VECTOR_LINEARACCEL = BNO055_LINEAR_ACCEL_DATA_X_LSB_ADDR, + VECTOR_GRAVITY = BNO055_GRAVITY_DATA_X_LSB_ADDR } adafruit_vector_type_t; - + #if defined (ARDUINO_SAMD_ZERO) && ! (ARDUINO_SAMD_FEATHER_M0) #error "On an arduino Zero, BNO055's ADR pin must be high. Fix that, then delete this line." Adafruit_BNO055 ( int32_t sensorID = -1, uint8_t address = BNO055_ADDRESS_B ); @@ -291,34 +351,56 @@ class Adafruit_BNO055 : public Adafruit_Sensor void displayRevInfo ( void ); void setExtCrystalUse ( boolean usextal ); void getSystemStatus ( uint8_t *system_status, - uint8_t *self_test_result, - uint8_t *system_error); + uint8_t *self_test_result, + uint8_t *system_error); void displaySystemStatus ( void ); void getCalibration ( uint8_t* system, uint8_t* gyro, uint8_t* accel, uint8_t* mag); - + imu::Vector<3> getVector ( adafruit_vector_type_t vector_type ); imu::Quaternion getQuat ( void ); int8_t getTemp ( void ); - + /* Adafruit_Sensor implementation */ bool getEvent ( sensors_event_t* ); void getSensor ( sensor_t* ); - + /* Functions to deal with raw calibration data */ bool getSensorOffsets(uint8_t* calibData); bool getSensorOffsets(adafruit_bno055_offsets_t &offsets_type); void setSensorOffsets(const uint8_t* calibData); void setSensorOffsets(const adafruit_bno055_offsets_t &offsets_type); bool isFullyCalibrated(void); - - private: + + /* Interrupt Methods */ + void resetInterrupts(); + void enableInterruptsOnXYZ(uint8_t x, uint8_t y, uint8_t z); + void enableSlowNoMotion(uint8_t threshold, uint8_t duration, uint8_t motionType); + void disableSlowNoMotion(); + void enableAnyMotion(uint8_t threshold, uint8_t duration); + void disableAnyMotion(); + +private: + /* Acceleration Interrupt management methods */ + void setInterruptEnableAccelNM(uint8_t enable); + void setInterruptMaskAccelNM(uint8_t enable); + void setInterruptEnableAccelAM(uint8_t enable); + void setInterruptMaskAccelAM(uint8_t enable); + + /* Change the register page */ + void setPage(adafruit_bno055_page_t page); + + /* Read and write to the registers */ byte read8 ( adafruit_bno055_reg_t ); bool readLen ( adafruit_bno055_reg_t, byte* buffer, uint8_t len ); bool write8 ( adafruit_bno055_reg_t, byte value ); + + /* Set bitwise values in the registers */ + uint8_t sliceValueIntoRegister(uint8_t value, uint8_t reg, uint8_t mask, uint8_t position); uint8_t _address; int32_t _sensorID; adafruit_bno055_opmode_t _mode; + adafruit_bno055_page_t _page; }; #endif