简介

BNO055是实现智能9轴绝对定向的新型传感器IC,它将整个传感器系统级封装在一起,集成了三轴14位加速度计,三轴16位陀螺仪,三轴地磁传感器和一个自带算法处理的32位微控制器。它的尺寸仅为5.2 x 3.8 x 1.1mm³,明显小于同类离散或系统板载解决方案。是目前最小尺寸支持Windows 8.1的Sensor-hub产品。它既可单独提供三类传感器(加速度/地磁/陀螺仪)的单一数据,亦可提供组合数据,例如欧拉向量绝对方位、四元素绝对方位。通过内置MCU计算,省略了繁琐的算法处理,为智能手机、穿戴设备等产品提供更多方面的应用支持。

特性

  • 传感器混合数据输出:四元素、欧拉角、旋转矢量、线性加速度、重力、朝向
    • 集成三个传感器:
      • 16位陀螺仪
      • 14位加速度
      • 地磁传感器
    • 智能电源管理系统:正常、低功耗、睡眠

技术规格

  • 工作电压:3.3V-5.5V
  • BNO055加速度:
  • 加速度:±2g/±4g/±8g/±16
  • 低通滤波频段:1kHz~<8Hz
  • 工作模式:正常、睡眠、低功耗、待机、深度睡
  • BNO055陀螺仪:
    • 加速度:±2g/±4g/±8g/±16
    • 低通滤波频段:1kHz~<8Hz
    • 工作模式:正常、睡眠、低功耗、待机、深度睡
  • BNO055陀螺仪:
  • 范围:±125°/s~2000°/s
  • 低通滤波频段:523Hz~12Hz
  • 工作模式:正常,快速启动、深度睡眠、睡眠、高级省电
  • 芯片中断控制:运动触发中断信号
  • BNO055地磁:
  • 范围:±1300uT(x-,y-axis);±2500uT(z-axis)
  • 地磁分辨率:~0.3
  • 工作模式:低功耗、定期、增强定期、高精度
  • 工作模式:正常、睡眠、强制
  • 外形尺寸:19mm x 21mm
  • 安装孔位置:16mm
  • 安装孔尺寸:内径2mm/外径3.7mm

注意:该传感器默认I2C地址为0X28。

引脚说明

BNO055气压温度传感器正面引脚说明

BNO055气压温度传感器背面引脚说明

丝印 功能描述
VCC 电源正极
GND 电源负极
SCL I2C时钟
SDA I2C数据
INT 中断引脚
BOOT 引导模式选择引脚
PS1 协议选择引脚1
PS2 协议选择引脚2
BL-IND 引导程序指示
RST 复位引脚
ADDR I2C地址选择
PS1 PS2 Functionalit
0 0 Standard/Fast 12C Interface
0 1 HID OVER I2C
1 0 UART Interface
1 1 Reserved

注意:该传感器PS1、SP2默认设置为0、0

API接口函数


class DFRobot_BNO055 {

public:
  /**
   * @功能 全局轴枚举定义(可以在操作的时候区分操作的哪个轴的数据,四元数和欧拉角的枚举除外)
   */
  typedef enum {
    eAxisAcc,
    eAxisMag,
    eAxisGyr,
    eAxisLia,
    eAxisGrv
  } eAxis_t;

  /**
   * @功能 全局单轴枚举定义(可以在操作的时候区分操作哪个单轴)
   */
  typedef enum {
    eSingleAxisX,
    eSingleAxisY,
    eSingleAxisZ
  } eSingleAxis_t;

  /**
   * @功能 枚举中断类型
   */
  typedef enum {
    eIntGyrAm = 0x04,
    eIntGyrHighRate = 0x08,
    eIntAccHighG = 0x20,
    eIntAccAm = 0x40,
    eIntAccNm = 0x80,
    eIntAll = 0xec
  } eInt_t;

  /**
   * @功能 枚举操作模式
   */
  typedef enum {
    eOprModeConfig,
    eOprModeAccOnly,
    eOprModeMagOnly,
    eOprModeGyroOnly,
    eOprModeAccMag,
    eOprModeAccGyro,
    eOprModeMagGyro,
    eOprModeAMG,
    eOprModeImu,
    eOprModeCompass,
    eOprModeM4G,
    eOprModeNdofFmcOff,
    eOprModeNdof
  } eOprMode_t;

  /**
   * @功能 枚举电源模式
   */
  typedef enum {
    ePowerModeNormal,
    ePowerModeLowPower,
    ePowerModeSuspend
  } ePowerMode_t;

  /**
   * @功能 轴模拟量数据结构体
   */
  typedef struct {
    float   x, y, z;
  } sAxisAnalog_t;

  /**
   * @功能 欧拉角模拟量数据结构体
   */
  typedef struct {
    float   head, roll, pitch;
  } sEulAnalog_t;

  /**
   * @功能 四元素模拟量结构体
   */
  typedef struct {
    float   w, x, y, z;
  } sQuaAnalog_t;

