The BNO055 is a versatile 9-axis sensor module that combines an accelerometer, gyroscope, and magnetometer to provide accurate orientation tracking in a compact package. It features a built-in microcontroller and advanced sensor fusion algorithms that provide stable and accurate measurements even in challenging environments.
The BNO055 can be used with a variety of microcontroller platforms, including the esp32, esp8266, and Arduino. To help users get started with the BNO055, a series of articles has been created that cover various aspects of working with the sensor module.
In part 1 of the series, the basic Adafruit library is introduced for use with the BNO055. Part 2 focuses on wiring and using the advanced Bosch library. Part 3 covers features, configuration, and axes remap, while part 4 delves into power modes and configuring the accelerometer any/no motion interrupt.
Part 5, which is the focus of this excerpt, covers enabling the INT pin and configuring the accelerometer High G Interrupt. Part 6 covers configuring the Gyroscope High Rate and Any Motion Interrupt.
Overall, the series of articles provides a comprehensive guide to working with the BNO055 and unlocking its full potential for a wide range of applications.
BNO055 pinouts
There are many module versions of these sensors, so I choose the smallest and cheap.
Here the module Aliexpress
All these modules have the same features, but to enable them, you must do different operations.
This is the clone I use:
And here is the Adafruit one:
The sensor support a 3.3v logic level, but the module can be powered by 5v.
Microcontroller interrupt on PIN
Now if we want to use the INT pin, we are going to add a bit mask and wiring an interrupted pin.
esp32 interrupt management
First, we must wire the INT pin, It’s better to select an RTC pin (check “ESP32 practical power saving: preserve gpio status, external and ULP wake up“).
Here some esp32 ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S
The INT pin is set to high on the interrupt and will remain high until it is reset or read by the host, so on esp32, we must attach interrupt like so:
bool somethingHappened = false;
void IRAM_ATTR interruptCallback() {
somethingHappened = true;
}
[...]
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(INTERRUPT_PIN, interruptCallback, RISING);
Arduino interrupt management
The Arduino boards have some pins that can be used as interrupts,
BOARD | DIGITAL PINS USABLE FOR INTERRUPTS |
---|---|
Uno, Nano, Mini, other 328-based | 2, 3 |
Uno WiFi Rev.2, Nano Every | all digital pins |
Mega, Mega2560, MegaADK | 2, 3, 18, 19, 20, 21 |
Micro, Leonardo, other 32u4-based | 0, 1, 2, 3, 7 |
Zero | all digital pins, except 4 |
MKR Family boards | 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 |
Nano 33 IoT | 2, 3, 9, 10, 11, 13, A1, A5, A7 |
Nano 33 BLE, Nano 33 BLE Sense | all pins |
Due | all digital pins |
101 | all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE) |
for Arduino UNO, we are going to select pin 2,
And we must manage the interrupt pin with the same behavior of esp32 already described.
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), interruptCallback, RISING);
esp8266 manage interrupt
esp8266 like esp32 has a lot of interrupt pins, and the management also is similar. Here is the wiring schema for the Adafruit sensor.
Here is the wiring schema for clone bno055.
The interrupt has the same management as esp32, and we are going to select D5
pin.
bool somethingHappened = false;
void IRAM_ATTR interruptCallback() {
somethingHappened = true;
}
[...]
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(INTERRUPT_PIN, interruptCallback, RISING);
Interrupt bitmask
To enable the INT pin, you must configure the interrupt bitmask.
To activate the interrupt pin, we must set 1 to the interrupt bit mask.
// Activate INT pin with bitmask
bno055_set_intmsk_accel_nomotion(1);
bno055_set_intmsk_accel_anymotion(1);
And every time we have an interrupt to reactivate the pin management, we must set 1 the RST_INT register with this command.
// reset all previous int signal
bno055_set_reset_int(1);
If you don’t do this operation, the int pin remains HIGH, and you can catch more interruptions.
Here is the complete sketch.
/**
* bno055 simple interrupt management
* enable register interrupt and pin 15
* for any motion and no motion in LOW POWER mode
* bit mask for interrupt pin on no and any motion
*
* by Renzo Mischianti <www.mischianti.org>
*
* https://mischianti.org/
*/
#include "BNO055_support.h" //Contains the bridge code between the API and Arduino
#include <Wire.h>
//The device address is set to BNO055_I2C_ADDR2 in this example. You can change this in the BNO055.h file in the code segment shown below.
// /* bno055 I2C Address */
// #define BNO055_I2C_ADDR1 0x28
// #define BNO055_I2C_ADDR2 0x29
// #define BNO055_I2C_ADDR BNO055_I2C_ADDR2
//Pin assignments as tested on the Arduino Due.
//Vdd,Vddio : 3.3V
//GND : GND
//SDA/SCL : SDA/SCL
//PSO/PS1 : GND/GND (I2C mode)
//This structure contains the details of the BNO055 device that is connected. (Updated after initialization)
struct bno055_t myBNO;
struct bno055_euler myEulerData; //Structure to hold the Euler data
unsigned long lastTime = 0;
/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (1000)
#define INTERRUPT_PIN 15
void getIntInterruptEnabled();
void getIntInterruptBitMaskEnabled();
void getInterruptStatusEnabled(bool synthetic = false);
void printSlowMotionNoMotionParameters();
bool somethingHappened = false;
void IRAM_ATTR interruptCallback() {
somethingHappened = true;
}
void setup() //This code is executed once
{
//Initialize I2C communication
Wire.begin();
//Initialization of the BNO055
BNO_Init(&myBNO); //Assigning the structure to hold information about the device
// bno055_set_reset_sys(1);
delay(1500);
bno055_set_powermode(POWER_MODE_LOW_POWER);
// Activate INT pin with bitmask
bno055_set_intmsk_accel_nomotion(1);
bno055_set_intmsk_accel_anymotion(1);
// reset all previous int signal
bno055_set_reset_int(1);
//Configuration to NDoF mode
bno055_set_operation_mode(OPERATION_MODE_NDOF);
// Activate SLOW MOTION
// bno055_set_accel_slow_no_motion_enable(0);
// Activate NO MOTION (default)
bno055_set_accel_slow_no_motion_enable(1);
delay(1);
//Initialize the Serial Port to view information on the Serial Monitor
Serial.begin(115200);
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(INTERRUPT_PIN, interruptCallback, RISING);
delay(1000);
getIntInterruptEnabled();
getIntInterruptBitMaskEnabled();
printSlowMotionNoMotionParameters();
}
bool suspended = false;
bool reactivated = false;
void loop() //This code is looped forever
{
if ((millis() - lastTime) >= BNO055_SAMPLERATE_DELAY_MS) //To stream at 10Hz without using additional timers
{
lastTime = millis();
bno055_read_euler_hrp(&myEulerData); //Update Euler data into the structure
Serial.print(millis()/1000); Serial.print("Secs - ");
/* The WebSerial 3D Model Viewer expects data as heading, pitch, roll */
Serial.print(F("Orientation: "));
Serial.print(360-(float(myEulerData.h) / 16.00));
Serial.print(F(", "));
Serial.print(360-(float(myEulerData.p) / 16.00));
Serial.print(F(", "));
Serial.print(360-(float(myEulerData.r) / 16.00));
Serial.print(F(" - "));
getInterruptStatusEnabled(true);
}
if (somethingHappened) {
Serial.println("---------------");
getInterruptStatusEnabled();
Serial.println("---------------");
bno055_set_reset_int(1);
somethingHappened = false;
}
}
/*
* Print the interrupt enabled
*/
void getIntInterruptEnabled() {
unsigned char gyro_am = 0;
unsigned char gyro_hr = 0;
unsigned char accel_hg = 0;
unsigned char accel_am = 0;
unsigned char accel_nm = 0;
bno055_get_int_gyro_anymotion(&gyro_am);
bno055_get_int_gyro_highrate(&gyro_hr);
bno055_get_int_accel_high_g(&accel_hg);
bno055_get_int_accel_anymotion(&accel_am);
bno055_get_int_accel_nomotion(&accel_nm);
Serial.println( "---- Interrupt enabled ----" );
Serial.print( "Gyro Any Motion " );
Serial.println( gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( gyro_hr );
Serial.print( "Accel High G " );
Serial.println( accel_hg );
Serial.print( "Accel Any Motion " );
Serial.println( accel_am );
Serial.print( "Accel No Motion " );
Serial.println( accel_nm );
Serial.println( "---------------------------" );
}
/*
* Print the interrupt to send on interrupt pin
*/
void getIntInterruptBitMaskEnabled() {
unsigned char gyro_am = 0;
unsigned char gyro_hr = 0;
unsigned char accel_hg = 0;
unsigned char accel_am = 0;
unsigned char accel_nm = 0;
bno055_get_intmsk_gyro_anymotion(&gyro_am);
bno055_get_intmsk_gyro_highrate(&gyro_hr);
bno055_get_intmsk_accel_high_g(&accel_hg);
bno055_get_intmsk_accel_anymotion(&accel_am);
bno055_get_intmsk_accel_nomotion(&accel_nm);
Serial.println( "---- Interrupt bitmask ----" );
Serial.print( "Gyro Any Motion " );
Serial.println( gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( gyro_hr );
Serial.print( "Accel High G " );
Serial.println( accel_hg );
Serial.print( "Accel Any Motion " );
Serial.println( accel_am );
Serial.print( "Accel No Motion " );
Serial.println( accel_nm );
Serial.println( "---------------------------" );
}
/*
* Print the interrupt status
*/
void getInterruptStatusEnabled(bool synthetic) {
// 37 INT_STA 0x00 ACC_NM ACC_AM ACC_HIGH_G GYR_DRDY GYR_HIGH_RATE GYRO_AM MAG_DRDY ACC_BSX_DRDY
#pragma pack(push, 1)
struct StatusInterrupt {
byte accel_bsx_drdy : 1;
byte mag_drdy : 1;
byte gyro_am : 1;
byte gyro_high_rate : 1;
byte gyro_drdy : 1;
byte accel_high_g : 1;
byte accel_am : 1;
byte accel_nm : 1;
};
#pragma pack(pop)
StatusInterrupt registerByte = {0};
// Read all tht INT_STA addr to get all interrupt status in one read
// after the read the register is cleared
BNO055_RETURN_FUNCTION_TYPE res = bno055_read_register(BNO055_INT_STA_ADDR, (unsigned char *)(®isterByte), 1);
if (res == 0) {
if (synthetic){
Serial.print("Anm Aam Ahg Grd Ggr Gam Mrd Abr --> ");
Serial.print( registerByte.accel_nm );
Serial.print( registerByte.accel_am );
Serial.print( registerByte.accel_high_g );
Serial.print( registerByte.gyro_drdy );
Serial.print( registerByte.gyro_high_rate );
Serial.print( registerByte.gyro_am );
Serial.print( registerByte.mag_drdy );
Serial.println( registerByte.accel_bsx_drdy );
}else{
Serial.print( "Gyro Any Motion " );
Serial.println( registerByte.gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( registerByte.gyro_high_rate );
Serial.print( "Accel High G " );
Serial.println( registerByte.accel_high_g );
Serial.print( "Accel Any Motion " );
Serial.println( registerByte.accel_am );
Serial.print( "Accel No Motion " );
Serial.println( registerByte.accel_nm );
}
} else {
Serial.println("Error status!");
}
}
void printSlowMotionNoMotionParameters(){
unsigned char accel_slow_no_thr = 0;
bno055_get_accel_slow_no_threshold(&accel_slow_no_thr);
Serial.print("Slow motion/no motion threshold: ");
Serial.println(accel_slow_no_thr);
unsigned char accel_am_dur = 0;
bno055_get_accel_anymotion_duration(&accel_am_dur);
Serial.print("Slow motion/no motion duration: ");
Serial.println(accel_am_dur);
}
Now the same operation result in this Serial output. When we are going to raise an interrupt on the pin, I print more detailed information like so.
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 0
Accel No Motion 1
---------------
Here is the complete output.
Connetti alla porta seriale COM27 a 115200
---- Interrupt enabled ----
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 1
Accel No Motion 1
---------------------------
---- Interrupt bitmask ----
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 1
Accel No Motion 1
---------------------------
Slow motion/no motion threshold: 10
Slow motion/no motion duration: 3
2Secs - Orientation: 360.00, 363.00, 353.00 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
3Secs - Orientation: 360.00, 363.00, 353.00 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
4Secs - Orientation: 359.62, 363.00, 353.00 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 1
Accel No Motion 0
---------------
5Secs - Orientation: 358.00, 362.94, 353.00 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 1
Accel No Motion 0
---------------
6Secs - Orientation: 358.37, 362.56, 353.25 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 1
Accel No Motion 0
---------------
7Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
8Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
9Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
10Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
11Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
12Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 0
Accel Any Motion 0
Accel No Motion 1
---------------
13Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
14Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
15Secs - Orientation: 357.25, 363.06, 352.87 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
You can also manage any motion interrupt for a single axis by disabling the others.
// Disable anymotion on X axis
bno055_set_accel_an_nm_axis_enable(BNO055_ACCEL_AM_NM_X_AXIS, 0);
// Enable anymotion on Y axis
bno055_set_accel_an_nm_axis_enable(BNO055_ACCEL_AM_NM_Y_AXIS, 1);
As for others parameters, you can retrieve the value for the axis.
unsigned char xEnabled = 0;
bno055_get_accel_an_nm_axis_enable(BNO055_ACCEL_AM_NM_X_AXIS, &xEnabled);
Accelerometer High G Interrupt
This interrupt is based on the comparison of acceleration data against a high-g threshold for the detection of shock or other high-acceleration events.
Params | Value |
---|---|
Interrupt Parameters | Threshold |
Duration | |
Axis selection | X-axis |
Y-axis | |
Z-axis |
The high-g interrupt is enabled (disabled) per axis. By default all axes are disabled. The high-g threshold can be set.
// Disable high g on X axis
bno055_set_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_X_AXIS, 0);
// Enable high g on Y axis
bno055_set_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_Y_AXIS, 1);
And the inverse operation to retrieve the value.
unsigned char xEnabled = 0;
bno055_get_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_X_AXIS, &xEnabled);
The high-g interrupt is generated if the absolute value of the acceleration of at least one of the enabled axes (´or´ relation) is higher than the threshold for at least the time defined by the duration of high-g.
To set the duration, you can use this command.
bno055_set_accel_high_g_duration(15);
Where the parameter is a pointer ACC_HG_DURATION, and you can calculate the milliseconds in delay with [ms] = [ACC_HG_DURATION + 1] * 2 ms, the maximum value in milliseconds is 512 (7bit pointer value).
The high-g threshold depended on g-range configured, corresponding to 7.81 mg in 2g-range, 15.63 mg in 4g-range, 31.25 mg in 8g-range, and 62.5 mg in 16g-range (i.e. increment depends on g-range setting). To set the threshold, you can use this command.
bno055_set_accel_high_g_threshold(192);
The interrupt is reset if the absolute value of the acceleration of all enabled axes (´and´ relation) is lower than the threshold for at least the time defined by the high-g duration. Therefore, possible delay times range from 2 ms to 512 ms.
Here is a complete sketch.
/**
* bno055 simple interrupt management
* enable register interrupt and pin 15
* for high-g acceleration
* bit mask for interrupt pin on high-g acceleration
*
* by Renzo Mischianti <www.mischianti.org>
*
* https://mischianti.org/
*/
#include "BNO055_support.h" //Contains the bridge code between the API and Arduino
#include <Wire.h>
//The device address is set to BNO055_I2C_ADDR2 in this example. You can change this in the BNO055.h file in the code segment shown below.
// /* bno055 I2C Address */
// #define BNO055_I2C_ADDR1 0x28
// #define BNO055_I2C_ADDR2 0x29
// #define BNO055_I2C_ADDR BNO055_I2C_ADDR2
//Pin assignments as tested on the Arduino Due.
//Vdd,Vddio : 3.3V
//GND : GND
//SDA/SCL : SDA/SCL
//PSO/PS1 : GND/GND (I2C mode)
//This structure contains the details of the BNO055 device that is connected. (Updated after initialization)
struct bno055_t myBNO;
struct bno055_euler myEulerData; //Structure to hold the Euler data
unsigned long lastTime = 0;
/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (1000)
#define INTERRUPT_PIN 15
void getIntInterruptEnabled();
void getIntInterruptBitMaskEnabled();
void getInterruptStatusEnabled(bool synthetic = false);
void printAccelHighGParameters();
bool somethingHappened = false;
void IRAM_ATTR interruptCallback() {
somethingHappened = true;
}
void setup() //This code is executed once
{
//Initialize I2C communication
Wire.begin();
//Initialization of the BNO055
BNO_Init(&myBNO); //Assigning the structure to hold information about the device
// bno055_set_reset_sys(1);
delay(1500);
bno055_set_powermode(POWER_MODE_NORMAL);
// disable nomotion and anymotion
bno055_set_int_accel_anymotion(0);
bno055_set_int_accel_nomotion(0);
// Activate INT pin with bitmask
bno055_set_intmsk_accel_nomotion(0);
bno055_set_intmsk_accel_anymotion(0);
// Activate acceleration high-g and bit mask fot INT pin
bno055_set_int_accel_high_g(1);
bno055_set_intmsk_accel_high_g(1);
// bno055_set_accel_high_g_threshold(192);
// bno055_set_accel_high_g_duration(15);
bno055_set_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_X_AXIS, 1);
bno055_set_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_Y_AXIS, 1);
bno055_set_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_Z_AXIS, 1);
// reset all previous int signal
bno055_set_reset_int(1);
//Configuration to NDoF mode
bno055_set_operation_mode(OPERATION_MODE_NDOF);
delay(1);
//Initialize the Serial Port to view information on the Serial Monitor
Serial.begin(115200);
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(INTERRUPT_PIN, interruptCallback, RISING);
delay(1000);
getIntInterruptEnabled();
getIntInterruptBitMaskEnabled();
printAccelHighGParameters();
}
bool suspended = false;
bool reactivated = false;
void loop() //This code is looped forever
{
if ((millis() - lastTime) >= BNO055_SAMPLERATE_DELAY_MS) //To stream at 10Hz without using additional timers
{
lastTime = millis();
bno055_read_euler_hrp(&myEulerData); //Update Euler data into the structure
Serial.print(millis()/1000); Serial.print("Secs - ");
/* The WebSerial 3D Model Viewer expects data as heading, pitch, roll */
Serial.print(F("Orientation: "));
Serial.print(360-(float(myEulerData.h) / 16.00));
Serial.print(F(", "));
Serial.print(360-(float(myEulerData.p) / 16.00));
Serial.print(F(", "));
Serial.print(360-(float(myEulerData.r) / 16.00));
Serial.print(F(" - "));
getInterruptStatusEnabled(true);
}
if (somethingHappened) {
Serial.println("---------------");
getInterruptStatusEnabled();
Serial.println("---------------");
bno055_set_reset_int(1);
somethingHappened = false;
}
}
/*
* Print the interrupt enabled
*/
void getIntInterruptEnabled() {
unsigned char gyro_am = 0;
unsigned char gyro_hr = 0;
unsigned char accel_hg = 0;
unsigned char accel_am = 0;
unsigned char accel_nm = 0;
bno055_get_int_gyro_anymotion(&gyro_am);
bno055_get_int_gyro_highrate(&gyro_hr);
bno055_get_int_accel_high_g(&accel_hg);
bno055_get_int_accel_anymotion(&accel_am);
bno055_get_int_accel_nomotion(&accel_nm);
Serial.println( "---- Interrupt enabled ----" );
Serial.print( "Gyro Any Motion " );
Serial.println( gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( gyro_hr );
Serial.print( "Accel High G " );
Serial.println( accel_hg );
Serial.print( "Accel Any Motion " );
Serial.println( accel_am );
Serial.print( "Accel No Motion " );
Serial.println( accel_nm );
Serial.println( "---------------------------" );
}
/*
* Print the interrupt to send on interrupt pin
*/
void getIntInterruptBitMaskEnabled() {
unsigned char gyro_am = 0;
unsigned char gyro_hr = 0;
unsigned char accel_hg = 0;
unsigned char accel_am = 0;
unsigned char accel_nm = 0;
bno055_get_intmsk_gyro_anymotion(&gyro_am);
bno055_get_intmsk_gyro_highrate(&gyro_hr);
bno055_get_intmsk_accel_high_g(&accel_hg);
bno055_get_intmsk_accel_anymotion(&accel_am);
bno055_get_intmsk_accel_nomotion(&accel_nm);
Serial.println( "---- Interrupt bitmask ----" );
Serial.print( "Gyro Any Motion " );
Serial.println( gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( gyro_hr );
Serial.print( "Accel High G " );
Serial.println( accel_hg );
Serial.print( "Accel Any Motion " );
Serial.println( accel_am );
Serial.print( "Accel No Motion " );
Serial.println( accel_nm );
Serial.println( "---------------------------" );
}
/*
* Print the interrupt status
*/
void getInterruptStatusEnabled(bool synthetic) {
// 37 INT_STA 0x00 ACC_NM ACC_AM ACC_HIGH_G GYR_DRDY GYR_HIGH_RATE GYRO_AM MAG_DRDY ACC_BSX_DRDY
#pragma pack(push, 1)
struct StatusInterrupt {
byte accel_bsx_drdy : 1;
byte mag_drdy : 1;
byte gyro_am : 1;
byte gyro_high_rate : 1;
byte gyro_drdy : 1;
byte accel_high_g : 1;
byte accel_am : 1;
byte accel_nm : 1;
};
#pragma pack(pop)
StatusInterrupt registerByte = {0};
// Read all tht INT_STA addr to get all interrupt status in one read
// after the read the register is cleared
BNO055_RETURN_FUNCTION_TYPE res = bno055_read_register(BNO055_INT_STA_ADDR, (unsigned char *)(®isterByte), 1);
if (res == 0) {
if (synthetic){
Serial.print("Anm Aam Ahg Grd Ggr Gam Mrd Abr --> ");
Serial.print( registerByte.accel_nm );
Serial.print( registerByte.accel_am );
Serial.print( registerByte.accel_high_g );
Serial.print( registerByte.gyro_drdy );
Serial.print( registerByte.gyro_high_rate );
Serial.print( registerByte.gyro_am );
Serial.print( registerByte.mag_drdy );
Serial.println( registerByte.accel_bsx_drdy );
}else{
Serial.print( "Gyro Any Motion " );
Serial.println( registerByte.gyro_am );
Serial.print( "Gyro High Rate " );
Serial.println( registerByte.gyro_high_rate );
Serial.print( "Accel High G " );
Serial.println( registerByte.accel_high_g );
Serial.print( "Accel Any Motion " );
Serial.println( registerByte.accel_am );
Serial.print( "Accel No Motion " );
Serial.println( registerByte.accel_nm );
}
} else {
Serial.println("Error status!");
}
}
void printAccelHighGParameters(){
unsigned char accel_hg_dur = 0;
bno055_get_accel_high_g_duration(&accel_hg_dur);
Serial.print("Accel high-g duration: ");
Serial.println(accel_hg_dur);
unsigned char accel_hg_thr = 0;
bno055_get_accel_high_g_threshold(&accel_hg_thr);
Serial.print("Accel high-g threshold: ");
Serial.println(accel_hg_thr);
unsigned char xEnabled = 0;
bno055_get_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_X_AXIS, &xEnabled);
Serial.print("X axis high-g enabled: ");
Serial.println(xEnabled);
unsigned char yEnabled = 0;
bno055_get_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_Y_AXIS, &yEnabled);
Serial.print("Y axis high-g enabled: ");
Serial.println(yEnabled);
unsigned char zEnabled = 0;
bno055_get_accel_high_g_axis_enable(BNO055_ACCEL_HIGH_G_Z_AXIS, &zEnabled);
Serial.print("Z axis high-g enabled: ");
Serial.println(zEnabled);
}
The result in Serial output is this.
---- Interrupt enabled ----
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 1
Accel Any Motion 0
Accel No Motion 0
---------------------------
---- Interrupt bitmask ----
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 1
Accel Any Motion 0
Accel No Motion 0
---------------------------
Accel high-g duration: 15
Accel high-g threshold: 192
X axis high-g enabled: 1
Y axis high-g enabled: 1
Z axis high-g enabled: 1
2Secs - Orientation: 85.25, 363.37, 357.00 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
3Secs - Orientation: 90.00, 358.37, 355.62 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 1
Accel Any Motion 0
Accel No Motion 0
---------------
4Secs - Orientation: 94.19, 329.00, 368.44 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
---------------
Gyro Any Motion 0
Gyro High Rate 0
Accel High G 1
Accel Any Motion 0
Accel No Motion 0
---------------
5Secs - Orientation: 92.75, 341.56, 367.75 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
6Secs - Orientation: 86.69, 365.50, 360.56 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
7Secs - Orientation: 87.31, 364.56, 360.31 - Anm Aam Ahg Grd Ggr Gam Mrd Abr --> 00000000
You can see the output highlighted when I shake the sensor.
Thanks
- BNO055 accelerometer, gyroscope, magnetometer with basic Adafruit library
- BNO055 for esp32, esp8266, and Arduino: wiring and advanced Bosch library
- BNO055 for esp32, esp8266, and Arduino: features, configuration, and axes remap
- BNO055: power modes, accelerometer, and motion interrupt
- BNO055 for esp32, esp8266, and Arduino: enable INT pin and accelerometer High G Interrupt
- BNO055 for esp32, esp8266, and Arduino: Gyroscope High Rate and Any Motion Interrupt