Files
..
2026-08-09 22:48:11 -04:00
2026-08-09 22:48:11 -04:00

yaris-obd — full build & install guide

This is the complete hardware → software walkthrough for building a yaris-obd unit from fresh parts and getting it running on a freshly flashed Raspberry Pi OS.

It assumes you are comfortable with basic Linux (flashing an SD card, SSH, running commands), basic soldering, and basic 12V/5V electronics — but have never touched this particular project before. The end result is a Pi that auto-starts the yaris-obd web app on boot and serves it at http://yaris.local over the car's own WiFi hotspot, with GPS tracking, live OBD-II data, dashcam import, and background uploads to a self-hosted server.

For the project's full phase-by-phase history and hardware bring-up notes, see PLAN.md.


1) Parts list

Part Purpose Notes
Raspberry Pi 3 Model B Runs the app, logs data, hosts the hotspot Pi 3 B is the reference build; a Pi 3B+/4 works too
Waveshare SIM868 HAT GNSS (GPS) + optional GSM/GPRS GSM needs a SIM and 2G coverage (often none in NA); GPS is the part in use
SIM868 antennas GSM + GPS reception Two separate antennas — GSM and GNSS each plug into their own u.FL port on the HAT
USB OBD-II adapter Reads live vehicle data PL2303-chip ELM327-compatible (USB). Appears as /dev/ttyUSB*
2× TP-Link Archer T3U WiFi — wlan1 = in-car 5GHz AP, wlan2 = internet uplink RTL8812BU chipset, needs a DKMS driver (the installer builds it)
DS3231 RTC module Keeps the clock correct with no internet Optional but strongly recommended; on the I²C bus i2c-1
CR2032 cell Backup battery for the RTC Must be non-rechargeable type for the ZS-042 board (see below)
5V power source Powers the Pi Either a quality USB PSU or a hard-wired 5V/GND feed to the GPIO header
USB dashcam Records video; files are imported over USB Any brand that enumerates as USB mass storage
SD card (≥16GB) Pi boot + app storage A2/U3 card recommended
Car The patient Reference car: 2013 Toyota Yaris

2) Hardware assembly

Safety first. Anything mounted in a car must not interfere with pedals, steering, airbags, visibility, or occupants. Route and secure every cable. Never do this work while driving. If you are tapping vehicle 12V, fuse the feed as close to the source as possible.

2.1 Raspberry Pi

  • Fit the SD card after flashing (Section 3).
  • If you plan to run the Pi without a keyboard/monitor, set up SSH during flashing so you can work on it headlessly.

2.2 SIM868 HAT (GPS)

The SIM868 HAT stacks on the Pi's 40-pin GPIO header.

  1. Set the UART jumper to B (Pi ↔ SIM868). This is the 3-position jumper on the HAT: A = USB↔SIM868, B = Pi GPIO↔SIM868, C = USB↔Pi console. It must be on B or the Pi cannot talk to the module.
  2. Connect both antennas. The GPS/GNSS antenna and the GSM antenna go into their own separate u.FL sockets on the HAT. A GPS fix is impossible with only the GSM antenna connected — this was the single most common bring-up mistake in the reference build.
  3. PWRKEY. This HAT revision ships with the "P4" GPIO power-on mod wire already installed (header pin 7 = BCM GPIO4). The app pulses it automatically at boot to power the module chip on. If your board does not have that wire, you must press the HAT's PWRKEY button for ~1–2s after every Pi power-up, or add the mod wire yourself.
  4. Run the installer with --with-sim868 (Section 4) so the Pi frees the full UART for the HAT (enable_uart=1, dtoverlay=disable-bt, no serial login shell, hciuart disabled). Baud rate is 115200.

Without an RTC the Pi boots with a wrong clock every time the car has no internet, which corrupts trip timestamps.

DS3231 (ZS-042) pin Pi GPIO header pin
VCC Pin 1 — 3.3V (not 5V)
GND Pin 6
SDA Pin 3 (I²C SDA)
SCL Pin 5 (I²C SCL)
  • Remove the charge diode on the ZS-042 board if you fit a non-rechargeable CR2032 — the board's trickle-charge circuit is unsafe for non-rechargeable cells.
  • If i2cdetect -y 1 shows nothing at 0x68, your SDA/SCL are crossed or a joint is cold. A lit LED only means power is present.
  • Run the installer with --with-rtc (Section 4) to add the overlay, disable fake-hwclock, and load the i2c-dev module.

