Site icon Renzo Mischianti

BNO055 for esp32, esp8266, and Arduino: wiring and advanced Bosch library – 2

Spread the love

This is the second article on bno055. If you need basic management, you can refer to the previous article, “BNO055 accelerometer, gyroscope, magnetometer with basic Adafruit library“, but if you need advanced management (and more complex) with interrupt, you must read this article also.

The BNO055 is a System in Package (SiP), integrating a triaxial 14-bit accelerometer, a triaxial 16-bit gyroscope with a range of ±2000 degrees per second, a triaxial geomagnetic sensor, and a 32-bit cortex M0+ microcontroller running Bosch Sensortec sensor fusion software, in a single package.

BNO055: ESP32, esp8266, rp2040, stm32, and Arduino wiring and Bosch library

The BNO055 can output the following sensor data:

BNO055 pinouts

Exists a lot of module versions of this sensor, I choose the smallest and cheap.

Here the module Aliexpress

All these modules had the same features, but to enable them, you must do different operations.

This is the clone I use:

BNO055 pinout mischianti

And here is the Adafruit one:

Adafruit bno055 pinout specs

The sensor supports a 3.3v logic level, but the module can be powered by 5v.

You can communicate via i2c (default option) and via UART, to activate the last modality you must desolder PS1.

PS1PS0Functionality
00Standard/Fast I2C Interface
01HID over I2C
10UART Interface
11Reserved

In standard i2c mode, you can select two addresses. By default, in this module, the address 0x29 is active. If you put to GND the ADD pin, the address becomes 0x28.

i2c configurationADDI2C address
SlaveHIGH0x29
SlaveLOW (default)0x28
HID-I2C0x40

INT is configured as an interrupt pin for signaling an interrupt to the host. The interrupt trigger is configured as a raising edge and is latched onto the INT pin. Once an interrupt occurs, the INT pin is set to high and will remain high until it is reset by the host.

Basic connections

For basic i2c usage, you must only connect VCC, GND, SDA, and SCL.

Wiring Arduino UNO

The Adafruit version of the sensor is well documented, and It fully supports the 5v logic level.

Arduino UNO bno055 adafruit wiring breadboard

The clone version was not clear if It fully supports a 5v logic level, but it surely supports a 5v power supply. I try to use Arduino UNO, and It works correctly without LLC.

Arduino UNO bno055 clone wiring breadboard

Here the Arduino boards Arduino UNO - Arduino MEGA 2560 R3 - Arduino Nano - Arduino Pro Mini

Wiring esp32

ESP32 DOIT DEV KIT v1 pinout

The esp32 worked at 3.3v, so wiring was easier.

esp32 bno055 adafruit wiring breadboard

And here is the clone.

esp32 bno055 clone wiring breadboard

Here my selection of 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

Wiring esp8266

WeMos D1 mini esp8266 pinout

esp8266 like esp32 work at 3.3v, so the wiring is linear.

esp8266 WeMos D1 mini bno055 adafruit wiring

And now the clone.

esp8266 WeMos D1 mini bno055 clone wiring

Here my selection of esp8266 boards WeMos D1 mini - NodeMCU V2 V2.1 V3 - esp01 - esp01 programmer

Bosch complete library

Bosh offers a completed but undocumented and not structured library.

You can download the library from GitHub here. Or you can directly download it from the Arduino IDE libraries manager.

bno055 bosch library interrupt Arduino IDE

Yaw, roll, and pitch sketch example

When we need to control robotics, aero, or machine, the better solution is to use Yaw, roll, and pitch. I added some figures to understand where these values are positioned.

Airplane yaw roll pitch axis

The bosh sensor can give elaborated data, one example is the Euler_Streaming on the BNO055 library.

/*
 ***************************************************************************

    Euler_Streaming.pde - part of sample SW for using BNO055 with Arduino

   (C) All rights reserved by ROBERT BOSCH GMBH

   Copyright (C) 2014 Bosch Sensortec GmbH

 	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 **************************************************************************/
/*	Date: 2014/01/07
 	 Revision: 1.2

*/

#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;

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

  //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);
}

void loop() //This code is looped forever
{
  if ((millis() - lastTime) >= 100) //To stream at 10Hz without using additional timers
  {
    lastTime = millis();

    bno055_read_euler_hrp(&myEulerData);			//Update Euler data into the structure

    Serial.print("Time Stamp: ");				//To read out the Time Stamp
    Serial.println(lastTime);

    Serial.print("Heading(Yaw): ");				//To read out the Heading (Yaw)
    Serial.println(float(myEulerData.h) / 16.00);		//Convert to degrees

    Serial.print("Roll: ");					//To read out the Roll
    Serial.println(float(myEulerData.r) / 16.00);		//Convert to degrees

    Serial.print("Pitch: ");				//To read out the Pitch
    Serial.println(float(myEulerData.p) / 16.00);		//Convert to degrees

    Serial.println();					//Extra line to differentiate between packets
  }
}

