Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU
ESP32 Projects

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

Mamtaz AlamBy Mamtaz AlamUpdated:April 27, 20268 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

Overview

In this article, we will be interfacing the BNO08x IMU with ESP32 to measure Pitch, Roll, and Yaw with very high accuracy and virtually no drift. The BNO08x family, which includes BNO080, BNO085, and BNO086, integrates an accelerometer, gyroscope, and magnetometer into a single sensor and uses advanced sensor fusion algorithms to provide stable orientation data, including drift-free yaw. You can build an IoT Activity Tracker project using BNO080.

Earlier, we implemented sensor fusion using the MPU6050 accelerometer-gyroscope and the HMC5883L magnetometer with ESP32 to measure Pitch, Roll, and Yaw. You can refer to the MPU6050 & HMC5883L Sensor Fusion article for that approach. However, the implementation required complex code and multiple algorithms, and the results were still not very accurate. Issues such as drift and noise were present even after careful tuning.

Another limitation was the hardware itself. The MPU6050, released around 2010, shows higher noise levels compared to modern IMUs. Additionally, the HMC5883L magnetometer is now obsolete, and the manufacturer has discontinued its production, making it unsuitable for new designs.

So the proper replacement for MPU6050 & HMC5883L is BNO08x. In this tutorial, we will implement the BNO08x complete setup using Arduino C++ code on the ESP32 and interface an OLED display to visualize real-time Pitch, Roll, and Yaw values. The displayed data is tested under static and dynamic conditions to verify measurement accuracy, stability, and yaw drift performance.


Bill of Materials

Following is the list of components that is required for this project.

S.N.Components NameQuantityPurchase Link
1ESP32 Board1Amazon | AliExpress
2BNO08x Accelerometer Gyroscope Magnetometer1Amazon | AliExpress
3OLED DisplayAmazon | AliExpress
4Connecting Wires10Amazon | AliExpress
5Breadboard2Amazon | AliExpress




BNO08X Accelerometer Gyroscope Magnetometer

BNO08x Module

The BNO08x is a high-performance 9-axis absolute orientation sensor module that integrates a triaxial accelerometer, gyroscope, magnetometer, and an onboard 32-bit ARM® Cortex-M0+ microcontroller in a compact System-in-Package (SiP). It is designed to function as a complete sensor hub, providing accurate motion, orientation, and heading information without requiring complex processing from the host microcontroller.

The module runs CEVA-Hillcrest’s SH-2 MotionEngine™ firmware, which performs real-time sensor fusion, dynamic calibration, and motion processing internally. By combining raw sensor data into stable outputs such as rotation vectors, quaternions, and linear acceleration, the BNO08x eliminates drift and reduces development effort while improving system reliability.

BNO08X block diagram
Fig: BNO08X block diagram

With support for multiple communication interfaces, including I²C, SPI, and UART, the BNO08x is well suited for applications such as robotics, wearable devices, AR/VR systems, and IoT platforms where low latency, low power consumption, and high-accuracy motion sensing are critical.

  • Check BNO08x Datasheet: BNO08x Datasheet

Core Features

  • 9-axis motion sensing: 3-axis accelerometer, gyroscope, and magnetometer
  • Integrated ARM® Cortex-M0+ MCU running SH-2 MotionEngine™ firmware
  • On-chip real-time sensor fusion with absolute orientation and heading output
  • Dynamic, continuous self-calibration for temperature variation and sensor aging
  • “Always-on” motion and activity detection:
    • Step counter
    • Tap detector
    • Stability and motion classification
  • Offloads motion processing from host MCU, reducing system power and CPU load
  • Android-compatible sensor hub architecture
  • Supports firmware upgrades via device firmware update (DFU)

Technical Specifications

Motion Sensors

  • Accelerometer: ±8 g range, 12-bit resolution
  • Gyroscope: ±2000 °/s range, 16-bit resolution
  • Magnetometer: 3-axis geomagnetic sensor



Motion Outputs

  • Orientation: Quaternion, Euler angles, rotation vectors
  • Linear acceleration and gravity vectors
  • Gyro rotation vector output up to 1 kHz (optimized for AR/VR)