2.4 USB OBD-II adapter

  • Any PL2303/CH340-based ELM327 USB adapter works. It enumerates as /dev/ttyUSB0 (or the first available /dev/ttyUSB*).
  • The app auto-detects the port; you can override it later with the OBD_PORT env var in the systemd unit if needed.

2.5 WiFi dongles (2× T3U)

  • Plug one T3U into each USB port. The interface names follow USB enumeration order, so on a given Pi wlan1 and wlan2 are stable only as long as the dongles stay in the same ports. If you ever swap ports, the AP and uplink roles will swap too.
  • The installer builds the RTL8812BU DKMS driver. On a Pi 3 the two identical dongles are distinguished only by their position, not by MAC — a MAC-based udev rule is a possible future improvement (not required for normal use).
  • Expected roles:
    • wlan1 — hosts the in-car AP (5GHz, 10.42.0.1)
    • wlan2 — carries the internet uplink (home WiFi + optional phone hotspot)
    • wlan0 — onboard radio, kept as a weak fallback only

2.6 Power

Two valid approaches:

  • Simplest: a good 5V/2.5A+ USB PSU (the official Pi 3 PSU is ideal). Avoid thin cables — voltage drop is the #1 cause of vcgencmd get_throttled undervoltage flags.
  • Robust for permanent install (reference build): hard-wire regulated 5V/GND directly to the GPIO header — red to Pin 2 (5V), black to Pin 6 (GND) — fed from a fused 12V→5V buck converter (≥3A) or a quality cigarette-lighter USB supply. This bypasses the fragile micro-USB connector.

Whichever you choose, verify after install:

vcgencmd get_throttled
# 0x0 = no undervoltage, no throttling (what you want)

A non-zero current undervoltage/throttling bit means the power feed is inadequate and must be fixed before the unit lives in the car.

2.7 Dashcam

  • Any dashcam that mounts as generic USB mass storage works — the app detects USB storage via lsblk and walks it for video files.
  • Known manual step: many dashcams boot into a "select mode" menu (dashcam / mass-storage / webcam) when they sense live USB data lines. To record, the USB data lines must be absent; to import, they must be present. The project does not switch this automatically — unplug/replug (or use a data-blocking cable) when switching between recording and importing.

2.8 Final in-car placement

  • Keep the GPS antenna with a skyward view (dash top is usually fine).
  • Keep the Pi and dongles clear of direct sunlight and away from heater vents.
  • Strap everything down; a loose Pi near the pedals is a hazard.

3) Flash Raspberry Pi OS

  1. Download Raspberry Pi Imager and write Raspberry Pi OS Bookworm (Lite is fine) to the SD card.
  2. In Imager's advanced options (gear icon) set:
    • hostname: yaris
    • enable SSH (password or key)
    • your primary username + password (the installer creates a separate yaris service user; this is just for you to log in)
    • optional: your home WiFi credentials so the Pi is reachable for the install
  3. Boot the Pi, find it on your network, and SSH in:
ssh <your-user>@yaris.local
# or fall back to the IP if mDNS isn't working yet

4) Run the one-shot installer

The installer (deploy/auto_install.sh) takes a fresh OS from zero to running. It installs packages, creates the yaris user, clones the repo, builds the T3U driver, creates the NetworkManager WiFi profiles, and runs every deploy/install_*.sh in the right order.

4.1 Get the script onto the Pi

Option A — download it directly (recommended):

curl -fsSL -o auto_install.sh \
  https://raw.githubusercontent.com/quoije/yaris-obd/shameless-aislop/deploy/auto_install.sh

Replace shameless-aislop with the repo's current default branch if it has changed since this was written.

Option B — clone the repo and run from inside it:

git clone https://github.com/quoije/yaris-obd.git
cd yaris-obd
# the script clones again into /home/yaris/app/yaris-obd; that is expected