  /**
   * @功能 枚举陀螺仪范围,单位为 G
   */
  typedef enum {
    eAccRange_2G,
    eAccRange_4G,
    eAccRange_8G,
    eAccRange_16G
  } eAccRange_t;

  /**
   * @功能 枚举陀螺仪带宽 HZ
   */
  typedef enum {
    eAccBandWidth_7_81,    // 7.81HZ
    eAccBandWidth_15_63,   // 16.63HZ
    eAccBandWidth_31_25,
    eAccBandWidth_62_5,
    eAccBandWidth_125,
    eAccBandWidth_250,
    eAccBandWidth_500,
    eAccBandWidth_1000
  } eAccBandWidth_t;

  /**
   * @功能 枚举陀螺仪电源模式
   */
  typedef enum {
    eAccPowerModeNormal,
    eAccPowerModeSuspend,
    eAccPowerModeLowPower1,
    eAccPowerModeStandby,
    eAccPowerModeLowPower2,
    eAccPowerModeDeepSuspend
  } eAccPowerMode_t;

  /**
   * @功能 枚举地磁计数据输出频率,单位 HZ
   */
  typedef enum {
    eMagDataRate_2,
    eMagDataRate_6,
    eMagDataRate_8,
    eMagDataRate_10,
    eMagDataRate_15,
    eMagDataRate_20,
    eMagDataRate_25,
    eMagDataRate_30
  } eMagDataRate_t;

  /**
   * @功能 枚举地磁计操作模式
   */
  typedef enum {
    eMagOprModeLowPower,
    eMagOprModeRegular,
    eMagOprModeEnhancedRegular,
    eMagOprModeHighAccuracy
  } eMagOprMode_t;

  /**
   * @功能 枚举地磁计电源模式
   */
  typedef enum {
    eMagPowerModeNormal,
    eMagPowerModeSleep,
    eMagPowerModeSuspend,
    eMagPowerModeForce
  } eMagPowerMode_t;

  /**
   * @功能 枚举陀螺仪数据范围 dps
   */
  typedef enum {
    eGyrRange_2000,
    eGyrRange_1000,
    eGyrRange_500,
    eGyrRange_250,
    eGyrRange_125
  } eGyrRange_t;

  /**
   * @功能 枚举陀螺仪带宽,单位 HZ
   */
  typedef enum {
    eGyrBandWidth_523,
    eGyrBandWidth_230,
    eGyrBandWidth_116,
    eGyrBandWidth_47,
    eGyrBandWidth_23,
    eGyrBandWidth_12,
    eGyrBandWidth_64,
    eGyrBandWidth_32
  } eGyrBandWidth_t;

  /**
   * @功能 枚举陀螺仪电源模式
   */
  typedef enum {
    eGyrPowerModeNormal,
    eGyrPowerModeFastPowerUp,
    eGyrPowerModeDeepSuspend,
    eGyrPowerModeSuspend,
    eGyrPowerModeAdvancedPowersave
  } eGyrPowerMode_t;

  /**
   * @功能 枚举加速度计中断信号
   */
  typedef enum {
    eAccIntSetAmnmXAxis = (0x01 << 2),
    eAccIntSetAmnmYAxis = (0x01 << 3),
    eAccIntSetAmnmZAxis = (0x01 << 4),
    eAccIntSetHgXAxis = (0x01 << 5),
    eAccIntSetHgYAxis = (0x01 << 6),
    eAccIntSetHgZAxis = (0x01 << 7),
    eAccIntSetAll = 0xfc
  } eAccIntSet_t;

  /**
   * @功能 枚举加速度计低速运动中断或无运动中断
   */
  typedef enum {
    eAccNmSmnmSm,  // 低速运动中断模式
    eAccNmSmnmNm   // 无运动中断模式
  } eAccNmSmnm_t;

  /**
   * @功能 枚举陀螺仪中断设置
   */
  typedef enum {
    eGyrIntSetAmXAxis = (0x01 << 0),
    eGyrIntSetAmYAxis = (0x01 << 1),
    eGyrIntSetAmZAxis = (0x01 << 2),
    eGyrIntSetHrXAxis = (0x01 << 3),
    eGyrIntSetHrYAxis = (0x01 << 4),
    eGyrIntSetHrZAxis = (0x01 << 5),
    eGyrIntSetAmFilt = (0x01 << 6),
    eGyrIntSetHrFilt = (0x01 << 7),
    eGyrIntSetAll = 0x3f
  } eGyrIntSet_t;

  /**
   * @功能 声明传感器状态
   */
  typedef enum {
    eStatusOK,    // 无问题
    eStatusErr,   // 未知错误
    eStatusErrDeviceNotDetect,    // 设备无法连接
    eStatusErrDeviceReadyTimeOut, // 设备准备就绪超时
    eStatusErrDeviceStatus,       // 设备内部状态错误
    eStatusErrParameter           // 函数参数错误
  } eStatus_t;

  /**
   * @功能 begin 传感器初始化
   * @返回 传感器状态
   */
  eStatus_t   begin();

