Skip to content

feat(bno055): add BNO055 9-axis absolute orientation IMU component - #858

Merged
finger563 merged 2 commits into
esp-cpp:mainfrom
alexchunlin:feature/bno055
Oct 22, 2026
Merged

finger563 merged 2 commits into
esp-cpp:mainfrom
alexchunlin:feature/bno055

Conversation

@alexchunlin

@alexchunlin alexchunlin commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds espp::Bno055, a driver for the Bosch BNO055 9-axis absolute-orientation IMU over I2C, plus an example and docs. espp has no BNO055 driver today. It follows the same BasePeripheral pattern as the ICM20948 and BMI270 drivers: the caller passes in probe, write and write_then_read, so the driver runs on any espp I2C bus.

  • Init: resets the chip, waits for chip ID 0xA0, selects normal power mode, sets SI units (m/s², rad/s, rad, °C), optionally enables the external 32 kHz crystal, then switches to the configured fusion mode. The default is IMU mode, accel + gyro fusion with heading relative to power-on. NDOF and the non-fusion modes are available.
  • update(): reads accel, mag, gyro, Euler angles, quaternion, linear acceleration, gravity, temperature and calibration status in a single 46-byte burst, and caches the result. data() returns a copy under a mutex.
  • Example: components/bno055/example prints a CSV row at 100 Hz. Pins and address are set in menuconfig. The defaults are SDA 7 / SCL 8 on esp32p4 (the ESP32-P4-ETH internal bus) and 21 / 22 elsewhere, at address 0x28.
  • Docs: doc/en/imu/bno055.rst, the example page, and the Doxyfile and imu/index.rst entries.

Axis remapping is left out on purpose. On an earlier robot the BNO055's register-level axis remap scrambled the quaternion axes, and doing the mounting correction in software was more reliable.

Motivation and Context

We use a BNO055 on the RAMMP MIB, an ESP32-P4-ETH wheelchair base controller (rammp-org/RAMMP-mib-fw#38). The driver started life there. This PR moves it upstream so the MIB can depend on espp/bno055 instead of carrying a local copy.

How has this been tested?

  • Example build: ESP-IDF v6.0.1, esp32p4. No warnings. clang-format clean.

  • Hardware: the example on an ESP32-P4-ETH (rev v1.3) with a BNO055 breakout on GPIO7/8, board still on a desk.

    • Initialized in IMU mode.
    • Gyro calibration reached 3 within about 1 s.
    • Roll −0.0533 rad and pitch −0.0444 rad, which matches the tilt from the accelerometer's gravity vector (−0.49, −0.41, 9.48 m/s²).
    • About 91 Hz at the default 115200 baud, where the CSV line length is the limit, not the I2C read. A burst read takes about 1.5 ms.
  • In-application: the same driver, under mib:: instead of espp::, has run in the MIB firmware at 100 Hz alongside Ethernet and RTPS.

  • Tilt by hand, in the MIB firmware (same driver):

    • I tilted the sensor to +34° pitch and −32° roll at 100 Hz.
    • Over the roll test, fused roll agreed with roll computed from the driver's own accelerometer output (atan2(a_x, |a_yz|)) to within a median 0.19°. That supports the driver's unit scaling and axis mapping.
    • The left panel also shows the sensor unplugged and replugged. The recovery there is application logic (probe, then init() again), not part of this component.

    Fused tilt and fusion vs gravity

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Documentation Update
  • Software change

Checklist:

  • My change requires a change to the documentation.
  • I have added / updated the documentation related to this change via either README or WIKI

Software

  • My code follows the code style of this project.

🤖 Generated with Claude Code

alexchunlin and others added 2 commits October 22, 2026 16:04
Add espp::Bno055, a BasePeripheral-based I2C driver for the Bosch BNO055.
It resets the sensor, waits for the chip ID, selects SI units (m/s^2,
rad/s, rad, uT), optionally enables the external 32 kHz crystal, and
enters the configured operating mode (IMU fusion by default). update()
reads every sensor and fusion output in one 46-byte burst.

Add an example that prints one CSV row per sample at 100 Hz, docs pages,
and the Doxygen entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

✅Static analysis result - no issues found! ✅

@alexchunlin
alexchunlin marked this pull request as ready for review October 22, 2026 21:22
alexchunlin added a commit to rammp-org/RAMMP-mib-fw that referenced this pull request Oct 22, 2026
Drop components/Bno055 and depend on espp/bno055 (esp-cpp/espp#858),
which is the same driver upstreamed. Pinned to the PR branch on the
alexchunlin/espp fork until the next espp release; replace the git
dependency in main/idf_component.yml with the released version before
merging.

Bench: IMU initializes and Diagnostics rows I1/I2 arrive over RTPS as
before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexchunlin
alexchunlin requested a review from finger563 October 22, 2026 21:51
@finger563
finger563 merged commit 83183d5 into esp-cpp:main Oct 22, 2026
175 of 177 checks passed
alexchunlin added a commit to rammp-org/RAMMP-mib-fw that referenced this pull request Oct 23, 2026
esp-cpp/espp#858 shipped in espp v1.3.10, unchanged from the branch
this PR was tested against. Replace the git dependency on the fork with
the registry release. A clean resolve moves every espp component to
1.3.10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants