# BNO085 IMU Driver for ESP-IDF
A clean, professional ESP-IDF component for the Bosch BNO085 9-axis IMU (3-axis accelerometer, 3-axis gyroscope, 3-axis magnetometer) via the CEVA SH2 sensor hub protocol over I2C.
## Features
- **9-DOF Sensor Fusion**: Accelerometer, gyroscope, and magnetometer with on-chip fusion
- **Multiple Output Types**: Rotation vectors (quaternions), linear acceleration, raw acceleration, calibrated gyroscope, calibrated magnetic field
- **Simple Handle-Based API**: Opaque handles, no sh2 types exposed to user code
- **Fully Decoupled**: SH2 library abstracted behind clean component API
- **Callback-Based Data Delivery**: Sensor events trigger user callbacks with decoded data
- **ESP-IDF Idioms**: Configuration structs, error codes, proper documentation
## Hardware Setup
### Wiring (Heltec LoRa V3 example)
| BNO085 Pin | ESP32-S3 Pin | Signal | Notes |
|------------|--------------|--------------|-----------------|
| SDA | GPIO 6 | I2C SDA | Pull-up enabled |
| SCL | GPIO 7 | I2C SCL | Pull-up enabled |
| INT (H_INTN)| GPIO 5 | Interrupt | Active-low |
| RST (NRST) | GPIO 4 | Reset | Active-low |
| AD0 | GND | Slave addr | I2C addr 0x4A |
| VCC | 3.3V | Power | |
| GND | GND | Ground | |
**Critical**: PS0 and PS1 pins must be tied to GND for I2C mode operation.
## Installation
### From ESP-IDF Component Registry
```bash
idf.py add-dependency bno085
```
### From Git Submodule (Development)
```bash
git submodule add https://github.com/<your-username>/bno085_aula8.git components/bno085
git submodule update --init --recursive
```
## Quick Start
```c
#include "bno085.h"
#include "driver/i2c_master.h"
#include "freertos/task.h"
static void sensor_callback(bno085_handle_t handle,
const bno085_sensor_value_t *value,
void *user_context)
{
if (value->sensor_id == BNO085_SENSOR_ROTATION_VECTOR) {
printf("Quaternion: i=%.4f, j=%.4f, k=%.4f, real=%.4f\n",
value->data.rotation_vector.i,
value->data.rotation_vector.j,
value->data.rotation_vector.k,
value->data.rotation_vector.real);
}
}
void app_main(void)
{
// Set up I2C bus (existing code)
i2c_master_bus_config_t bus_config = { /* ... */ };
i2c_master_bus_handle_t bus_handle;
i2c_new_master_bus(&bus_config, &bus_handle);
i2c_device_config_t dev_config = { /* ... */ };
i2c_master_dev_handle_t dev_handle;
i2c_master_bus_add_device(bus_handle, &dev_config, &dev_handle);
// Initialize BNO085 with default config
bno085_config_t config;
bno085_config_default(&config);
bno085_handle_t bno085;
bno085_init(&config, dev_handle, GPIO_INT_PIN, GPIO_RST_PIN, &bno085);
// Register callback and enable sensor
bno085_register_sensor_callback(bno085, sensor_callback, NULL);
bno085_enable_sensor(bno085, BNO085_SENSOR_ROTATION_VECTOR, 100000); // 10Hz
// Service in main loop (10ms recommended)
while (1) {
bno085_service(bno085);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
```
## API Reference
### Initialization
```c
esp_err_t bno085_init(const bno085_config_t *config,
i2c_master_dev_handle_t i2c_dev,
gpio_num_t int_pin,
gpio_num_t reset_pin,
bno085_handle_t *out_handle);
```
Initialize the BNO085 with I2C device and GPIO pins. Only one instance can be active at a time (due to underlying SH2 library singleton design).
### Service Loop
```c
void bno085_service(bno085_handle_t handle);
```
Poll the device for pending sensor reports. Call periodically (10ms recommended) from the main loop.
### Cleanup
```c
void bno085_deinit(bno085_handle_t handle);
```
Close the device and free resources.
### Callbacks
```c
typedef void (*bno085_sensor_callback_t)(bno085_handle_t handle,
const bno085_sensor_value_t *value,
void *user_context);
esp_err_t bno085_register_sensor_callback(bno085_handle_t handle,
bno085_sensor_callback_t callback,
void *user_context);
```
Register a function to be called whenever sensor data is available. Replaces any previous callback.
### Sensor Control
```c
esp_err_t bno085_enable_sensor(bno085_handle_t handle,
uint8_t sensor_id,
uint32_t report_interval_us);
esp_err_t bno085_disable_sensor(bno085_handle_t handle,
uint8_t sensor_id);
```
Enable/disable individual sensors with specified reporting interval.
## Supported Sensors
The driver decodes the following five sensor types with named fields:
| Sensor ID | Constant | Output Type | Use Case |
|-----------|----------|-------------|----------|
| 0x01 | `BNO085_SENSOR_ACCELEROMETER` | `data.accelerometer` | Motion detection with gravity |
| 0x02 | `BNO085_SENSOR_GYROSCOPE_CALIBRATED` | `data.gyroscope` | Angular velocity (rad/s) |
| 0x03 | `BNO085_SENSOR_MAGNETIC_FIELD_CALIBRATED` | `data.magnetic_field` | Magnetometer (µTesla) |
| 0x04 | `BNO085_SENSOR_LINEAR_ACCELERATION` | `data.linear_acceleration` | Motion without gravity |
| 0x05 | `BNO085_SENSOR_ROTATION_VECTOR` | `data.rotation_vector` | Orientation as quaternion |
Other SH2 sensors (step counter, activity classifier, etc.) can be enabled via raw sensor IDs, but data arrives undecoded (only `sensor_id`, `status`, `timestamp_us` populated).
See `SENSOR_GUIDE.md` in this directory for the complete list of all 40+ available sensors and example usage patterns.
## Configuration
```c
typedef struct {
uint32_t i2c_timeout_ms; // I2C operation timeout (default: 100ms)
uint8_t reset_retry_count; // Soft-reset retries (default: 5)
uint32_t reset_retry_delay_ms; // Delay between retries (default: 30ms)
uint32_t reset_settle_delay_ms; // Delay after reset (default: 300ms)
} bno085_config_t;
void bno085_config_default(bno085_config_t *config);
```
Use `bno085_config_default()` to get recommended values, then customize as needed.
## Limitations
- **Single Instance Only**: The underlying SH2 library uses a global state (`sh2_t _sh2`), so only one BNO085 can be initialized at a time. Calling `bno085_init()` while another instance is active returns `ESP_ERR_INVALID_STATE`.
- **Decoded Sensors**: Only 5 sensor types (listed above) have built-in decoding to named fields. Other sensors can be enabled but arrive raw (metadata only).
## Example Projects
See `examples/basic_read/` for a self-contained example that initializes the device and prints rotation vectors.
## License
Apache-2.0. Contains the CEVA SH2 library (Apache-2.0 with NOTICE.txt).
## Support
- GitHub Issues: Report bugs or request features
- Datasheet: BNO085 datasheet available from Bosch Sensortec
- SH2 Reference: See `sh2/README.md` for protocol details
80acb2975269619a100a5622c4dd4c0fc3c9f93f
idf.py add-dependency "rinku404/bno085^1.0.0"