DIY OBD-II car dashboard with Raspberry Pi + ELM327 Bluetooth

Asked 3 weeks ago Modified 3 days ago Viewed 3 times
DIY OBD-II car dashboard with Raspberry Pi + ELM327 Bluetooth

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).value

Step-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> 1

3. 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`.