  /**
   * @功能 getAxisAnalog 获取相应轴的模拟量数据
   * @参数 eAxis 一个来自于 eAxis_t 的轴声明
   * @返回 结构体 sAxisAnalog_t, 包含轴的模拟量数据, 成员的数据单位取决于 eAxis 的值:
   *                如果是 eAxisAcc, 单位是 mg
   *                如果是 eAxisLia, 单位是 mg
   *                如果是 eAxisGrv, 单位是 mg
   *                如果是 eAxisMag, 单位是 ut
   *                如果是 eAxisGyr, 单位是 dps
   */
  sAxisAnalog_t getAxis(eAxis_t eAxis);

  /**
   * @功能 getEulAnalog 获取欧拉角的模拟量数据
   * @返回 结构体 sEulAnalog_t, 包含欧拉角的模拟量数据
   */
  sEulAnalog_t  getEul();

  /**
   * @功能 getQuaAnalog 获取四元数的模拟量数据
   * @返回 结构体 sQuaAnalog_t, 板换四元数的模拟量数据
   */
  sQuaAnalog_t  getQua();

  /**
   * @功能 setAccOffset 设置轴偏移
   * @参数 eAxis 一个来自于 eAxis_t 的轴声明, 仅仅只支持加速度计,陀螺仪和地磁计
   * @参数 sOffset 结构体 sAxisAnalog_t, 包含轴的模拟量数据, 成员数据的单位取决于 eAxis:
   *                如果是 eAxisAcc, 单位 mg, 值不能超过加速度计设置的数据范围
   *                如果是 eAxisMag, 单位 ut, 值不能超过地磁计设置的数据范围
   *                如果是 eAxisGyr, 单位 dps, 值不能超过陀螺仪设置的数据范围
   */
  void    setAxisOffset(eAxis_t eAxis, sAxisAnalog_t sOffset);

  /**
   * @功能 setOprMode 设置操作模式
   * @参数 eOpr 一个来自于 eOprMode_t 的操作声明
   */
  void    setOprMode(eOprMode_t eMode);

  /**
   * @功能 setPowerMode 设置电源模式
   * @参数 eMode 一个来自于 ePowerMode_t 的电源模式声明
   */
  void    setPowerMode(ePowerMode_t eMode);

  /**
   * @功能 重置传感器
   */
  void    reset();

  /**
   * @功能 setAccRange 设置加速度计测量范围, 默认值是 4g
   * @参数 eRange 一个来自于 eAccRange_t 的范围声明
   */
  void    setAccRange(eAccRange_t eRange);

  /**
   * @功能 setAccBandWidth 设置加速度计带宽, 默认值是 62.5hz
   * @参数 eBand 一个来自于 eAccBandWidth_t 的带宽声明
   */
  void    setAccBandWidth(eAccBandWidth_t eBand);

  /**
   * @功能 setAccPowerMode 设置加速度计电源模式, 默认值是 eAccPowerModeNormal
   * @参数 eMode 一个来自于 eAccPowerMode_t 的电源模式声明
   */
  void    setAccPowerMode(eAccPowerMode_t eMode);

  /**
   * @功能 setMagDataRate 设置地磁计的数据输出频率, 默认值是 20hz
   * @参数 eRate 一个来自于 eMagDataRate_t 的频率声明
   */
  void    setMagDataRate(eMagDataRate_t eRate);

  /**
   * @功能 setMagOprMode 设置地磁计的操作模式, 默认值是 eMagOprModeRegular
   * @参数 eMode 一个来自于 eMagOprMode_t 的操作声明
   */
  void    setMagOprMode(eMagOprMode_t eMode);

  /**
   * @功能 setMagPowerMode 设置地磁计的电源模式, 默认值是 eMagePowerModeForce
   * @参数 eMode 一个来自于 eMagPowerMode_t 的电源模式声明
   */
  void    setMagPowerMode(eMagPowerMode_t eMode);

  /**
   * @功能 setGyrRange 设置陀螺仪数据范围, 默认值是 2000
   * @参数 eRange 一个来自于 eGyrRange_t 的范围声明
   */
  void    setGyrRange(eGyrRange_t eRange);

  /**
   * @功能 setGyrBandWidth 设置陀螺仪的带宽范围, 默认值是 32HZ
   * @参数 eBandWidth 一个来自于 eGyrBandWidth_t 的带宽声明
   */
  void    setGyrBandWidth(eGyrBandWidth_t eBandWidth);

  /**
   * @功能 setGyrPowerMode 设置陀螺仪的电源模式, 默认值是 eGyrPowerModeNormal
   * @参数 eMode 一个来自于 eGyrPowerMode_t 的电源模式声明
   */
  void    setGyrPowerMode(eGyrPowerMode_t eMode);

  /**
   * @功能 getIntState 获取中断状态, 中断在读取状态后自动清楚
   * @返回 如果返回值大于 0, 则至少有一个中断被触发了, 返回值 & eIntXXX (来自于 eInt_t) 来测试触发的是哪个中断
   */
  uint8_t   getIntState();

