Lightweight MicroPython driver for the Bosch BMI160 IMU (accelerometer + gyroscope). Includes clean configuration APIs, data reads (raw and scaled), interrupts, and built‑in calibration (FOC) support.
- Simple initialization and power-up sequence
- Flexible accelerometer/gyroscope range and output data rate (ODR) configuration
- Motion and tap/double-tap interrupt support (any-motion, single/double tap)
- Fast Offset Calibration (FOC) and manual offset adjustment
- Read raw and scaled acceleration (g) and gyro (°/s) values
- I2C interface, compatible with ESP32 and other MicroPython boards
| BMI160 Pin | ESP32 Example | Notes |
|---|---|---|
| VCC | 3V3 | 1.71–3.6 V typical |
| GND | GND | Common ground |
| SCL | 16 | Any I2C SCL‑capable |
| SDA | 4 | Any I2C SDA‑capable |
| INT1 | 5 (optional) | For motion/tap IRQs |
from machine import I2C, Pin
from bmi160 import BMI160
i2c = I2C(0, sda=Pin(4), scl=Pin(16), freq=400_000)
imu = BMI160(i2c, addr=0x68)
imu.initialize()
# Configure
imu.set_accel_range(2) # ±2 g
imu.set_accel_rate(100) # 100 Hz
imu.set_gyro_range(250) # ±250 °/s
imu.set_gyro_rate(100) # 100 Hz
# Read scaled values
ax, ay, az = imu.read_accel() # g
gx, gy, gz = imu.read_gyro() # °/s
print(ax, ay, az, gx, gy, gz)imu.set_accel_range(2); imu.set_accel_rate(100)
imu.set_gyro_range(250); imu.set_gyro_rate(100)
while True:
ax, ay, az = imu.read_accel()
gx, gy, gz = imu.read_gyro()
print("Accel (g):", ax, ay, az, "Gyro (°/s):", gx, gy, gz)Note: Keep the board completely still. For accel FOC, place it flat (Z+ up) to target X=0 g, Y=0 g, Z=+1 g.
# Enable offset compensation, then run FOC
imu.set_accel_offset_enabled(True)
imu.set_gyro_offset_enabled(True)
imu.auto_calibrate_x_accel_offset(0) # X -> 0 g
imu.auto_calibrate_y_accel_offset(0) # Y -> 0 g
imu.auto_calibrate_z_accel_offset(1) # Z -> +1 g
imu.auto_calibrate_gyro_offset() # Gyro -> zero-rate
print("Accel offsets:", imu.get_x_accel_offset(), imu.get_y_accel_offset(), imu.get_z_accel_offset())
print("Gyro offsets:", imu.get_x_gyro_offset(), imu.get_y_gyro_offset(), imu.get_z_gyro_offset())imu.initialize()
imu.set_gyro_range(250)
while True:
gx, gy, gz = imu.read_gyro()
print("g:\t{:.2f}\t{:.2f}\t{:.2f}".format(gx, gy, gz))imu = BMI160(i2c, addr=0x68)
imu.initialize()
imu.set_accel_range(2)
imu.set_accel_rate(100)
imu.set_motion_threshold_mg(200.0)
imu.set_motion_duration_s(0.03)
imu.set_int_output(active_low=False, open_drain=False, enable=True)
imu.set_int_latch('320_MS')
imu.enable_any_motion(True)
# Configure wakeup with esp32.wake_on_ext0/ext1 on the INT pin, then deepsleep- No response on I2C: verify wiring, address (
0x68vs0x69), and pull‑ups. - FOC has no effect: ensure offsets are enabled before FOC and the sensor is completely still.
- Motion interrupt not firing: verify INT pin polarity/latch config and threshold/duration settings.
- Issues and PRs welcome. Please keep code lightweight and portable across MicroPython boards.
- Specify your preferred license here (e.g., MIT). If this folder is shared standalone, add a
LICENSEfile.
