Goal: a replacement dashboard for my older hatchback that shows RPM, speed, coolant temperature, fuel level, and battery voltage on a big touchscreen. Pulls live data from the car's OBD-II port over Bluetooth — no manufacturer subscription, no cloud, no nonsense.
Parts
- Raspberry Pi 3B+ (the 4 is overkill, the 3 is plenty)
- Official 7" Raspberry Pi Touchscreen
- A generic ELM327 Bluetooth OBD-II dongle (~$15 — pick a 'v1.5' variant, the v2.1 clones are flaky)
- A 12V → 5V buck converter rated 3A (the Pi + screen draws ~2A)
- A car cigarette-lighter plug + cable to feed the buck converter
- 3D-printed bezel to fit the centre-console
Why Bluetooth, not USB: the dongle stays plugged into OBD-II under the steering wheel; the screen sits on the dashboard. Bluetooth is the only sane way to bridge that gap without running cables.
Software stack
- Raspberry Pi OS Lite (no desktop — we run Kivy fullscreen at boot)
- Python 3 + the `obd` library (pip install obd)
- Kivy for the touch UI
- systemd service to launch the app on boot
Reading OBD-II in Python
import obd
connection = obd.Async('/dev/rfcomm0')
connection.watch(obd.commands.RPM)
connection.watch(obd.commands.SPEED)
connection.watch(obd.commands.COOLANT_TEMP)
connection.start()
# Later: connection.query(obd.commands.RPM).valueStep-by-step
1. Pair the ELM327 with the Pi using bluetoothctl: scan, trust, pair, connect.
2. Bind it to a serial device:
sudo rfcomm bind 0 <DONGLE_MAC> 13. Test with: python3 -c "import obd; print(obd.OBD('/dev/rfcomm0').query(obd.commands.RPM).value)"
4. Build a Kivy screen with large needle-style gauges.
5. Set up systemd to auto-start the app at boot.
Dashboard layout decisions
- Big circular RPM gauge top-left.
- Big digital speed top-right.
- Two smaller gauges below: coolant temp + fuel level.
- A 'trip' page accessible by swipe: instant + average fuel economy, distance, time.
Power tip: the Pi must shut down cleanly, otherwise the SD card will eventually corrupt. I wired a GPIO to the ignition switch (via an opto-isolator + voltage divider) and run a small Python daemon: when ignition goes low, run `sudo shutdown -h now`.