  /**
   * @功能 setIntMask 允许选中的中断掩码, 影响中断引脚,如果设置正确则会在中断引脚上有一个上升沿中断
   * @参数 eInt 一个或多个来自于 eInt_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setIntMaskEnable(eInt_t eInt);

  /**
   * @功能 setIntMaskDisable 静止选中的中断掩码
   * @参数 eInt 一个或多个来自于 eInt_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setIntMaskDisable(eInt_t eInt);

  /**
   * @功能 setIntEnEnable 允许选中的中断
   * @参数 eInt 一个或多个来自于 eInt_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setIntEnable(eInt_t eInt);

  /**
   * @功能 setIntEnDisable 禁止选中的中断
   * @参数 eInt 一个或多个来自于 eInt_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setIntDisable(eInt_t eInt);

  /**
   * @功能 setAccAmThres 设置加速度计任意运动中断阀值
   * @参数 thres 要设置的阀值, 单位是 mg, 值得范围依赖于选择的加速度计数据范围,
   *        如果是 2g, 不能超过 1991
   *        如果是 4g, 不能超过 3985
   *        如果是 8g, 不能超过 7968
   *        如果是 16g, 不能超过 15937
   *        注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setAccAmThres(uint16_t thres);

  /**
   * @功能 setAccIntDur 设置加速度计中断触发延迟次数,
   *        如果任意运动中断触发次数超过 (dur + 1) 次,才会触发任意运动中断信号,
   * @参数 dur 要设置的延迟,范围 1 到 4
   */
  void    setAccIntAmDur(uint8_t dur);

  /**
   * @功能 setAccIntEnable 允许相应的加速度计中断
   * @参数 eInt 一个或多个来自于 eAccIntSet_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setAccIntEnable(eAccIntSet_t eInt);

  /**
   * @功能 setAccIntDisable 禁止相应的加速度计中断
   * @参数 eInt 一个或多个来自于 eAccIntSet_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setAccIntDisable(eAccIntSet_t eInt);

  /**
   * @功能 setAccHighGDuration 设置加速度计高加速度中断, 高加速度速中断延时时间为 [dur + 1] * 2 ms
   * @参数 dur 2ms 到 512ms 之间的时间
   */
  void    setAccHighGDuration(uint16_t dur);

  /**
   * @功能 setAccHighGThres 设置加速度计高加速度阀值
   * @参数 thres 要设置的阀值,单位 mg, 值不能超过加速度计设置的数据范围
   *        如果是 2g, 不能超过 1991
   *        如果是 4g, 不能超过 3985
   *        如果是 8g, 不能超过 7968
   *        如果是 16g, 不能超过 15937
   *        注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setAccHighGThres(uint16_t thres);

  /**
   * @功能 setAccNmThres 设置加速度计无运动中断阀值
   * @参数 thres 要设置的阀值,单位 mg, 值不能超过加速度计设置的数据范围
   *        如果是 2g, 不能超过 1991
   *        如果是 4g, 不能超过 3985
   *        如果是 8g, 不能超过 7968
   *        如果是 16g, 不能超过 15937
   *        注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setAccNmThres(uint16_t thres);

  /**
   * @功能 setAccNmSet 设置加速度计中断为慢运动或无运动,以及该中断的超时时间
   * @参数 eSmnm 来自于 eAccNmSmnm_t 的枚举
   * @参数 dur 中断触发延时 (单位为秒), 不能超过 344.
   *           注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setAccNmSet(eAccNmSmnm_t eSmnm, uint16_t dur);

  /**
   * @功能 setGyrIntEnable 允许选择的陀螺仪中断
   * @参数 eInt 一个或多个来自于 eGyrIntSet_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setGyrIntEnable(eGyrIntSet_t eInt);

  /**
   * @功能 setGyrIntDisable 禁止相应的陀螺仪中断
   * @参数 eInt 一个或多个来自于 eGyrIntSet_t 的中断标志, 使用或的逻辑输入它们
   */
  void    setGyrIntDisable(eGyrIntSet_t eInt);

  /**
   * @功能 setGyrHrSet 设置陀螺仪高速中断
   * @参数 eSingleAxis 要设置的单个轴
   * @参数 thres 要设置的高速中断阀值, 单位 度/秒, 值不能超过陀螺仪设置的数据范围
   *        如果是 2000, 不能超过 1937
   *        如果是 1000, 不能超过 968
   *        如果是 500, 不能超过 484
   *        如果是 250, 不能超过 242
   *        如果是 125, 不能超过 121
   *        注意:根据技术手册,实际值将会与设定值有点偏差
   * @参数 dur 高速中断延时, 单位 ms, 时间在 2.5ms 到 640ms 之间
   *           注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setGyrHrSet(eSingleAxis_t eSingleAxis, uint16_t thres, uint16_t dur);

  /**
   * @功能 setGyrAmThres 设置陀螺仪任意运动中断阀值
   * @参数 thres 要设置的阀值, 单位 mg, 值不能超过陀螺仪设置的数据范围
   *        如果是 2000, 不能超过 128
   *        如果是 1000, 不能超过 64
   *        如果是 500, 不能超过 32
   *        如果是 250, 不能超过 16
   *        如果是 125, 不能超过 8
   *        注意:根据技术手册,实际值将会与设定值有点偏差
   */
  void    setGyrAmThres(uint8_t thres);

