justin 01de18a568 Document cross-platform support (Windows/macOS/Linux)
The stack is portable by construction: PySide6/pyqtgraph/numpy/pyserial all
ship wheels for all three OSes (incl. Apple Silicon); obdcore has no
OS-specific code; the terminal dashboard's only platform code is guarded
(os.name=='nt' vs termios for POSIX = macOS+Linux).

- ARCHITECTURE.md: Cross-platform section -- portability rules (list_ports
  only, pathlib, no shelling out, platformdirs for config), the three per-OS
  seams (CH340 driver, PyInstaller per-OS packaging, Gatekeeper/SmartScreen).
- README: Setup now covers Windows (CH341SER), macOS (CH34xVCPDriver), Linux
  (in-kernel ch341 + dialout group) instead of Windows-only.

No code changes; obdcore tests still pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yT89n4zR4qbrySoSiEyZs
2026-06-30 14:06:49 -04:00

ford-obd

Minimal ELM327 OBD-II code reader with a Ford 6.0L Power Stroke no-start triage, built for a cheap CH340 ELM327 USB adapter. Works on any OBD-II vehicle for generic codes/PIDs; the triage notes are 6.0-specific.

Created as a stopgap while forscan.org was offline — it covers reading/clearing codes and the basics, not Ford-enhanced diesel PIDs (see Scope below).

Features

  • Read stored (mode 03), pending (mode 07), permanent (mode 0A) DTCs
  • Decode P/C/B/U codes, with common 6.0 codes described and no-start suspects flagged
  • Clear codes (mode 04) — guarded behind --clear + a typed CLEAR confirmation, then re-reads to show any code that returns immediately (active fault)
  • Key live values (coolant, IAT, MAP, module voltage, RPM, load, throttle) + battery voltage
  • 6.0 Power Stroke no-start triage checklist (FICM, ICP, cam/crank, batteries, fuel)

Setup

Runs on Windows, macOS, and Linux (Python + pyserial). The only per-OS difference is the CH340 USB driver:

  • Windows — install WCH CH341SER; adapter shows as USB-SERIAL CH340 (COMx) in Device Manager → Ports. Install Python from https://www.python.org/downloads/ (tick Add Python to PATH), or just double-click RUN_OBD.bat.
  • macOS — install WCH CH34xVCPDriver (Mac App Store or wch.cn). Port appears as /dev/cu.wchusbserial*. pip install pyserial.
  • Linuxch341 driver is built into the kernel (no install). Port is /dev/ttyUSB0; add yourself to the dialout group for access (sudo usermod -aG dialout $USER, then re-login). pip install pyserial.

The tool auto-detects the port on all three; pass it explicitly if needed (COM5, /dev/cu.usbserial-1420, /dev/ttyUSB0).

Usage

python obd_reader.py                # auto-detect the COM port
python obd_reader.py COM5           # force a port
python obd_reader.py COM5 9600      # force port + baud (default 38400)
python obd_reader.py COM5 --clear   # read, then optionally clear (asks to confirm)
python obd_reader.py COM5 -v        # verbose: show raw ELM327 traffic

Crank monitor (dedicated no-start view) — --crank

The one to use for a crank-but-won't-start. Big ICP readout with a wide bar (the | marks the 500-psi firing threshold), a rolling ASCII trace of the ICP build-up, peak-hold, FICM/battery/RPM with sag tracking, and a pass/fail verdict. Start it, then crank.

python obd_reader.py COM5 --crank                  # crank monitor
python obd_reader.py COM5 --crank --dash-log crank.csv   # + record a CSV
  ICP  [#################################|##----]   539.8 psi
  PEAK    540 psi   FIRING PRESSURE REACHED
  FICM Main 47.5V (min 47.5) [DOC]    Batt 12.6V (min 10.7)    RPM 200

  ICP trace (psi vs time, last 16 samples)
   600 |
   500 |----------------------------------------------####   <- firing line
       |                                            ######
       |                                          ########
       +--------------------------------------------------

Read it: ICP should climb past 500 psi within 12 s of cranking (FIRING PRESSURE REACHED, green). If it stalls below 500 (red, trace flat under the line), that's the high-pressure oil bleed-off — STC fitting / oil-rail O-rings. On exit it prints the peak and a verdict. q quits, r resets.

Live dashboard (real-time gauges)

Updates in place as you crank or run the engine — color-coded, with live min/max so a crank's peak ICP is captured. No extra dependencies (ANSI; works on any Windows 10+ terminal). q quits, r resets min/max.

python obd_reader.py COM5 --dash            # vitals preset (ICP, FICM, IPR, batt, RPM, temps)
python obd_reader.py COM5 --dash crank      # cranking preset: ICP / FICM main / batt / RPM (fastest)
python obd_reader.py COM5 --dash full       # every PID
python obd_reader.py COM5 --dash crank --dash-log crank.csv   # + write a CSV while you watch

No-start use: run --dash crank, then crank. A healthy 6.0 builds ~500+ psi ICP within 12 s; if ICP stalls below 500 (red), that confirms the high-pressure oil bleed-off. FICM Main should hold ~48V. The --dash-log CSV is your streaming log — paste it back for analysis.

Note: the FICM PIDs (09xx) are [DOC] (not yet confirmed on this truck); if they read --, they auto-drop after a few frames so the refresh rate stays up.

Or just double-click RUN_OBD.bat on Windows (auto-installs pyserial).

On the truck: plug into the OBD port under the dash, key to RUN (engine off is fine for codes), then run the tool.

Scope / honesty

A generic ELM327 reads standard OBD-II only: codes, generic PIDs, port voltage. It does not read Ford-enhanced diesel PIDs (ICP, FICM main/sync voltage, IPR%) — those need FORScan. For FICM/ICP numbers, measure at the FICM with a meter, or use FORScan when it's available. Default baud is 38400 (measured on the CH340 adapter); try 9600 if you get garbage.

Requirements

pyserial (pip install pyserial). Tested against a QinHeng CH340 ELM327 v1.5 clone.

S
Description
OBDash — open-source, vehicle-agnostic OBD-II scanner (Python/Qt). Live multi-axis graphs, car-style gauges, DTC read/clear, JSON vehicle profiles.
Readme MIT 1.8 MiB
v0.1.0 Latest
2026-06-30 16:53:36 -04:00
Languages
Python 99.7%
Batchfile 0.3%