Correct Ford 6.0 Mode-22 PID table from workflow research
The old 12xx PIDs (1209/1228/120B/...) were wrong addresses -- that's why they returned 'no response' on the truck, NOT a bus/gateway problem. The real Ford-enhanced DIDs are in the 09xx/14xx/16xx families. Confirmed by the truck's own brute-scan: 1446=ICP, 1445=EBP, 1440=MAP, 1442=BARO, 1310=EOT, 11B3=gear, 11B4=TSS all decode to sane on-vehicle values. - Rewrite FORD_60_PIDS with corrected addresses + [VERIFIED]/[DOC]/[TENTATIVE] tags - FICM voltages -> 09D0/09CF/09CE/09CD (09D0 Main = the ~48V no-start metric) - ICP=1446 *0.57, IPR=1434, ICP_V=16AD; EOT scaling fixed to /100-40 - watch --ford now streams 09D0/09CF/1446/1434 (FICM main V + ICP during crank) - Add diagnostics/2026-06-29-no-start/pid-research.md (full workflow findings) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yT89n4zR4qbrySoSiEyZs
This commit is contained in:
+61
-38
@@ -11,19 +11,19 @@ Scope (what a generic ELM327 CAN do, engine off / KOEO):
|
||||
* Read key KOEO live PIDs (coolant, IAT, MAP, module voltage, RPM...)
|
||||
* Battery voltage at the OBD port (ATRV)
|
||||
|
||||
Experimental: with --ford it also tries a handful of community-sourced
|
||||
Ford-enhanced Mode-22 PIDs (ICP, IPR%, FICM main/sync/logic voltage, EBP,
|
||||
EOT). The PID numbers and scaling are TENTATIVE and need to be verified
|
||||
against a known-good reading (meter or FORScan). Raw bytes are always
|
||||
printed so you can sanity-check. Wrong PID = "no response", nothing
|
||||
written to the truck.
|
||||
Ford enhanced (--ford): reads Ford-enhanced Mode-22 PIDs (ICP, IPR%, FICM
|
||||
main/logic/vehicle voltage + sync, MAP/BARO/EBP, EOT, gear). Addresses were
|
||||
corrected 2026-06-29 (see diagnostics/2026-06-29-no-start/pid-research.md):
|
||||
14xx/13xx/11Bx are VERIFIED on this truck; the 09xx FICM family is documented
|
||||
but not yet read here -- re-probe to confirm. Raw bytes are always printed.
|
||||
ICP_DES (desired ICP) has no public Mode-22 DID -> FORScan-only.
|
||||
|
||||
Usage (Windows):
|
||||
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
|
||||
python obd_reader.py --ford # + try Ford 6.0 Mode-22 PIDs
|
||||
python obd_reader.py --pid 1430 # probe one Mode-22 PID, show raw
|
||||
python obd_reader.py --ford # + read Ford 6.0 Mode-22 PIDs
|
||||
python obd_reader.py --pid 1446 # probe one Mode-22 PID (1446=ICP), show raw
|
||||
python obd_reader.py --clear # erase stored + pending DTCs
|
||||
|
||||
Requires: pip install pyserial
|
||||
@@ -142,32 +142,54 @@ def _u16(b):
|
||||
return (b[0] << 8) + b[1]
|
||||
|
||||
|
||||
# Confidence tags in the notes column:
|
||||
# [VERIFIED] multi-source AND confirmed by this truck's own brute-scan
|
||||
# (the 14xx/13xx/11Bx PIDs returned sane values on-vehicle)
|
||||
# [DOC] corroborated in >=2 independent sources but NOT yet read on
|
||||
# this truck (the 09xx FICM family was outside the scan window)
|
||||
# [TENTATIVE] single-source or disputed scaling -- sanity-check before trust
|
||||
#
|
||||
# These addresses were corrected 2026-06-29 by the ford-60-pid-hunt workflow.
|
||||
# The OLD 12xx numbers (1209/1228/120B/...) were WRONG -- not real Mode-22
|
||||
# DIDs -- which is why they all returned "no response" on the truck. See
|
||||
# diagnostics/2026-06-29-no-start/pid-research.md for sources and the full
|
||||
# verification. (ICP_DES / desired ICP has no public Mode-22 DID -> FORScan-only.)
|
||||
FORD_60_PIDS = [
|
||||
# --- Injection Control Pressure (need ~500+ psi to fire) ---
|
||||
("1209", "ICP", "psi", lambda b: _u16(b),
|
||||
"Injection Control Pressure (need ~500+ psi to fire)"),
|
||||
("121A", "ICP_DES", "psi", lambda b: _u16(b),
|
||||
"ICP desired (commanded)"),
|
||||
("1430", "ICP_V", "V", lambda b: _u16(b) / 1000.0,
|
||||
"ICP sensor raw voltage"),
|
||||
("1446", "ICP", "psi", lambda b: round(_u16(b) * 0.57, 1),
|
||||
"[VERIFIED] Injection Control Pressure -- need ~500+ psi to fire"),
|
||||
("16AD", "ICP_V", "V", lambda b: round(_u16(b) * 0.000072, 4),
|
||||
"[TENTATIVE] ICP sensor raw voltage (single-source)"),
|
||||
|
||||
# --- Injection Pressure Regulator duty ---
|
||||
("120B", "IPR", "%", lambda b: round(b[0] * 100 / 255, 1),
|
||||
"IPR duty (high = trying hard to make ICP)"),
|
||||
("1434", "IPR", "%", lambda b: round(b[0] * 13.53 / 35, 1),
|
||||
"[TENTATIVE] IPR duty -- KOEO ~14-15%, cranking ~30-40%, idle ~25-30%"),
|
||||
|
||||
# --- FICM voltages -- THE 6.0 no-start metric (~48V cranking) ---
|
||||
("1228", "FICM_MPWR", "V", lambda b: _u16(b) / 1000.0,
|
||||
"FICM Main Power -- want ~48V cranking, <45V = suspect"),
|
||||
("1229", "FICM_SYNC", "V", lambda b: _u16(b) / 1000.0,
|
||||
"FICM Sync Power"),
|
||||
("122A", "FICM_LPWR", "V", lambda b: _u16(b) / 1000.0,
|
||||
"FICM Logic Power (~12V)"),
|
||||
("09D0", "FICM_MPWR", "V", lambda b: round(_u16(b) / 256.0, 1),
|
||||
"[DOC] FICM Main Power -- want ~48V cranking, <45V = suspect"),
|
||||
("09CF", "FICM_LPWR", "V", lambda b: round(_u16(b) / 256.0, 1),
|
||||
"[DOC] FICM Logic Power (~12V)"),
|
||||
("09CE", "FICM_VPWR", "V", lambda b: round(_u16(b) / 256.0, 1),
|
||||
"[DOC] FICM Vehicle Power (battery, ~12-14V)"),
|
||||
("09CD", "FICM_SYNC", "", lambda b: (b[0] >> 1) & 1,
|
||||
"[DOC] FICM Sync -- 1=in sync, 0=no sync (bit 1 of A)"),
|
||||
|
||||
# --- Exhaust back pressure / oil temp (handy, not no-start critical) ---
|
||||
("121C", "EBP", "psi", lambda b: _u16(b) / 100.0,
|
||||
"Exhaust Back Pressure"),
|
||||
("1310", "EOT", "C", lambda b: b[0] - 40,
|
||||
"Engine Oil Temperature"),
|
||||
# --- Pressures (all raw*0.03625 -> psi ABSOLUTE) ---
|
||||
("1440", "MAP", "psi", lambda b: round(_u16(b) * 0.03625, 2),
|
||||
"[VERIFIED] Manifold Absolute Pressure (psi abs; MGP boost = MAP-BARO)"),
|
||||
("1442", "BARO", "psi", lambda b: round(_u16(b) * 0.03625, 2),
|
||||
"[VERIFIED] Barometric Pressure (psi abs)"),
|
||||
("1445", "EBP", "psi", lambda b: round(_u16(b) * 0.03625, 2),
|
||||
"[VERIFIED] Exhaust Back Pressure (psi abs; minus BARO = gauge)"),
|
||||
|
||||
# --- Oil temp / driveline ---
|
||||
("1310", "EOT", "C", lambda b: round(_u16(b) / 100.0 - 40, 1),
|
||||
"[VERIFIED] Engine Oil Temperature"),
|
||||
("11B3", "GEAR", "", lambda b: b[0] // 2,
|
||||
"[VERIFIED] Current gear (5R110W TorqShift)"),
|
||||
("11B4", "TSS", "rpm", lambda b: _u16(b) / 4,
|
||||
"[VERIFIED] Trans input/turbine shaft speed"),
|
||||
]
|
||||
|
||||
|
||||
@@ -408,10 +430,11 @@ def read_ford_pids(elm, pids=None):
|
||||
if pids is None:
|
||||
pids = FORD_60_PIDS
|
||||
print("\n" + "-" * 64)
|
||||
print(" FORD 6.0 ENHANCED (Mode 22) -- TENTATIVE / UNVERIFIED")
|
||||
print(" FORD 6.0 ENHANCED (Mode 22)")
|
||||
print("-" * 64)
|
||||
print(" PID numbers and scaling are community-sourced and NOT yet")
|
||||
print(" verified on this truck. Raw bytes shown for sanity-checking.")
|
||||
print(" [VERIFIED] = confirmed on this truck's scan; [DOC] = corroborated")
|
||||
print(" in sources but not yet read here (re-probe to confirm);")
|
||||
print(" [TENTATIVE] = single-source/disputed scaling. Raw bytes shown.")
|
||||
print(" 'no response' = wrong PID or this PCM doesn't expose it.")
|
||||
print()
|
||||
any_response = False
|
||||
@@ -464,17 +487,17 @@ def watch_loop(elm, seconds=20, with_ford=False):
|
||||
"""Stream battery + module voltage as fast as we can for N seconds.
|
||||
Designed for cranking: start it, then turn the key.
|
||||
|
||||
with_ford=True also streams Mode-22 FICM/ICP PIDs -- only enable once
|
||||
those PIDs are verified for this PCM, otherwise each 'no response'
|
||||
timeout starves the sample rate."""
|
||||
with_ford=True also streams Mode-22 FICM/ICP PIDs. 09D0 (FICM Main) is
|
||||
the no-start metric -- watch it sag during cranking (<45V = failing FICM).
|
||||
The 09xx PIDs are [DOC]-grade (not yet read on this truck) -- if they
|
||||
'no response', the timeout will starve the sample rate, so drop --ford."""
|
||||
stream_pids = []
|
||||
if with_ford:
|
||||
stream_pids = [
|
||||
("1228", "FICM_M", "V", lambda b: (b[0] << 8 | b[1]) / 1000.0),
|
||||
("1229", "FICM_S", "V", lambda b: (b[0] << 8 | b[1]) / 1000.0),
|
||||
("122A", "FICM_L", "V", lambda b: (b[0] << 8 | b[1]) / 1000.0),
|
||||
("1209", "ICP", "psi", lambda b: (b[0] << 8 | b[1])),
|
||||
("120B", "IPR", "%", lambda b: round(b[0] * 100 / 255, 1)),
|
||||
("09D0", "FICM_M", "V", lambda b: round((b[0] << 8 | b[1]) / 256.0, 1)),
|
||||
("09CF", "FICM_L", "V", lambda b: round((b[0] << 8 | b[1]) / 256.0, 1)),
|
||||
("1446", "ICP", "psi", lambda b: round((b[0] << 8 | b[1]) * 0.57, 1)),
|
||||
("1434", "IPR", "%", lambda b: round(b[0] * 13.53 / 35, 1)),
|
||||
]
|
||||
print("\n" + "=" * 64)
|
||||
print(f" WATCH MODE ({seconds}s) -- Ctrl-C to stop early")
|
||||
|
||||
Reference in New Issue
Block a user