  /**
   * @功能 lastOpreateStatus 保存最近一次类中函数的操作结果
   */
  eStatus_t   lastOpreateStatus;
};

class DFRobot_BNO055_IIC : public DFRobot_BNO055 {
public:
  /**
   * @功能 DFRobot_BNO055_IIC 类构造体
   * @参数 pWire 选择一个 TwoWire 类外设
   * @参数 addr 传感器地址
   */
  DFRobot_BNO055_IIC(TwoWire *pWire, uint8_t addr);
};

使用教程

该模块板载BNO055传感器,可以用I2C接口访问BNO055的I2C地址,从而获取相应的位置数据。

准备

  • 硬件
    • 1 x Arduino UNO控制板
    • 1 x BNO055 Intelligent 9-axis sensor module模块
    • 若干 杜邦线
  • 软件

接线图

连接模块与UNO主板(通过I2C接口),按照如下图的方式连接。

样例代码

样例代码
程序功能:通过I2C接口读取BNO055传感器的仰角、翻滚角、偏航角,并将读取到的数据通过串口打印出来。此demo结合我们为此设计的一个可视化小软件 Euler angle visual tool.exe 使用,能更直观的显示10Dof姿态的变化,如下图gif所示:

/*!
  * imu_show.ino
  *
  * Download this demo to show attitude on [imu_show](https://github.com/DFRobot/DFRobot_IMU_Show)
  * Attitude will show on imu_show
  *
  * Product: https://www.dfrobot.com.cn/goods-1860.html
  * Copyright   [DFRobot](https://www.dfrobot.com), 2016
  * Copyright   GNU Lesser General Public License
  *
  * version  V1.0
  * date  07/03/2019
  */

#include "DFRobot_BNO055.h"
#include "Wire.h"

typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********

BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address

// show last sensor operate status
void printLastOperateStatus(BNO::eStatus_t eStatus)
{
  switch(eStatus) {
  case BNO::eStatusOK:    Serial.println("everything ok"); break;
  case BNO::eStatusErr:   Serial.println("unknow error"); break;
  case BNO::eStatusErrDeviceNotDetect:    Serial.println("device not detected"); break;
  case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break;
  case BNO::eStatusErrDeviceStatus:       Serial.println("device internal status error"); break;
  default: Serial.println("unknow status"); break;
  }
}

void setup()
{
  Serial.begin(115200);
  bno.reset();
  while(bno.begin() != BNO::eStatusOK) {
    Serial.println("bno begin faild");
    printLastOperateStatus(bno.lastOperateStatus);
    delay(2000);
  }
  Serial.println("bno begin success");
}

void loop()
{
  BNO::sEulAnalog_t   sEul;
  sEul = bno.getEul();
  Serial.print("pitch:");
  Serial.print(sEul.pitch, 3);
  Serial.print(" ");
  Serial.print("roll:");
  Serial.print(sEul.roll, 3);
  Serial.print(" ");
  Serial.print("yaw:");
  Serial.print(sEul.head, 3);
  Serial.println(" ");
  delay(80);
}

如果把BNO055模块比作一架机头指向正东方向的飞机,则x轴指向方向为机头方向,y轴左机翼指向正北方向,z轴垂直于x轴与y轴形成的平面xoy,当BNO055模块的x,y,z完全与上述方向重合,则pitch、roll、yaw的值均为0度。其中pitch(仰角)为机头沿y轴上仰或下仰后,与xoy平面所形成的夹角,向上为正,向下为负;roll(翻滚角)为机身沿x轴左右翻滚后,与xoy平面所形成的夹角;yaw(偏航角)为机头沿z轴旋转后与xoz平面所形成的夹角;

使用测试软件观察传感器姿态时需关闭串口打印所占用的串口!

样例代码
程序功能:获取传感器在x、y、z轴上的各项数据,并通过串口打印出来。

/*!
  * read_data.ino
  *
  * Download this demo to test read data from bno055
  * Data will print on your serial monitor
  *
  * Product: https://www.dfrobot.com.cn/goods-1860.html
  * Copyright   [DFRobot](https://www.dfrobot.com), 2016
  * Copyright   GNU Lesser General Public License
  *
  * version  V1.0
  * date  07/03/2019
  */

#include "DFRobot_BNO055.h"
#include "Wire.h"

typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********

BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address

// show last sensor operate status
void printLastOperateStatus(BNO::eStatus_t eStatus)
{
  switch(eStatus) {
  case BNO::eStatusOK:   Serial.println("everything ok"); break;
  case BNO::eStatusErr:  Serial.println("unknow error"); break;
  case BNO::eStatusErrDeviceNotDetect:   Serial.println("device not detected"); break;
  case BNO::eStatusErrDeviceReadyTimeOut:    Serial.println("device ready time out"); break;
  case BNO::eStatusErrDeviceStatus:    Serial.println("device internal status error"); break;
  default: Serial.println("unknow status"); break;
  }
}

