⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion components/bmi270/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ This example shows how to use the `espp::Bmi270` component to initialize and com
- [Debug Tips](#debug-tips)
- [Performance Notes](#performance-notes)
- [Advanced Features](#advanced-features)
- [Data Ready Interrupt](#data-ready-interrupt)
- [Fast Offset Compensation (FOC)](#fast-offset-compensation-foc)
- [Component Re-Trim (CRT)](#component-re-trim-crt)
- [Built-in Features](#built-in-features)
- [References](#references)

<!-- markdown-toc end -->
Expand All @@ -32,6 +36,8 @@ This example shows how to use the `espp::Bmi270` component to initialize and com
- **Orientation Filtering**: Both Kalman and Madgwick filter implementations
- **Real-time Data Logging**: CSV format output suitable for plotting
- **Interrupt Configuration**: Data ready and motion detection interrupts
- **Fast Offset Compensation (FOC)**: Calibrate accelerometer and gyroscope offsets
- **Component Re-Trim (CRT)**: Compensate for gyroscope sensitivity changes
- **Advanced Configuration**: Performance modes, bandwidth settings, power management

## How to use example
Expand Down Expand Up @@ -187,6 +193,16 @@ The CSV output can be imported into analysis tools like:
- Consider magnetometer integration for yaw correction
- Check for temperature effects

**Stack Overflow during Initialization**:
- Device crashes or resets while calling `bmi270.init()`.
- Uploading the configuration file uses a large stack buffer by default.
- Reduce the burst write size in the configuration to limit stack usage.
```cpp
espp::Bmi270::Config config;
config.burst_write_size = 128; // Use 128-byte chunks (default is 0/unlimited)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The note says burst_write_size default is "0/unlimited", but in the driver 0 maps to a single chunk of config_file_size bytes (currently 8192). Consider updating this wording to avoid implying an unbounded write size.

Suggested change
config.burst_write_size = 128; // Use 128-byte chunks (default is 0/unlimited)
config.burst_write_size = 128; // Use 128-byte chunks (default 0 = one chunk of config_file_size bytes, e.g. 8192)

Copilot uses AI. Check for mistakes.
espp::Bmi270 imu(config);
```

### Debug Tips

1. **Enable verbose logging:**
Expand Down Expand Up @@ -218,7 +234,46 @@ The CSV output can be imported into analysis tools like:

## Advanced Features

The example can be extended to demonstrate:
### Data Ready Interrupt

The BMI270 can be configured to generate an interrupt when new data is available. This is more efficient than polling the sensor.

```cpp
Imu::InterruptConfig int_config{
.pin = Imu::InterruptPin::INT1,
.output_type = Imu::InterruptOutput::PUSH_PULL,
.active_level = Imu::InterruptLevel::ACTIVE_HIGH,
.enable_data_ready = true
};
imu.configure_interrupts(int_config, ec);
```

### Fast Offset Compensation (FOC)

FOC allows for quick calibration of the accelerometer and gyroscope offsets.

```cpp
// Accelerometer FOC (e.g., device flat on table, Z axis pointing up)
Imu::AccelFocGValue accel_foc_target = {
.x = 0, .y = 0, .z = 1, .sign = 0 // 1g on Z axis
};
imu.perform_accel_foc(accel_foc_target, ec);

// Gyroscope FOC (device must be stationary)
imu.perform_gyro_foc(ec);
```

### Component Re-Trim (CRT)

CRT is a feature to compensate for sensitivity changes in the gyroscope that may occur during assembly or over time.

```cpp
imu.perform_crt(ec);
```

### Built-in Features

The BMI270 also supports several on-chip features that can be demonstrated by extending this example:

- **Motion Detection**: Any motion, no motion, significant motion
- **Step Counting**: Pedometer functionality
Expand Down
57 changes: 39 additions & 18 deletions components/bmi270/example/main/bmi270_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,45 @@ extern "C" void app_main(void) {
// create the IMU
Imu imu(config);

// ---------------------------------------------------------------------------
// [Optional] Sensor Calibration (FOC & CRT)
// WARNING:
// 1. The device must be COMPLETELY STATIONARY on a flat surface.
// 2. Enable these lines only when you need calibration (e.g., once after assembly).
// ---------------------------------------------------------------------------
#if 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please put this behind a KConfig variable for the example that defaults to true? that way the automated builds in CI catch any potential breaking API changes and the example naturally tests the API.

// Perform FOC (Fast Offset Compensation)
// Note: This assumes the device is flat on a table (Z-axis = 1g)
// For a real application, you might want to trigger this based on a user action
// or store the offsets in NVS.
std::error_code ec;

logger.info("Performing Accelerometer FOC...");
Imu::AccelFocGValue accel_foc_target = {.x = 0, .y = 0, .z = 1, .sign = 0}; // 1g on Z axis
if (imu.perform_accel_foc(accel_foc_target, ec)) {
logger.info("Accelerometer FOC completed successfully");
} else {
logger.error("Accelerometer FOC failed: {}", ec.message());
}

logger.info("Performing Gyroscope FOC...");
// Note: Device must be stationary for Gyro FOC
if (imu.perform_gyro_foc(ec)) {
logger.info("Gyroscope FOC completed successfully");
} else {
logger.error("Gyroscope FOC failed: {}", ec.message());
}

// Perform CRT (Component Re-Trim)
// This feature compensates for sensitivity changes in the gyroscope.
logger.info("Performing CRT...");
if (imu.perform_crt(ec)) {
logger.info("CRT completed successfully");
} else {
logger.error("CRT failed: {}", ec.message());
}
#endif

// make a task to read out the IMU data and print it to console
auto task_fn = [&](std::mutex &m, std::condition_variable &cv) -> bool {
// sleep first in case we don't get IMU data and need to exit early
Expand Down Expand Up @@ -142,24 +181,6 @@ extern "C" void app_main(void) {
fmt::format("{:02.3f},{:02.3f},{:02.3f},", (float)accel.x, (float)accel.y, (float)accel.z);
text += fmt::format("{:03.3f},{:03.3f},{:03.3f},", (float)gyro.x, (float)gyro.y, (float)gyro.z);
text += fmt::format("{:02.1f},", temp);
// print kalman filter outputs
text += fmt::format("{:03.3f},{:03.3f},{:03.3f},", (float)orientation.x, (float)orientation.y,
(float)orientation.z);
text += fmt::format("{:03.3f},{:03.3f},{:03.3f},", (float)gravity_vector.x,
(float)gravity_vector.y, (float)gravity_vector.z);

auto madgwick_orientation = madgwick_filter_fn(dt, accel, gyro);
float roll = madgwick_orientation.roll;
float pitch = madgwick_orientation.pitch;
float yaw = madgwick_orientation.yaw;
float vx = sin(pitch);
float vy = -cos(pitch) * sin(roll);
float vz = -cos(pitch) * cos(roll);

// print madgwick filter outputs
text += fmt::format("{:03.3f},{:03.3f},{:03.3f},", roll, pitch, yaw);
text += fmt::format("{:03.3f},{:03.3f},{:03.3f}", vx, vy, vz);

Comment on lines -145 to -162
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you removed these prints / calculations?

fmt::print("{}\n", text);

return false;
Expand Down
Loading