Electrical Characteristics

  • Supply voltage (VDD): 2.4 V – 3.6 V
  • I/O voltage (VDDIO): 1.65 V – 3.6 V
  • Typical current consumption:
    • Low-power / always-on modes: tens of µA
    • Full sensor fusion operation: a few mA (mode and data rate dependent

Interfaces

  • I²C (up to 400 kHz)
  • SPI
  • UART (SHTP and UART-RVC modes)

Sensor Fusion Algorithm

The BNO08x uses CEVA-Hillcrest MotionEngine™, a real-time sensor fusion algorithm that combines accelerometer, gyroscope, and magnetometer data to generate accurate, stable, and drift-corrected motion outputs. The algorithm continuously processes raw sensor data to compute absolute orientation, angular motion, and gravity-compensated linear acceleration.

Fig: BNO08X axis orientation

MotionEngine™ performs automatic background calibration to compensate for sensor bias, temperature changes, and long-term drift. Gyroscope drift is corrected using accelerometer and magnetometer references, while magnetic distortion detection ensures reliable heading estimation in non-ideal environments.

Multiple fusion modes are supported, including Game, Geomagnetic, and AR/VR-stabilized rotation vectors, allowing optimization for either low latency or absolute accuracy. This approach provides the host MCU with ready-to-use motion data, reducing processing load and system complexity.



Pinout of BNO08x

The GY-BNO08x breakout board exposes ten essential pins required for power,
communication, interrupts, reset, and interface selection. These pins allow
the BNO08x to operate in I²C or SPI mode with minimal external
components.

Pin No. Pin Name Function
1 VCC Power supply input (typically 3.3 V). Supplies both the sensor core and the I/O
2 GND Ground reference
3 SCL I²C clock line (H_SCL)
4 SDA I²C data line (H_SDA)
5 ADO I²C address select (SA0). LOW = 0x4A, HIGH = 0x4B
6 CS SPI chip select (active low). Must be pulled HIGH when using I²C
7 INT Interrupt output (H_INTN), active low. Signals data ready or events
8 RST Active-low hardware reset (NRST)
9 PS1 Interface selection pin (Protocol Select 1)
10 PS0 Interface selection pin (Protocol Select 0 / SPI wake)

BNO08x Connectivity (Communication Protocol

The BNO08X can support connections to a host microcontroller through various serial interfaces:

  • I²C interface
  • UART interface
  • SPI interface
  • UART-RVC interface – a simplified UART interface for unmanned ground roving robots (such as robot vacuum cleaners)

In addition, the BNO08X includes a bootloader to allow for firmware upgrades. The bootloader can support
I²C, SPI, or UART. Access to the bootloader is achieved by setting BOOTN to 0.
Configuration of the communication interface is achieved by setting the protocol selection (PS1/PS0)
pins appropriately.

Protocol Selection for BNO08X

PS1 PS0 BNO08X (BOOTN = 1) BNO08X Bootloader (BOOTN = 0)
0 0 I²C I²C
0 1 UART-RVC Reserved
1 0 UART UART
1 1 SPI SPI

The protocol selection and BOOTN pins are sampled at reset.
PS0 is repurposed as a WAKE signal in SPI mode following reset.



BNO08x Module Schematic

Here is the typical application circuit for the BNO080 IMU, configured primarily for I²C communication with selectable address and interface control.

BNO08x Schematic


Differences Between BNO080, BNO085, and BNO086

Aspect BNO080 BNO085 BNO086
Sensor Fusion Firmware Standard SH-2 MotionEngine™ Enhanced MotionEngine™ Enhanced MotionEngine™
AR/VR Optimization No Yes Yes
Orientation Prediction Basic Improved prediction Improved prediction
Gyro Rotation Vector Latency Standard Lower latency Lower latency
Host-Based AR/VR Support Not supported Supported Supported
Intended Use General motion sensing AR/VR controllers & headsets AR/VR controllers & headsets
Firmware Feature Set Baseline Extended Extended / latest

Comparision Between MPU6050, BMI160, and BNO08x

Aspect MPU6050 BMI160 BNO08x (BNO080/85/86)
Sensor Type 6-axis IMU 6-axis IMU 9-axis Sensor Hub
Sensors Included Accelerometer + Gyroscope Accelerometer + Gyroscope Accelerometer + Gyroscope + Magnetometer
On-Chip MCU ❌ No ❌ No ✅ Yes (ARM Cortex-M0+)
Sensor Fusion ❌ Not onboard ❌ Not onboard ✅ On-chip MotionEngine™
Orientation Output Raw data only Raw data only Absolute orientation, quaternions, rotation vectors
Drift Compensation Host-side only Host-side only Automatic, real-time
Calibration Manual (host) Manual (host) Automatic background calibration
AR/VR Support ❌ No ❌ No ✅ Optimized (BNO085/086)
Host Processing Load High Medium Very low
Power Consumption Moderate Low Low (mode dependent)
Communication I²C I²C, SPI I²C, SPI, UART
Typical Use Case Basic motion sensing Wearables, low-power IMU Robotics, AR/VR, navigation
Complexity to Use Low Medium Very low (high-level data)




Interfacing BNO08x with ESP32 Microcontroller & OLED Display

Now let us interface the BNO08x IMU – BNO080, BNO085, and BNO086 – with the ESP32 microcontroller. This setup demonstrates how to connect the sensor and communicate with it to obtain accurate motion and orientation data.

The motion data can be displayed on 0.96″ I2C OLED Display.

Interfacing BNO08x with ESP32 Microcontroller & OLED Display
Fig: Interfacing BNO08x with ESP32 & OLED

The BNO08x IMU and OLED display are connected to the ESP32 via the I²C bus. Both devices share SDA (GPIO 21) and SCL (GPIO 22) lines, with VCC connected to 3.3 V and GND to common ground.

ESP32 BNO080 BNO085 BNO086

You can use the breadboard to connect BNO08x with ESP32 and OLED Display.


Source Code/Program for High-Accuracy Pitch, Roll, Yaw Measurement

Let’s write an Arduino C++ sketch to interface the BNO08x IMU (BNO080/085/086) with the ESP32 and continuously measure pitch, roll, and yaw in real time. The orientation data will be shown on a 0.96″ SSD1306 OLED so we can easily monitor changes as the sensor moves.

In this code, we will enable the BNO08x sensor fusion rotation vector, convert the quaternion/rotation vector output into human-readable Euler angles, and update the OLED smoothly at a fixed refresh rate.

One of the best features of the BNO08x module is the availability of a dedicated SparkFun library. To get started, download the SparkFun BNO08x library and install it in the Arduino IDE using the Library Manager or by adding it to the Arduino libraries folder.

Now copy the following code and upload it to the ESP32 microcontroller board.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <Wire.h>
#include "SparkFun_BNO080_Arduino_Library.h"
 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
// --------- Pins (ESP32 default I2C) ----------
#define SDA_PIN 21
#define SCL_PIN 22
 
// --------- I2C addresses ----------
#define BNO_ADDR  0x4B
#define OLED_ADDR 0x3C
 
// --------- OLED setup ----------
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
 
// --------- IMU ----------
BNO080 myIMU;
 
void setup() {
  Serial.begin(115200);
  delay(200);
 
  // Start I2C
  Wire.begin(SDA_PIN, SCL_PIN);
  Wire.setClock(400000);
 
  // Start OLED
  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.println("OLED not found at 0x3C");
    while (1) delay(10);
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
 
  // Start BNO080 at 0x4B
  if (!myIMU.begin(BNO_ADDR, Wire)) {
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0, 0);
    display.println("BNO080 not found");
    display.println("Check wiring");
    display.display();
    while (1) delay(10);
  }
 
  // Enable Euler angles (via Rotation Vector)
  myIMU.enableRotationVector(50); // 50ms (20Hz)
 
  // Header
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("BNO080 Euler (deg)");
  display.display();
}
 
void loop() {
  if (myIMU.dataAvailable()) {
    // Convert radians to degrees
    float roll  = myIMU.getRoll()  * 180.0f / PI;
    float pitch = myIMU.getPitch() * 180.0f / PI;
    float yaw   = myIMU.getYaw()   * 180.0f / PI;
 
    // OLED update
    display.clearDisplay();
 
    display.setTextSize(1);
    display.setCursor(0, 0);
    display.println("Roll / Pitch / Yaw");
 
    // Use larger text for readability
    display.setTextSize(2);
 
    display.setCursor(0, 18);
    display.print("R:");
    display.print(roll, 2);
 
    display.setCursor(0, 36);
    display.print("P:");
    display.print(pitch, 2);
 
    display.setCursor(0, 54);
    display.print("Y:");
    display.print(yaw, 2);
 
    display.display();
 
    // Optional serial (same format)
    Serial.print(roll, 2);  Serial.print(",");
    Serial.print(pitch, 2); Serial.print(",");
    Serial.println(yaw, 2);
  }
}




Testing of High-Accuracy Pitch, Roll, Yaw with BNO08x & ESP32

After uploading the code, the device is ready to test.

Pitch Roll Yaw ESP32 BNO08x

Once powered on, the 0.96-inch OLED will display real-time Pitch, Roll, and Yaw values from the BNO08x IMU.

BNO08X ESP32 Testing

Gently tilt the device forward/backward and left/right to observe changes in pitch and roll. Rotate the device horizontally to see the yaw value update, similar to a compass heading.

For accurate results, move the device slowly in all directions for a few seconds to stabilize the sensor fusion. When the device is stationary, the displayed values should remain steady. I used BNO080 to build an IoT Activity Tracker project. You can read that too.


Video Tutorial & Guide

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU | Sensor Fusion | Drift Fixed | No Noise
Watch this video on YouTube.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleDIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32
Next Article Building a Smart Sensor Node with a BLE Microcontroller

Related Posts

IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

Updated:May 10, 20261K
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

Updated:May 2, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

Updated:April 27, 20261K
DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

Updated:February 1, 20261K
Flight Black-Box Motion Recorder using ESP32 & BMI160

Flight Black-Box Motion Recorder System using ESP32 & BMI160

Updated:December 7, 20252K
Add A Comment

CommentsCancel reply

Latest Posts
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

May 31, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

February 1, 2026
Top Posts & Pages
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
  • IoT Based Drinking Water Quality Monitoring with ESP32
    IoT Based Drinking Water Quality Monitoring with ESP32
  • LD2410 Sensor with ESP32 - Human Presence Detection
    LD2410 Sensor with ESP32 - Human Presence Detection
  • ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
    ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
  • DIY IoT Water pH Meter using pH Sensor & ESP32
    DIY IoT Water pH Meter using pH Sensor & ESP32
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • How to use Modbus RTU with ESP32 to read Sensor Data
    How to use Modbus RTU with ESP32 to read Sensor Data
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (204)
    • ESP32 MicroPython (7)
    • ESP32 Projects (81)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.