{"id":21815351,"url":"https://github.com/eupn/bno055","last_synced_at":"2025-04-12T21:20:00.910Z","repository":{"id":41539700,"uuid":"169385565","full_name":"eupn/bno055","owner":"eupn","description":"Device-agnostic Bosch Sensortec BNO055 9-axis Sensor Fusion IMU driver","archived":false,"fork":false,"pushed_at":"2024-11-26T04:30:13.000Z","size":331,"stargazers_count":70,"open_issues_count":5,"forks_count":21,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-04T00:48:56.955Z","etag":null,"topics":["bno055","embedded-hal-driver","no-std","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eupn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-06T10:03:55.000Z","updated_at":"2025-02-20T05:41:17.000Z","dependencies_parsed_at":"2025-02-12T07:13:25.251Z","dependency_job_id":"698dfdaa-6bb2-4bdd-8b76-e1fe7c424667","html_url":"https://github.com/eupn/bno055","commit_stats":{"total_commits":77,"total_committers":11,"mean_commits":7.0,"dds":"0.16883116883116878","last_synced_commit":"77883b7cc831d66037ff20dcc99bd1d5260e25ab"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eupn%2Fbno055","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eupn%2Fbno055/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eupn%2Fbno055/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eupn%2Fbno055/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eupn","download_url":"https://codeload.github.com/eupn/bno055/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248632181,"owners_count":21136640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bno055","embedded-hal-driver","no-std","rust"],"created_at":"2024-11-27T15:18:07.602Z","updated_at":"2025-04-12T21:20:00.884Z","avatar_url":"https://github.com/eupn.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Bosch Sensortec BNO055 embedded-hal driver\n\n[![](https://img.shields.io/crates/v/bno055.svg?style=flat)](https://crates.io/crates/bno055)\n[![docs.rs](https://docs.rs/bno055/badge.svg)](https://docs.rs/bno055/)\n[![](https://img.shields.io/crates/d/bno055.svg?maxAge=3600)](https://crates.io/crates/bno055)\n\n\u003cimg src=\"bno055.jpg\" width=\"400\" height=\"400\"\u003e\n\n## What is this?\n\nThis is a [embedded-hal](https://github.com/rust-embedded/embedded-hal) driver\nfor Bosch's Absolute Orientation Sensor [BNO055](https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BNO055-DS000.pdf).\n\nIt is device-agnostic and uses embedded-hal's `Write`/`WriteRead` (for I2C)\nand `Delay` traits for its operation.\n\nUses and re-exports [mint](https://crates.io/crates/mint)'s\n[Quaternion](https://docs.rs/mint/0.5.1/mint/struct.Quaternion.html) for quaternion reading\nand [EulerAngles](https://docs.rs/mint/0.5.1/mint/struct.EulerAngles.html) for Euler angles\nand [Vector3](https://docs.rs/mint/0.5.1/mint/struct.Vector3.html) for sensor readings.\n\n## Usage notes\n### Important note on I2C issues\nAs [noted e.g. by Adafruit](https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor) the sensor has issues\nwith its I2C implementation, which causes it to not work correctly with certain microcontrollers.\n\nThis seems to be caused by clock stretching, thus running at lower I2C speeds and with increased I2C timeouts should\nresolve the issue.\n\n### Initial startup delay\nThe sensor has an initial startup time during which interaction with it will fail.\nAs per [the documentation](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bno055-ds000.pdf)\nthis is in the 400ms - 650ms range (consult chapter 1.2 / page 14 for further details).\nIf your microcontroller is faster in starting up you might have to delay before talking to the sensor (or retry on failure).\n\n## Feature flags\n\n### `std`\n\nBy default, this crate is `no_std` compatible. However, you can enable `std` features by enabling the `std` feature flag.\nAt the moment this only adds `std::error::Error` trait implementation for the `Error` type.\n\n### `serde`\n\nThe `serde` flag adds implementation of `Serialize` / `Deserialize` to `BNO055Calibration`.\n\n**Note:** `serde` itself is `no_std` compatible, however not all serializers are (e.g. `serde-json` is not but `serde-json-core` is),\nso be careful that you're not enabling `serde`'s `std` feature by accident (see [here](https://serde.rs/no-std.html#no-std-support) for a complete explanation).\n\n## Usage\n\n1. Add a dependency to `Cargo.toml`:\n\n    ```bash\n    cargo add bno055\n    ```\n\n2. Instantiate and init the device:\n\n    ```rust\n    // ... declare and configure your I2c and Delay implementations ...\n    // let i2c = ...;\n    // let delay = ...;\n\n    // Init BNO055 IMU\n    let mut imu = bno055::Bno055::new(i2c);\n\n    imu.init(\u0026mut delay)?;\n\n    // Enable 9-degrees-of-freedom sensor fusion mode with fast magnetometer calibration\n    imu.set_mode(bno055::BNO055OperationMode::NDOF, \u0026mut delay)?;\n\n    Ok(imu)\n    ```\n\n3. Read orientation data, quaternion or euler angles (roll, pitch, yaw/heading):\n\n    ```rust\n    let quat: mint::Quaternion\u003cf32\u003e = imu.quaternion()?;\n    // or:\n    let euler: mint::EulerAngles\u003cf32, ()\u003e = imu.euler_angles()?;\n    ```\n\n    \u003eDue to the BNO055 firmware bugs, the Euler angles reading shouldn't be relied on.\n    I recommend to stick with quaternion readings and convert them to the Euler angles later if needed.\n\n## Details and examples\n\n### Device calibration\n\nTo calibrate the device's sensors for first time:\n\n```rust\nuse bno055::{BNO055Calibration, BNO055OperationMode, BNO055_CALIB_SIZE};\n\nlet bno055 = ...;\n\n// Enter NDOF (absolute orientation) sensor fusion mode which is also performing\n// a regular sensors calibration\nbno055.set_mode(BNO055OperationMode::NDOF)?;\n\n// Wait for device to auto-calibrate.\n// Please perform steps necessary for auto-calibration to kick in.\n// Required steps are described in Datasheet section 3.11\nwhile !bno055.is_fully_calibrated() {}\n\nlet calib = bno055.calibration_profile()?;\n\n// Save calibration profile in NVRAM\nmcu.nvram_write(BNO055_CALIB_ADDR, calib.as_bytes(), BNO055_CALIB_SIZE)?;\n```\n\nTo load a previously saved calibration profile:\n\n```rust\nuse bno055::{BNO055Calibration, BNO055OperationMode, BNO055_CALIB_SIZE};\n\nlet bno055 = ...;\n\n// Read saved calibration profile from MCUs NVRAM\nlet mut buf = [0u8; BNO055_CALIB_SIZE];\nmcu.nvram_read(BNO055_CALIB_ADDR, \u0026mut buf, BNO055_CALIB_SIZE)?;\n\n// Apply calibration profile\nlet calib = BNO055Calibration::from_buf(buf);\nbno055.set_calibration_profile(calib)?;\n```\n\n### Remapping of axes to correspond your mounting\n\nBNO055 allows to change default axes to meet the chip orientation with\nan actual physical device orientation, thus providing possibility to place BNO055\nchip on PCB as suitable for the designer and to match the chip's axes to physical\naxes in software later.\n\n```rust\nuse bno055::{AxisRemap, BNO055AxisConfig};\n// ...\n\n// Build remap configuration example with X and Y axes swapped:\nlet remap = AxisRemap::builder()\n    .swap_x_with(BNO055AxisConfig::AXIS_AS_Y)\n    .build()\n    .expect(\"Failed to build axis remap config\");\n\nbno055.set_axis_remap(remap)?;\n```\n\nPlease note that `AxisRemap` builder (and the chip itself) doesn't allow an invalid state to be constructed,\nthat is, when one axis is swapped with multiple of others.\nFor example, swapping axis `X` with both `Y` and `Z` at the same time is not allowed:\n\n```rust\nAxisRemap::builder()\n    .swap_x_with(BNO055AxisConfig::AXIS_AS_Y)\n    .swap_x_with(BNO055AxisConfig::AXIS_AS_Z)\n    .build()\n    .unwrap(); // \u003c- panics, .build() returned Err\n```\n\n### Changing axes sign\n\nIt is also possible to flip the sign of either axis of the chip.\n\nExample of flipping X and Y axes:\n\n```rust\nbno055\n    .set_axis_sign(BNO055AxisSign::X_NEGATIVE | bno055::BNO055AxisSign::Y_NEGATIVE)\n    .expect(\"Unable to communicate\");\n```\n\n### Using external 32k crystal\n\nFor better performance, it is recommended to connect and use external 32k quartz crystal.\n\nYou enable or disable its use by calling `set_external_crystal`:\n\n```rust\nbno055\n    .set_external_crystal(true)\n    .expect(\"Failed to set to external crystal\");\n```\n\n### Using alternative I2C address\n\nBNO055 allows to change its I2C address from default `0x29` to alternative `0x28` by setting\n`COM3` pin `LOW`.\n\nTo connect to device with an alternative address, enable its use by calling `with_alternative_address()`:\n\n```rust\n// use default 0x29 address\nlet mut bno = bno055::Bno055::new(i2c);\n\n// or:\n\n// use 0x28 address\nlet mut bno = bno055::Bno055::new(i2c).with_alternative_address();\n```\n\n### Change BNO055 power mode\n\n```rust\nuse bno055::{Bno055, BNO055PowerMode};\n// Normal mode\nbno055.set_power_mode(BNO055PowerMode::NORMAL)?;\n\n// Low-power mode (only accelerometer being awake)\nbno055.set_power_mode(BNO055PowerMode::LOW_POWER)?;\n\n// Suspend mode (all sensors and controller are sleeping)\nbno055.set_power_mode(BNO055PowerMode::SUSPEND)?;\n```\n\n### Read chip temperature\n\nTemperature is specified in degrees Celsius by default.\n\n```rust\nlet temp: i8 = bno055.temperature()?;\n```\n\n## Status\n\nWhat is done and tested and what is not yet:\n\n- [x] Sensor initialization\n- [x] Device mode setup\n- [x] Device status readout\n- [x] Calibration status readout\n- [x] External crystal selection\n- [x] Axis remap\n- [x] Axis sign setup\n- [x] Calibration data readout\n- [x] Calibration data setup\n- [x] Alternative I2C address\n- [x] Take register pages into account\n- [x] Orientation data readout\n    - [x] Quaternions\n    - [x] Euler angles\n- [x] Raw sensor data readout\n    - [x] Raw accelerometer data readout\n    - [x] Raw gyroscope data readout\n    - [x] Raw magnetometer data readout\n- [x] Linear acceleration data readout\n- [x] Gravity vector data readout\n- [x] Temperature readout\n- [ ] Per-sensor configuration (when not in fusion mode)\n- [ ] Unit selection\n- [ ] Interrupts\n\nLicense: MIT.\n\n**Contributions welcomed!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feupn%2Fbno055","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feupn%2Fbno055","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feupn%2Fbno055/lists"}