4.2 Run it

The only required inputs are your home WiFi and in-car hotspot credentials. Pass them through the environment (or let the script prompt you):

sudo -E bash auto_install.sh \
  --with-rtc \
  --with-sim868

with these environment variables set:

export HOME_WIFI_SSID="MyHomeWiFi"
export HOME_WIFI_PSK="home-wifi-password"
export HOTSPOT_SSID="yaris-obd"          # in-car AP; default is "yaris-obd"
export HOTSPOT_PSK="in-car-password"
# optional phone hotspot uplink:
export PHONE_HOTSPOT_SSID="MyPhoneHotspot"
export PHONE_HOTSPOT_PSK="phone-hotspot-password"

Fully non-interactive (no prompts) — fails if a required value is missing:

sudo -E bash auto_install.sh --non-interactive --with-rtc --with-sim868

4.3 Flags

Flag Effect
--with-rtc Enable the DS3231 RTC (I²C overlay, disable fake-hwclock)
--with-sim868 Enable the SIM868 UART (enable_uart=1, disable-bt, no serial console, hciuart off)
--skip-t3u-driver Skip the RTL8812BU build (if you're not using T3U dongles)
--no-watchdog Skip the 10s hardware watchdog
--no-app-updater Skip the Android APK mirror timer
--non-interactive Never prompt; error out on missing credentials
-h / --help Print help

Optional env vars also honoured: GIT_URL, GIT_BRANCH, YARIS_PASSWORD, OWNER_NAME, CAR_MODEL, DEVICE_NAME, YARIS_SERVER_URL, YARIS_DEVICE_NAME, YARIS_API_KEY.

4.4 What the installer does

  1. Installs base packages (git, Python tooling, NetworkManager, nftables, avahi, dnsmasq-base, iw) and enables NetworkManager.
  2. Creates the yaris service user (groups: sudo, dialout, gpio, i2c).
  3. Clones the repo to /home/yaris/app/yaris-obd.
  4. Applies --with-rtc / --with-sim868 boot-config changes if requested.
  5. Builds the RTL8812BU driver (unless skipped).
  6. Creates/updates the home-wifi, Hotspot-local, and optional phone-hotspot NetworkManager profiles.
  7. Runs, in order: install_service.sh, install_port_redirect.sh, install_netwatch.sh, install_video_tools.sh, and (unless disabled) install_watchdog.sh + install_app_updater.sh.
  8. Optionally prefills config/device.json and db/upload_creds.env from env vars, fixes repo ownership, and creates the writable data directories.

4.5 Reboot

If you used --with-rtc or --with-sim868, reboot so the boot-config changes apply:

sudo reboot

5) Verify

After reboot, on the Pi:

sudo systemctl status yaris-obd.service --no-pager
sudo systemctl status yaris-netwatch.timer --no-pager
sudo nft list ruleset | grep -n "dport 80"
curl -I http://127.0.0.1/
curl -s http://127.0.0.1/api/gps/status

Expected:

  • yaris-obd.service is active (running)
  • yaris-netwatch.timer is active
  • nftables redirects port 80 → 5000
  • local HTTP on port 80 returns 200/302
  • /api/gps/status returns JSON (GPS thread alive)

From another device on your home WiFi:

  • http://yaris.local

From a phone connected to the in-car hotspot (HOTSPOT_SSID):

  • http://yaris.local — or http://10.42.0.1 if the phone doesn't resolve mDNS

If the T3U dongles don't appear after the driver build:

ip link show wlan1
ip link show wlan2

If wlan1 is missing, fix the driver first (see Section 9), then re-run sudo bash deploy/install_netwatch.sh.


6) Configure device identity

The Pi shows an owner name, car model, device name, and avatar. Either edit the file directly:

sudo nano /home/yaris/app/yaris-obd/config/device.json
{
  "owner_name": "Your Name",
  "car_model": "Toyota Yaris 2013",
  "device_name": "My Yaris OBD",
  "avatar_path": "img/yaris.png"
}