void setup()
{
  Serial.begin(115200);
  bno.reset();
  while(bno.begin() != BNO::eStatusOK) {
    Serial.println("bno begin faild");
    printLastOperateStatus(bno.lastOperateStatus);
    delay(2000);
  }
  Serial.println("bno begin success");
}

#define printAxisData(sAxis) \
  Serial.print(" x: "); \
  Serial.print(sAxis.x); \
  Serial.print(" y: "); \
  Serial.print(sAxis.y); \
  Serial.print(" z: "); \
  Serial.println(sAxis.z)

void loop()
{
  BNO::sAxisAnalog_t   sAccAnalog, sMagAnalog, sGyrAnalog, sLiaAnalog, sGrvAnalog;
  BNO::sEulAnalog_t    sEulAnalog;
  BNO::sQuaAnalog_t    sQuaAnalog;
  sAccAnalog = bno.getAxis(BNO::eAxisAcc);    // read acceleration
  sMagAnalog = bno.getAxis(BNO::eAxisMag);    // read geomagnetic
  sGyrAnalog = bno.getAxis(BNO::eAxisGyr);    // read gyroscope
  sLiaAnalog = bno.getAxis(BNO::eAxisLia);    // read linear acceleration
  sGrvAnalog = bno.getAxis(BNO::eAxisGrv);    // read gravity vector
  sEulAnalog = bno.getEul();                  // read euler angle
  sQuaAnalog = bno.getQua();                  // read quaternion
  Serial.println();
  Serial.println("======== analog data print start ========");
  Serial.print("acc analog: (unit mg)       "); printAxisData(sAccAnalog);
  Serial.print("mag analog: (unit ut)       "); printAxisData(sMagAnalog);
  Serial.print("gyr analog: (unit dps)      "); printAxisData(sGyrAnalog);
  Serial.print("lia analog: (unit mg)       "); printAxisData(sLiaAnalog);
  Serial.print("grv analog: (unit mg)       "); printAxisData(sGrvAnalog);
  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);
  Serial.print("qua analog: (no unit)       "); Serial.print(" w: "); Serial.print(sQuaAnalog.w); printAxisData(sQuaAnalog);
  Serial.println("========  analog data print end  ========");

  delay(1000);
}

样例代码
程序功能:监听传感器的各种中断,包含高速运动或低速运功中断,快速倾斜中断

/*!
  * interrupt.ino
  *
  * Download this demo to test bno055 interrupt
  * Connect bno055 int pin to arduino pin 2
  * If there occurs interrupt, it will printr on you serial monitor, more detail please reference comment
  *
  * Product: https://www.dfrobot.com.cn/goods-1860.html
  * Copyright   [DFRobot](https://www.dfrobot.com), 2016
  * Copyright   GNU Lesser General Public License
  *
  * version  V1.0
  * date  07/03/2019
  */

#include "DFRobot_BNO055.h"
#include "Wire.h"

typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********

BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address

// show last sensor operate status
void printLastOperateStatus(BNO::eStatus_t eStatus)
{
  switch(eStatus) {
  case BNO::eStatusOK:    Serial.println("everything ok"); break;
  case BNO::eStatusErr:   Serial.println("unknow error"); break;
  case BNO::eStatusErrDeviceNotDetect:    Serial.println("device not detected"); break;
  case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break;
  case BNO::eStatusErrDeviceStatus:       Serial.println("device internal status error"); break;
  default: Serial.println("unknow status"); break;
  }
}

bool intFlag = false;

void intHandle()
{
  intFlag = true;
}

