Using the BNO08x with Arduino is a simple matter of wiring up the sensor to your Arduino-compatible microcontroller, installing the Adafruit BNO08x library, and running the provided example code.

Because of the size and complexity of the BNO08x library, you will have to use an Arduino-compatible with a larger amount of memory such as the SAMD21, SAMD51, nRF52, ESP, Mega, etc. Arduino Uno or Leonardo will not work due to minimal RAM
The examples below show Metro and Feather M4s, and reference their 3.3V logic level for power connections. If using a board with a 5V logic level, connect the BNO085 Vin to 5V instead
The BNO08x I2C implementation violates the I2C protocol in some circumstances. This causes it not to work well with certain chip families. It does not work well with Espressif ESP32, ESP32-S3, and NXP i.MX RT1011, and it does not work well with I2C multiplexers. Operation with SAMD51, RP2040, STM32F4, and nRF52840 is more reliable.

I2C Wiring

Use this wiring if you want to connect via I2C interface. The default I2C address for the BNO08x is 0x4A but it can be switched to 0x4B by pulling the DI pin high to VCC. 

Here is how to wire up the sensor using one of the STEMMA QT connectors. The examples show a Metro but wiring will work the same for an Arduino or other compatible board.

  • Connect board VIN (red wire) to Board 3V 
  • Connect board GND (black wire) to Board GND
  • Connect board SCL (yellow wire) to Board SCL
  • Connect board SDA (blue wire) to Board SDA

Here is how to wire the sensor to a board using a solderless breadboard:

  • Connect board VIN (red wire) to Board 3V 
  • Connect board GND (black wire) to Board GND
  • Connect board SCL (yellow wire) to Board SCL
  • Connect board SDA (blue wire) to Board SDA

UART Wiring

  • BNO085 Vin to the power supply, using the same logic level as your microcontroller. For the Metro M4 shown that is 3.3V, however check your board's documentation to be sure
  • BNO085 GND to board GND
  • BNO085 SCL to board TX
  • BNO085 SDA to board RX
  • BNO085 P1 to Board Power supply

SPI Wiring

Finally for SPI we are using a Feather M4 for the wiring diagram to make it easier to read. If using an Arduino compatible or other different shaped board, you will still connect to the same pin names to ensure that you use hardware SPI

  • BNO085 Vin to 3V on the Feather M4
  • BNO085 GND to common power/data ground
  • BNO085 SCL to the SPI SCK pin on the Feather M4
  • BNO085 SDA pin to the SPI MISO pin on the Feather M4
  • BNO085 DI  to  the SPI MOSI pin on the Feather M4
  • BNO085 CS to pin #10 on the Feather M4
  • BNO085 INT to pin #9 on the Feather M4
  • BNO085 RST to pin #5 on the Feather M4
  • BNO085 P0 and P1 to 3V on the Feather M4
This is a lot of wires! You may be tempted to omit the INT and RST pin connections but do not! They are required for a good SPI connection

Library Installation

You can install the Adafruit BNO08x library for Arduino using the Library Manager in the Arduino IDE.

Click the Manage Libraries ... menu item, search for Adafruit BNO08x, and select the Adafruit BNO08x library:

Follow the same process for the Adafruit BusIO library.

Load Example

This example shows the Rotation Vector report however there are *many* more. See the Report Types page for more information

Open up File -> Examples -> Adafruit BNO08x -> rotation_vector

After opening the demo file, upload the compiled code to your Arduino wired up to the sensor. Once you upload the code, you will see the rotation vector quaternion values being printed when you open the Serial Monitor (Tools->Serial Monitor) at 115200 baud, similar to this:

Example Code

// Basic demo for readings from Adafruit BNO08x
#include <Adafruit_BNO08x.h>

// For SPI mode, we need a CS pin
#define BNO08X_CS 10
#define BNO08X_INT 9

// For SPI mode, we also need a RESET 
//#define BNO08X_RESET 5
// but not for I2C or UART
#define BNO08X_RESET -1

Adafruit_BNO08x  bno08x(BNO08X_RESET);
sh2_SensorValue_t sensorValue;

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit BNO08x test!");

  // Try to initialize!
  if (!bno08x.begin_I2C()) {
  //if (!bno08x.begin_UART(&Serial1)) {  // Requires a device with > 300 byte UART buffer!
  //if (!bno08x.begin_SPI(BNO08X_CS, BNO08X_INT)) {
    Serial.println("Failed to find BNO08x chip");
    while (1) { delay(10); }
  }
  Serial.println("BNO08x Found!");

  for (int n = 0; n < bno08x.prodIds.numEntries; n++) {
    Serial.print("Part ");
    Serial.print(bno08x.prodIds.entry[n].swPartNumber);
    Serial.print(": Version :");
    Serial.print(bno08x.prodIds.entry[n].swVersionMajor);
    Serial.print(".");
    Serial.print(bno08x.prodIds.entry[n].swVersionMinor);
    Serial.print(".");
    Serial.print(bno08x.prodIds.entry[n].swVersionPatch);
    Serial.print(" Build ");
    Serial.println(bno08x.prodIds.entry[n].swBuildNumber);
  }

  setReports();

  Serial.println("Reading events");
  delay(100);
}

// Here is where you define the sensor outputs you want to receive
void setReports(void) {
  Serial.println("Setting desired reports");
  if (! bno08x.enableReport(SH2_GAME_ROTATION_VECTOR)) {
    Serial.println("Could not enable game vector");
  }
}


void loop() {
  delay(10);

  if (bno08x.wasReset()) {
    Serial.print("sensor was reset ");
    setReports();
  }
  
  if (! bno08x.getSensorEvent(&sensorValue)) {
    return;
  }
  
  switch (sensorValue.sensorId) {
    
    case SH2_GAME_ROTATION_VECTOR:
      Serial.print("Game Rotation Vector - r: ");
      Serial.print(sensorValue.un.gameRotationVector.real);
      Serial.print(" i: ");
      Serial.print(sensorValue.un.gameRotationVector.i);
      Serial.print(" j: ");
      Serial.print(sensorValue.un.gameRotationVector.j);
      Serial.print(" k: ");
      Serial.println(sensorValue.un.gameRotationVector.k);
      break;
  }

}

This guide was first published on Oct 14, 2020. It was last updated on Sep 18, 2020.

This page (Arduino) was last updated on Sep 18, 2020.

Text editor powered by tinymce.