BNO055 for esp32, esp8266 and Arduino: enable INT pin and accelerometer High G Interrupt – 5

Spread the love

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.

BNO055 for esp32, esp8266 and Arduino: enable INT pin and accelerometer High G Interrupt
BNO055 for esp32, esp8266 and Arduino: enable INT pin and accelerometer High G Interrupt

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:

BNO055 pinout mischianti
BNO055 pinout mischianti

And here is the Adafruit one:

Adafruit bno055 pinout specs
Adafruit bno055 pinout specs

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

ESP32 DOIT DEV KIT v1 pinout
ESP32 DOIT DEV KIT v1 pinout

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

esp32 bno055 adafruit wiring interrupt
esp32 bno055 adafruit wiring interrupt

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);
esp32 bno055 clone wiring interrupt
esp32 bno055 clone wiring interrupt

Arduino interrupt management

The Arduino boards have some pins that can be used as interrupts,

BOARDDIGITAL PINS USABLE FOR INTERRUPTS
Uno, Nano, Mini, other 328-based2, 3
Uno WiFi Rev.2, Nano Everyall digital pins
Mega, Mega2560, MegaADK2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based0, 1, 2, 3, 7
Zeroall digital pins, except 4
MKR Family boards0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Nano 33 IoT2, 3, 9, 10, 11, 13, A1, A5, A7
Nano 33 BLE, Nano 33 BLE Senseall pins
Dueall digital pins
101all 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,

Arduino UNO bno055 adafruit wiring interrupt
Arduino UNO bno055 adafruit wiring interrupt

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

WeMos D1 mini esp8266 pinout mischianti low resolution
WeMos D1 mini esp8266 pinout mischianti low resolution

esp8266 like esp32 has a lot of interrupt pins, and the management also is similar. Here is the wiring schema for the Adafruit sensor.

esp8266 WeMos D1 mini bno055 adafruit cablaggio con interrupt
esp8266 WeMos D1 mini bno055 adafruit cablaggio con interrupt

Here is the wiring schema for clone bno055.

esp8266 WeMos D1 mini bno055 clone wiring interrupt
esp8266 WeMos D1 mini bno055 clone wiring interrupt

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.

esp32 bno055 adafruit wiring interrupt
esp32 bno055 adafruit wiring interrupt

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.

ParamsValue
Interrupt ParametersThreshold
 Duration
Axis selectionX-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

  1. BNO055 accelerometer, gyroscope, magnetometer with basic Adafruit library
  2. BNO055 for esp32, esp8266, and Arduino: wiring and advanced Bosch library
  3. BNO055 for esp32, esp8266, and Arduino: features, configuration, and axes remap
  4. BNO055: power modes, accelerometer, and motion interrupt
  5. BNO055 for esp32, esp8266, and Arduino: enable INT pin and accelerometer High G Interrupt
  6. BNO055 for esp32, esp8266, and Arduino: Gyroscope High Rate and Any Motion Interrupt

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *