A high-performance, AEM CD-7 inspired digital instrument cluster and telemetry logger for BMW E-Series vehicles (specifically tested on E90 320i N43 and E60 525d). Built with Python and PyQt6, this dashboard actively polls standard OBD-II PIDs over the D-CAN network to bypass hidden OEM parameters.
- Motorsport Aesthetic: Pitch-black background, high-contrast typography, and strict geometric layouts designed for high-speed glanceability.
- Active OBD-II Polling: Rapidly requests standard ECU data (RPM, Speed, Boost, IAT, FRP, ECT) via ID
0x7DF. - Hardware Abstraction: Seamlessly switch between a physical USB-CAN adapter (
livemode) and a virtual PC data generator (simmode) for off-car development. - Auto-Detection: Automatically scales redlines and gauges based on the detected vehicle profile.
To run this live in a vehicle, you need:
- A Linux-based host machine (Raspberry Pi, laptop, or Linux tablet).
- A USB-CAN adapter that supports SocketCAN (e.g., CANable or Waveshare USB-CAN-A).
- An OBD-II pigtail cable wired to the adapter:
- CAN High: OBD-II Pin 6
- CAN Low: OBD-II Pin 14
-
Clone the repository:
git clone [https://github.com/bomberrie/bmw-digital-dash.git](https://github.com/bomberrie/bmw-digital-dash.git) cd bmw-digital-dash -
Set up the virtual environment:
python3 -m venv venv source venv/bin/activate -
Install dependencies:
pip install -r requirements.txt
Edit config.py to set your desired execution mode before launching.
Simulation Mode (For PC Testing):
CONNECTION_MODE = 'sim'
SIMULATED_VEHICLE = 'E60' # or 'E90'Run the application: python main_ui.py
Live Hardware Mode (For the Car):
Ensure your USB-CAN adapter is plugged in and the SocketCAN interface (can0) is up.
CONNECTION_MODE = 'live'
CAN_INTERFACE = 'socketcan'
CAN_CHANNEL = 'can0'
CAN_BITRATE = 500000Run the application: python main_ui.py
main_ui.py: The PyQt6 frontend overlay featuring QPainter-drawn arcs and multi-threaded UI updates.can_backend.py: The isolated background thread managing the SocketCAN interface and the OBD-II polling queue.can_decoder.py: Handles hexadecimal frame translation into human-readable metric values.
Distributed under the MIT License. See LICENSE for more information.