A clean, plug-and-play Zephyr RTOS driver for the BNO08x IMU with Sensor Fusion.
The BNO08x is a powerful 9-axis System-in-Package (SiP) featuring an accelerometer, gyroscope, magnetometer, and a 32-bit ARM Cortex M0+ running Hillcrest Labs' SH-2 firmware. It outputs incredibly stable, pre-calculated quaternions, Euler angles, and activity classifications.
This repository packages the official Hillcrest SH-2 library into a native Zephyr Module, seamlessly handling I2C communication and exposing a clean API for your applications.
This driver is structured as a Zephyr out-of-tree module. To add it to your project, simply add it to your west.yml manifest file:
manifest:
projects:
- name: zephyr-bno08x
url: https://github.com/YourUsername/zephyr-bno08x # Replace with your actual repo URL!
revision: mainThen, run west update to fetch the module into your workspace.
Enable the module and the required Zephyr I2C subsystem in your prj.conf:
CONFIG_I2C=y
CONFIG_BNO08X=y
# (Optional) Enable floating point print support if you want to print the sensor values
CONFIG_CBPRINTF_FP_SUPPORT=yAdd the BNO08x to your board's device tree overlay on the appropriate I2C bus. Make sure to update the pins to match your hardware!
&i2c1 {
status = "okay";
clock-frequency = <I2C_BITRATE_FAST>; /* 400kHz recommended */
pinctrl-0 = <&i2c1_default>;
pinctrl-names = "default";
bno086: bno086@4b {
compatible = "i2c-device";
reg = <0x4B>; /* 0x4B is the default. Can be 0x4A depending on the SA0 pin */
label = "BNO086";
};
};
(Note: The driver currently assumes the devicetree node is labeled bno086 and uses address 0x4B).
Here is a minimal example of how to initialize the sensor and read the Game Rotation Vector (quaternions) to calculate pitch, roll, and yaw.
#include <zephyr/kernel.h>
#include <bno08x/bno08x.h>
void main(void) {
printk("Starting BNO08x test...\n");
// 1. Initialize the sensor
if (bno08x_init() != SH2_OK) {
printk("Failed to initialize BNO08x!\n");
return;
}
// 2. Enable the Game Rotation Vector report at 100Hz (10,000 microseconds)
bno08x_enable_report(SH2_GAME_ROTATION_VECTOR, 10000);
sh2_SensorValue_t sensor_data;
bno08x_euler_t euler;
while (1) {
// 3. Poll the sensor for new data
if (bno08x_get_sensor_event(&sensor_data)) {
if (sensor_data.sensorId == SH2_GAME_ROTATION_VECTOR) {
// Convert raw quaternion into degrees
bno08x_quaternion_to_euler(
sensor_data.un.gameRotationVector.real,
sensor_data.un.gameRotationVector.i,
sensor_data.un.gameRotationVector.j,
sensor_data.un.gameRotationVector.k,
&euler, true
);
printk("Pitch: %.1f | Roll: %.1f | Yaw: %.1f\n",
(double)euler.pitch, (double)euler.roll, (double)euler.yaw);
}
}
k_msleep(1);
}
}This module wraps the original Hillcrest Laboratories SH-2 library.
The core SH-2 library and the Zephyr wrapper code are provided under the Apache License 2.0. See the LICENSE file for details.