or open the web UI → Settings and manage it there.

  • owner_name — top-right of the topbar
  • car_model — left sidebar, next to the car icon
  • device_name — device identity used for remote-server sync
  • avatar_path — avatar image, relative to static/ (drop your image in static/img/ and update the path, or replace static/img/yaris.png)

Restart after editing the file:

sudo systemctl restart yaris-obd.service

Heads-up: the local SQLite database filename is derived from owner_name (db/sql/<owner_name>_<car_model>.db). Changing owner_name later creates a new empty database and orphans the old one — rename the old file to match if you want to keep the data.


Trip logs and dashcam footage upload to a self-hosted Flask + Postgres server (server/ in this repo). See server/README.md for deploying it.

Once the server is up and a device is registered, put the credentials on the Pi either via the web UI (Settings → Remote server credentials → Test connection → Sync now) or by prefilling db/upload_creds.env:

sudo nano /home/yaris/app/yaris-obd/db/upload_creds.env
YARIS_SERVER_URL = "https://your-server.example"
YARIS_DEVICE_NAME = "yaris-2013"
YARIS_API_KEY = "your-one-time-key"

Then enable Sync with server in Settings if you want the server to own the device identity.


8) Daily use & updates

Update the Pi to the latest code:

cd /home/yaris/app/yaris-obd
git pull --ff-only
sudo bash deploy/install_service.sh        # re-deploy the unit + sudoers
sudo systemctl restart yaris-obd.service

If any deploy/ files changed, re-run the matching installer(s) (install_netwatch.sh, install_port_redirect.sh, install_app_updater.sh, …).

In-car, connect your phone to the hotspot and browse http://yaris.local. Dashcam files are imported from the Dashcam page; live telemetry is on the Dashboard; past drives are under History.


9) Troubleshooting

bash /home/yaris/app/yaris-obd/scripts/diagnose.sh          # read-only check
bash /home/yaris/app/yaris-obd/scripts/diagnose.sh --fix    # attempt auto-fix

Common issues:

Symptom Likely cause Fix
wlan1/wlan2 missing RTL8812BU driver didn't build Re-run the driver build from Section 4; check dkms status
GPS never gets a fix GPS antenna on wrong u.FL / not seated; HAT jumper not on B; SIM868 chip not powered Re-check antennas + jumper; confirm the app pulses PWRKEY (or press the button 1–2s)
Wrong time after a cold boot No RTC or RTC not configured i2cdetect -y 1 should show UU at 0x68; check wiring (3.3V!)
vcgencmd get_throttled ≠ 0x0 Weak power feed Use a better PSU/cable, or hard-wire 5V to GPIO pins 2 & 6
Dashcam import hangs yaris lacks passwordless sudo for mount/rm Re-run sudo bash deploy/install_service.sh (installs yaris-dashcam.sudoers)
Hotspot SSID/password changes don't save yaris-hotspot.sudoers missing Re-run sudo bash deploy/install_netwatch.sh
yaris.local not resolving on a phone mDNS blocked / phone doesn't relay mDNS on the hotspot Use http://10.42.0.1 directly
pip install -r requirements.txt fails Outdated checkout with the concatenated requests-toolbeltreverse_geocoder line git pull --ff-only (fixed in current repo)
SSH drops when NetworkManager is enabled (Bookworm Lite) NM takes over the interface and has no profile for your current WiFi yet Run the installer over Ethernet, or pre-create the profile before enabling NM; after the run, re-connect to your WiFi

Manual reference: the installers

auto_install.sh is just a wrapper around these individual scripts, which you can also run by hand from /home/yaris/app/yaris-obd:

sudo bash deploy/install_service.sh        # systemd unit + venv + sudoers
sudo bash deploy/install_port_redirect.sh  # nftables port 80 -> 5000
sudo bash deploy/install_netwatch.sh       # uplink watcher + hotspot profiles
sudo bash deploy/install_video_tools.sh    # ffmpeg for dashcam thumbnails
sudo bash deploy/install_watchdog.sh       # 10s hardware watchdog
sudo bash deploy/install_app_updater.sh    # Android APK mirror timer

The manual order matters: install_netwatch.sh expects the home-wifi and Hotspot-local profiles to already exist (create them with nmcli, or just let auto_install.sh do it).