void setup()
{
  Serial.begin(115200);
  bno.reset();
  while(bno.begin() != BNO::eStatusOK) {
    Serial.println("bno begin faild");
    printLastOperateStatus(bno.lastOperateStatus);
    delay(2000);
  }
  Serial.println("bno begin success");

  bno.setOprMode(BNO::eOprModeConfig);    // set to config mode

  bno.setIntMaskEnable(BNO::eIntAll);    // set interrupt mask enable, signal to int pin when interrupt
  // bno.setIntMaskDisable(BNO::eIntAccAm | BNO::eIntAccNm);    // set interrupt mask disable, no signal to int pin when interrupt

  bno.setIntEnable(BNO::eIntAll);   // set interrupt enable
  // bno.setIntDisable(BNO::eIntAccAm | BNO::eIntAccNm);    // set interrupt disable

  bno.setAccIntEnable(BNO::eAccIntSetAll);    // set accelerometer interrupt enable
  // bno.setAccIntDisable(BNO::eAccIntSetAmnmXAxis | BNO::eAccIntSetHgXAxis);   // set accelerometer interrupt disable

  /* accelerometer any motion threshold to set, unit mg, value is dependent on accelerometer range selected,
   * case 2g, no more than 1991
   * case 4g, no more than 3985
   * case 8g, no more than 7968
   * case 16g, no more than 15937
   * attenion: The set value will be slightly biased according to datasheet
   * tips: default accelerometer range is 4g
   */
  // how to trig this: still --> fast move
  bno.setAccAmThres(200);
  // any motion interrupt triggers if duration consecutive data points are above the any motion interrupt
  // threshold define in any motion threshold
  bno.setAccIntAmDur(1);
  // set high-g duration, value from 2ms to 512ms
  bno.setAccHighGDuration(80);
  /*
   * accelerometer high-g threshold to set, unit mg, value is dependent on accelerometer range selected,
   * case 2g, no more than 1991
   * case 4g, no more than 3985
   * case 8g, no more than 7968
   * case 16g, no more than 15937
   * Attenion: The set value will be slightly biased according to datasheet
   */
  // how to trig this: still --> (very) fast move
  bno.setAccHighGThres(900);
  // accelerometer (no motion) / (slow motion) settings, 2nd parameter unit seconds, no more than 344
  bno.setAccNmSet(BNO::eAccNmSmnmNm, 4);
  /*
   * accelerometer no motion threshold to set, unit mg, value is dependent on accelerometer range selected,
   * case 2g, no more than 1991
   * case 4g, no more than 3985
   * case 8g, no more than 7968
   * case 16g, no more than 15937
   * Attenion: The set value will be slightly biased according to datasheet
   */
  // hot to trig this: any motion --> still --> still
  bno.setAccNmThres(100);

  bno.setGyrIntEnable((BNO::eGyrIntSet_t) (BNO::eGyrIntSetHrXAxis | BNO::eGyrIntSetHrYAxis | BNO::eGyrIntSetHrZAxis));    // set gyroscope interrupt enable, in most cases, this is enough.
  // bno.setGyrIntEnable(BNO::eGyrIntSetAmYAxis | BNO::eGyrIntSetAmYAxis | BNO::eGyrIntSetAmZAxis);    // set gyroscope interrupt enable
  // bno.setGyrIntDisable(BNO::eGyrIntSetHrXAxis | BNO::eGyrIntSetAmXAxis);    // set gyroscope interrupt disable

  /*
   * 2nd parameter, high rate threshold to set, unit degree/seconds, value is dependent on gyroscope range selected,
   * case 2000, no more than 1937
   * case 1000, no more than 968
   * case 500, no more than 484
   * case 250, no more than 242
   * case 125, no more than 121
   * Attenion: The set value will be slightly biased according to datasheet
   * 3rd parameter, high rate duration to set, unit ms, duration from 2.5ms to 640ms
   * Attenion: The set value will be slightly biased according to datasheet
   */
  // how to trigger this: still --> fast tilt
  bno.setGyrHrSet(BNO::eSingleAxisX, 300, 80);
  bno.setGyrHrSet(BNO::eSingleAxisY, 300, 80);
  bno.setGyrHrSet(BNO::eSingleAxisZ, 300, 80);
  /*
   * gyroscope any motion threshold to set, unit mg, value is dependent on accelerometer range selected,
   * case 2000, no more than 128
   * case 1000, no more than 64
   * case 500, no more than 32
   * case 250, no more than 16
   * case 125, no more than 8
   * Attenion: The set value will be slightly biased according to datasheet
   * tips: default range is 2000
   */
  // how to trigger this: still --> fast tilt
  bno.setGyrAmThres(20);

  bno.setOprMode(BNO::eOprModeNdof);    // configure done

  attachInterrupt(0, intHandle, RISING);   // attach interrupt
  bno.getIntState();    // clear unexpected interrupt
  intFlag = false;
}

void loop()
{
  if(intFlag) {
    intFlag = false;
    uint8_t   intSta = bno.getIntState();   // interrupt auto clear after read

    Serial.println("interrupt detected");
    if(intSta & BNO::eIntAccAm)
      Serial.println("accelerometer any motion detected");
    if(intSta & BNO::eIntAccNm)
      Serial.println("accelerometer no motion detected");
    if(intSta & BNO::eIntAccHighG)
      Serial.println("acceleromter high-g detected");
    if(intSta & BNO::eIntGyrHighRate)
      Serial.println("gyroscope high rate detected");
    if(intSta & BNO::eIntGyrAm)
      Serial.println("gyroscope any motion detected");
  }
}

样例代码
程序功能:对传感器进行各项配置

/*!
  * config.ino
  *
  * Download this demo to test config to bno055
  * Data will print on your serial monitor
  *
  * Product: https://www.dfrobot.com.cn/goods-1860.html
  * Copyright   [DFRobot](https://www.dfrobot.com), 2016
  * Copyright   GNU Lesser General Public License
  *
  * version  V1.0
  * date  07/03/2019
  */

#include "DFRobot_BNO055.h"
#include "Wire.h"

typedef DFRobot_BNO055_IIC    BNO;    // ******** use abbreviations instead of full names ********

BNO   bno(&Wire, 0x28);    // input TwoWire interface and IIC address

