A lightweight, robust, and dependency-minimal Python codebase for Raspberry Pi 4 to read real-time data from an IMU (MPU6050/MPU9250 at address 0x68) and a Magnetometer (HMC5883L/QMC5883L at address 0x1E).
Connect both sensors to the Raspberry Pi 4 I2C bus as follows:
| Sensor Pin | Pi 4 GPIO Pin | Description |
|---|---|---|
| VCC | Pin 1 (3.3V) | Power Supply |
| GND | Pin 9 (Ground) | Common Ground |
| SDA | Pin 3 (SDA / GPIO 2) | Serial Data Line |
| SCL | Pin 5 (SCL / GPIO 3) | Serial Clock Line |
Note: Since I2C is a shared bus, both sensors can be wired in parallel to the same SDA and SCL pins on the Raspberry Pi.
Open the Raspberry Pi terminal and open the configuration tool:
sudo raspi-configNavigate to Interface Options -> I2C and select Yes to enable the I2C interface. Reboot your Pi:
sudo rebootInstall i2c-tools to check if the Pi detects the sensors:
sudo apt-get install -y i2c-toolsRun i2cdetect to scan the bus:
i2cdetect -y 1You should see output indicating devices are present at address 1e and 68:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Install Python dependencies using the provided requirements.txt:
pip install -r requirements.txtTo launch the interactive 3D WebGL Dashboard with real-time trajectory visualization, run:
python web_server.pyThen open http://localhost:8000 in your web browser.
To view raw text telemetry in your terminal, run:
python client.pyExecute the main script to start streaming sensor readings:
python main.pyIn main.py, you can customize:
DECLINATION_ANGLE_DEG: Set this to get accurate true-north headings based on your location. Find your declination angle at magnetic-declination.com.UDP_IP: Target IP address to send sensor data (e.g., target laptop's IP, or"255.255.255.255"for local network broadcast).UDP_PORT: Port number for UDP transmission (default is5005).
The payload is sent as a JSON string with the following structure:
{
"timestamp": 1721389811.234,
"dt": 0.02,
"rotation": {
"quaternion": {"w": 0.99, "x": 0.01, "y": 0.02, "z": -0.05},
"euler": {"roll": 1.2, "pitch": 2.3, "yaw": -5.7}
},
"translation": {
"position": {"x": 0.12, "y": -0.05, "z": 0.01},
"velocity": {"x": 0.01, "y": -0.00, "z": 0.00},
"linear_accel": {"x": 0.05, "y": -0.02, "z": 0.01}
},
"heading": 85.3,
"raw_imu": {
"accel": {"x": 0.01, "y": -0.02, "z": 0.98},
"gyro": {"x": 0.1, "y": -0.2, "z": 0.05},
"mag": {"x": -2.3, "y": 25.1, "z": -40.2},
"temp": 28.5
}
}