Documentation
Inertial Measurement Unit (IMU)
Source:
hardware_io/imu/README.md
The hardware_io.imu package provides a small interface for reading linear
acceleration and angular velocity from an inertial measurement unit. The
included Mpu6050Imu implementation communicates with an MPU-6050 over I2C.
Measurements are returned as immutable Vector3 values in SI units:
- Acceleration: meters per second squared (
m/s²) - Angular velocity: radians per second (
rad/s)
The package reports raw sensor measurements. Calibration, filtering, attitude estimation, and application behavior belong in higher-level components.
Hardware Setup
Connect the MPU-6050 to the host’s I2C bus:
| MPU-6050 | Raspberry Pi |
|---|---|
| VCC | 3.3 V |
| GND | Ground |
| SDA | I2C SDA |
| SCL | I2C SCL |
Check the voltage requirements of the specific breakout board before wiring it. Enable I2C on Raspberry Pi OS:
sudo raspi-config
Choose Interface Options, enable I2C, and reboot if prompted. Verify that the device is visible:
i2cdetect -y 1
The default MPU-6050 address is 0x68. Boards that expose the AD0 pin can
typically use 0x69 when AD0 is high.
Installation
From the project root, install the MPU-6050 feature bundle:
scripts/installers/host_setup.sh --feature mpu6050
This installs i2c-tools, Adafruit Blinka, and the Adafruit CircuitPython
MPU-6050 driver. To install only the Python dependencies in an existing
environment:
python3 -m pip install adafruit-blinka adafruit-circuitpython-mpu6050
Usage
from hardware_io.imu import Mpu6050Imu
imu = Mpu6050Imu()
imu.start()
try:
acceleration = imu.get_acceleration_mps2()
angular_velocity = imu.get_angular_velocity_rad_s()
print(
f"acceleration: x={acceleration.x:.3f}, "
f"y={acceleration.y:.3f}, z={acceleration.z:.3f} m/s²"
)
print(
f"angular velocity: x={angular_velocity.x:.4f}, "
f"y={angular_velocity.y:.4f}, "
f"z={angular_velocity.z:.4f} rad/s"
)
finally:
imu.stop()
Call start() before reading the sensor and stop() when finished. Repeated
calls to start() are safe. Reading before startup or after shutdown raises a
RuntimeError.
To use a non-default address:
imu = Mpu6050Imu(address=0x69)
An existing CircuitPython-compatible I2C bus can also be shared:
import board
from hardware_io.imu import Mpu6050Imu
i2c = board.I2C()
imu = Mpu6050Imu(i2c_bus=i2c)
When a bus is supplied by the caller, stop() leaves that bus open. When the
driver creates the default bus, stop() releases it.
Interface
Hardware-independent consumers can depend on ImuIf:
from hardware_io.imu import ImuIf
def read_motion(imu: ImuIf) -> None:
acceleration = imu.get_acceleration_mps2()
angular_velocity = imu.get_angular_velocity_rad_s()
ImuIf defines:
start()— initialize the devicestop()— release owned resourcesis_connected()— report whether initialization succeededget_acceleration_mps2()— return an accelerationVector3get_angular_velocity_rad_s()— return an angular-velocityVector3
Component Test
Run the live hardware test from the project root:
python3 -m hardware_io.imu.component_test.imu_cli
The CLI prints acceleration and angular velocity every 0.2 seconds. Press
Ctrl+C to stop it.
Read one sample and exit:
python3 -m hardware_io.imu.component_test.imu_cli --once
Use a different address or sampling interval:
python3 -m hardware_io.imu.component_test.imu_cli \
--address 0x69 \
--interval 0.5
Run the CLI with --help to see all options.
Troubleshooting
- If
i2cdetectdoes not show the sensor, check power, ground, SDA, SCL, the selected I2C bus, and whether I2C is enabled. - If initialization fails at
0x68, scan the bus and try--address 0x69if that is the address reported. - If Python reports a missing MPU-6050 or
boardmodule, install the dependencies listed above in the same environment used to run the CLI. - If access to the I2C device is denied, check the permissions and group
ownership of
/dev/i2c-*for the host system.