// show last sensor operate status
void printLastOperateStatus(BNO::eStatus_t eStatus)
{
  switch(eStatus) {
  case BNO::eStatusOK:    Serial.println("everything ok"); break;
  case BNO::eStatusErr:   Serial.println("unknow error"); break;
  case BNO::eStatusErrDeviceNotDetect:    Serial.println("device not detected"); break;
  case BNO::eStatusErrDeviceReadyTimeOut: Serial.println("device ready time out"); break;
  case BNO::eStatusErrDeviceStatus:       Serial.println("device internal status error"); break;
  default: Serial.println("unknow status"); break;
  }
}

void setup()
{
  Serial.begin(115200);
  bno.reset();
  while(bno.begin() != BNO::eStatusOK) {
    Serial.println("bno begin faild");
    printLastOperateStatus(bno.lastOperateStatus);
    delay(2000);
  }
  Serial.println("bno begin success");

  bno.setPowerMode(BNO::ePowerModeNormal);    // set to normal power mode
  bno.setOprMode(BNO::eOprModeConfig);    // must set sensor to config-mode before configure
  bno.setAccPowerMode(BNO::eAccPowerModeNormal);    // set acc to normal power mode
  bno.setGyrPowerMode(BNO::eGyrPowerModeNormal);    // set gyr to normal power mode
  bno.setMagPowerMode(BNO::eMagPowerModeForce);     // set mag to force power mode

  // accelerometer normal configure
  bno.setAccRange(BNO::eAccRange_4G);   // set range to 4g
  bno.setAccBandWidth(BNO::eAccBandWidth_62_5);   // set band width 62.5HZ
  bno.setAccPowerMode(BNO::eAccPowerModeNormal);  // set accelerometer power mode

  // magnetometer normal configure
  bno.setMagDataRate(BNO::eMagDataRate_20);   // set output data rate 20HZ
  bno.setMagPowerMode(BNO::eMagPowerModeForce);   // set power mode
  bno.setMagOprMode(BNO::eMagOprModeRegular); // set operate mode

  // gyroscope normal configure
  bno.setGyrRange(BNO::eGyrRange_2000);   // set range
  bno.setGyrBandWidth(BNO::eGyrBandWidth_32);   // set band width
  bno.setGyrPowerMode(BNO::eGyrPowerModeNormal);    // set power mode

  BNO::sAxisAnalog_t    sOffsetAcc;   // unit mg, members can't out of acc range
  BNO::sAxisAnalog_t    sOffsetMag;   // unit ut, members can't out of mag range
  BNO::sAxisAnalog_t    sOffsetGyr;   // unit dps, members can't out of gyr range
  sOffsetAcc.x = 1;
  sOffsetAcc.y = 1;
  sOffsetAcc.z = 1;
  sOffsetMag.x = 1;
  sOffsetMag.y = 1;
  sOffsetMag.z = 1;
  sOffsetGyr.x = 1;
  sOffsetGyr.y = 1;
  sOffsetGyr.z = 1;
  bno.setAxisOffset(BNO::eAxisAcc, sOffsetAcc);   // set offset
  bno.setAxisOffset(BNO::eAxisMag, sOffsetMag);
  bno.setAxisOffset(BNO::eAxisGyr, sOffsetGyr);

  bno.setOprMode(BNO::eOprModeNdof);   // shift to other operate mode, reference datasheet for more detail
}

#define printAxisData(sAxis) \
  Serial.print(" x: "); \
  Serial.print(sAxis.x); \
  Serial.print(" y: "); \
  Serial.print(sAxis.y); \
  Serial.print(" z: "); \
  Serial.println(sAxis.z)

void loop()
{
  BNO::sAxisAnalog_t   sAccAnalog, sMagAnalog, sGyrAnalog, sLiaAnalog, sGrvAnalog;
  BNO::sEulAnalog_t    sEulAnalog;
  BNO::sQuaAnalog_t    sQuaAnalog;
  sAccAnalog = bno.getAxis(BNO::eAxisAcc);
  sMagAnalog = bno.getAxis(BNO::eAxisMag);
  sGyrAnalog = bno.getAxis(BNO::eAxisGyr);
  sLiaAnalog = bno.getAxis(BNO::eAxisLia);
  sGrvAnalog = bno.getAxis(BNO::eAxisGrv);
  sEulAnalog = bno.getEul();
  sQuaAnalog = bno.getQua();
  Serial.println();
  Serial.println("======== analog data print start ========");
  Serial.print("acc analog: (unit mg)       "); printAxisData(sAccAnalog);
  Serial.print("mag analog: (unit ut)       "); printAxisData(sMagAnalog);
  Serial.print("gyr analog: (unit dps)      "); printAxisData(sGyrAnalog);
  Serial.print("lia analog: (unit mg)       "); printAxisData(sLiaAnalog);
  Serial.print("grv analog: (unit mg)       "); printAxisData(sGrvAnalog);
  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);
  Serial.print("qua analog: (no unit)       "); Serial.print(" w: "); Serial.print(sQuaAnalog.w); printAxisData(sQuaAnalog);
  Serial.println("========  analog data print end  ========");

  delay(1000);
}

常见问题

还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png [DFRobot商城购买链接]