And the result in serial output is:

Car yaw roll pitch axis
Time Stamp: 6500
Heading(Yaw): 182.50
Roll: -3.44
Pitch: -26.00

Time Stamp: 6600
Heading(Yaw): 187.69
Roll: -16.37
Pitch: -18.69

Time Stamp: 6700
Heading(Yaw): 193.50
Roll: -27.75
Pitch: -8.25

Time Stamp: 6800
Heading(Yaw): 197.44
Roll: -34.81
Pitch: 1.19

Time Stamp: 6900
Heading(Yaw): 199.87
Roll: -37.25
Pitch: 9.00

Time Stamp: 7000
Heading(Yaw): 201.25
Roll: -36.88
Pitch: 16.25

Time Stamp: 7100
Heading(Yaw): 199.94
Roll: -30.75
Pitch: 21.94

Time Stamp: 7200
Heading(Yaw): 198.25
Roll: -20.62
Pitch: 27.50

Time Stamp: 7300
Heading(Yaw): 196.50
Roll: -12.44
Pitch: 30.31

Time Stamp: 7400
Heading(Yaw): 196.19
Roll: -4.06
Pitch: 31.44

Time Stamp: 7500
Heading(Yaw): 194.31
Roll: 4.50
Pitch: 31.31

Time Stamp: 7600
Heading(Yaw): 190.56
Roll: 12.75
Pitch: 28.00

Time Stamp: 7700
Heading(Yaw): 186.87
Roll: 22.94
Pitch: 23.12

Time Stamp: 7800
Heading(Yaw): 184.62
Roll: 29.81
Pitch: 19.37

Time Stamp: 7900
Heading(Yaw): 182.75
Roll: 35.19
Pitch: 15.94

Time Stamp: 8000
Heading(Yaw): 181.12
Roll: 42.63
Pitch: 11.63

Time Stamp: 8100
Heading(Yaw): 180.37
Roll: 47.56
Pitch: 9.13

Time Stamp: 8200
Heading(Yaw): 181.69
Roll: 53.44
Pitch: 4.12

Time Stamp: 8300
Heading(Yaw): 184.31
Roll: 57.81
Pitch: -0.94

Time Stamp: 8400
Heading(Yaw): 183.44
Roll: 60.81
Pitch: -3.62

These values were the basic elements for all machines, such as cars or boats.

Boat yaw roll pitch axis

And can be managed with 10Hz frequencies. I checked that the noise was managed very well.

Move 3d bunny with WebGL and absolute position.

Here I write a simple sketch like Adafruit one (check the previous BNO055 article) that reads the serial data and converts it to a 3D rotation to do that in a simple way using Web Serial API for Chrome browser.

So first, you need Chrome.

Then you must enable WebSerial API, and do that, you must put in the browser input URL chrome://flags then search (with Ctrl+f) Experimental Web Platform features and enable It.

Chrome enables Experimental Web Platform features.

Then load the example.

/**
 * Simple example with bosch library for bno055 to work with
 * Adafruit webGL example with euler angles
 * https://adafruit.github.io/Adafruit_WebSerial_3DModelViewer/
 *
 * 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 char accelCalibStatus = 0;		//Variable to hold the calibration status of the Accelerometer
unsigned char magCalibStatus = 0;		//Variable to hold the calibration status of the Magnetometer
unsigned char gyroCalibStatus = 0;		//Variable to hold the calibration status of the Gyroscope
unsigned char sysCalibStatus = 0;		//Variable to hold the calibration status of the System (BNO055's MCU)

unsigned long lastTime = 0;

/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (100)

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

  //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);
}

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

    /* 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.println(F(""));

	bno055_get_accelcalib_status(&accelCalibStatus);
	bno055_get_gyrocalib_status(&gyroCalibStatus);
	bno055_get_syscalib_status(&sysCalibStatus);
	bno055_get_magcalib_status(&magCalibStatus);

	Serial.print(F("Calibration: "));
	Serial.print(sysCalibStatus, DEC);
	Serial.print(F(", "));
	Serial.print(gyroCalibStatus, DEC);
	Serial.print(F(", "));
	Serial.print(accelCalibStatus, DEC);
	Serial.print(F(", "));
	Serial.print(magCalibStatus, DEC);
	Serial.println(F(""));


  }
}

Now open in the browser this URL:

https://adafruit.github.io/Adafruit_WebSerial_3DModelViewer/

Select 115200 baud, click connect and select the correct device serial port.

The result is that you can change the orientation of the bunny with the movement of bno055.

https://cdn-learn.adafruit.com/assets/assets/000/091/721/large1024mp4/sensors_animated.mp4

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
Exit mobile version