hondavert-dev/docs/HANDOFF.md
metatroncubeswdev e9b1c0f8fd Fuel pump flag, confirmed ECT/IAT/BAT offsets, persisted ECU type
Work that was previously only in the local working tree:
- Rename fuelCut -> fuelPump (SW2 bit2, active-low, live-confirmed)
- ECT/IAT/BAT moved to live-confirmed offsets 33/34/36
- S300 template-frame detection with hold-last-good logic
- Persist ECU type in SharedPreferences; drop per-connect protocol dialog
- Official-protocol probe and DTC clear on the debug/DTC screens
- Sanity clamp for multi-byte fields; scrollable vertical dashboard
- docs/HANDOFF.md

Includes temporary [DBG]/[KDBG] prints, removed in the next commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:02:05 -04:00

10 KiB

HV BT Dashboard — Data Layer Handoff

Context for continuing work on the S300/KPro Bluetooth data layer. Paste this into a new chat to resume.

To be continued tomorrow — debugging in progress, session ended mid-investigation

Was actively live-debugging a connection lockup with the phone connected and a flutter run session attached when the user had to leave. Nothing is currently running (flutter session and Monitor were both stopped cleanly), but the investigation is mid-thread — see "Today's session" below for exactly where it left off, and pick up from "Next steps for tomorrow" at the end.

The temporary debug print is still active in sensor_provider.dart (search for TEMP: live-debugging session, remove after — two spots, a dbgFrameCount counter and a print(...) call). It logs template/rpm/gear/ect/fuelPump/mil/vtec/fan/sw2 for S300 frames, throttled to ~2/sec. Don't re-add it tomorrow — it's already there. Remove it once this investigation is actually closed out.

Reference documents (in project root)

  • hvbt_protocol.pdf — legacy fixed-offset frame protocol (what the app currently uses). Ground truth for byte offsets/formulas, though its own offset labels are internally inconsistent — don't trust them without a live capture.
  • Bluetooth.pdf — Hondata's official, newer, self-describing channel-based protocol (v1.6, 2020). Confirmed via live probe that this specific hardware does NOT support it — legacy protocol is the only option.
  • Requrements.pdf — original customer UI/UX requirements, references a "TunerView" app as the visual benchmark.

Today's session: fuel pump held-during-template fix, then a fresh reproduction of the lockup

  1. Fixed: fuelPump, mil, vtec, fanOut are now also held from last-known-good during S300 template frames (sensor_provider.dart), not just RPM/VSS/MAP/etc and gear/ECT/IAT/BAT from the previous round. This was prompted by the user seeing fuel pump flip to a wrong value after leaving the app idle without changing anything on the bench — consistent with the connection sitting in a run of template frames (where SW2 was still being decoded fresh and showing whatever the frozen pattern happened to contain) during that idle stretch.
  2. Reproduced a worse case live: reconnected and watched a fresh session start with 100% template frames — zero live frames — for the first 103+ consecutive polls. Since lastGood had never been populated yet (no live frame had ever arrived), the hold logic had nothing to fall back on and just displayed raw template garbage (RPM=0, gear=1) directly. A manual disconnect/reconnect fixed it — RPM immediately started tracking real changes again (535 of the next 1159 frames were live).
  3. User raised a valid concern: will this lockup recur after sitting idle again? Proposed (but did not build, pending a decision) an auto-reconnect feature: detect N consecutive template frames with zero live data and trigger an automatic disconnect+reconnect, rather than requiring the user to notice and do it manually.
  4. It recurred within the same debugging session, unprompted, while just sitting idle — caught a long run of template=true, rpm=0 again in the log. It eventually broke free on its own (one live frame came through), but then the live debug session itself died: flutter run reported "Lost connection to device" and exited (the background bash task completed with exit code 0). This is the phone's USB/ADB link to the laptop dropping, not necessarily the phone's Bluetooth link to the ECU — those are two different connections and losing one doesn't necessarily mean the other dropped too.
  5. Unresolved when the session ended: whether the app itself (on the phone, independent of the USB debug tether) is still running/connected to the ECU via Bluetooth, or whether it also crashed/disconnected. Debug builds tied to an active flutter run session sometimes get killed when that session ends — this needs to be checked first thing tomorrow. adb devices showed the phone reachable again by the end of the session, so the USB/ADB link itself recovered at least.

Next steps for tomorrow, in order

  1. Check whether the app survived the "Lost connection to device" event — is it still open and showing data on the phone, or did it close? If it closed, that's itself worth understanding (does losing the USB/ADB tether kill the debug-mode app process, or was this a coincidental separate crash?).
  2. Decide on the auto-reconnect feature (see point 3 above) — now that the lockup has reproduced twice in one session, including a from-cold-start 100%-template case that the hold-last-good-value fix can't help with at all, this is probably worth building. Tradeoff to weigh: an automatic reconnect means a brief, visible disconnect/reconnect blip whenever it triggers, and if tuned too aggressively could interrupt a legitimately long-but-real stretch of template frames.
  3. Relaunch live debugging (see Environment notes) to keep characterizing the lockup — specifically it would help to know: does it always eventually self-recover (like it did once today), or does it sometimes stay stuck indefinitely without a manual reconnect? How long does a "stuck" stretch typically last? Does it correlate with anything (idle time specifically, or could be triggered by anything)?
  4. Once the lockup itself is on firmer ground, return to the still-open data fields below.

Confirmed & fixed (shipped, working — from before today, still holding)

  • RPM, VSS, MAP, IGN formulas: match the official doc / live captures. (IGN's formula itself may be worth a second look — one live check showed a big mismatch — not investigated further, low priority.)
  • TPS (offset 9, raw*100/255), Gear (offset 27): confirmed correct against live USB captures.
  • ECT (offset 33), IAT (offset 34), BAT (offset 36): all moved from earlier wrong offsets and confirmed via live capture matching USB closely.
  • Fuel Pump (SW2 bit 2, active-low: (sw2 & 0x04) == 0): confirmed correct when frame is live (non-template).
  • S300 "template frame" detection and hold logic: isS300TemplateFrame() in s300_parser.dart detects the frozen byte pattern (bytes 0-16, plus bytes 32-36 covering gear/ECT/IAT/BAT). sensor_provider.dart now holds RPM/VSS/MAP/TPS/INJ/IGN/knock/O2/gear/ECT/IAT/BAT/fuelPump/mil/vtec/fanOut from last-known-good during these frames. This only works once at least one live frame has been seen — a connection stuck in 100% template from the very start has nothing to hold and shows raw garbage (see today's session, point 2).
  • Root cause of the template-frame phenomenon itself is still unknown. Most likely an adapter-side sampling/buffering limitation, possibly related to whatever's now also causing full lockups (100% template, no live frames at all) after idle periods — these might be the same underlying issue at different severities, not two separate problems.
  • Bluetooth ECU-type persistence: connecting no longer shows a "S300 or KPro?" popup every time — it connects directly using whatever's set in Settings (persisted via SharedPreferences, survives app restart). bt_picker_screen.dart / settings_provider.dart.
  • Sanity clamp, dashboard scrolling, official protocol probe: unchanged from before, still working.
  • Clear DTC command: still not getting acknowledged over Bluetooth despite the ECU accepting it via USB — unresolved, lower priority than the connection lockup.

Still open — data fields needing live data to resolve (lower priority than the lockup investigation above)

  • SW1 during template frames — never actually confirmed either way for this specific frame type.
  • AFR: confirmed wrong (aliased to ERR03's byte). No correct offset found.
  • PA: candidate at offset 50 is close (~3 kPa off) but not confirmed.
  • IGN formula: flagged as possibly wrong, not investigated.

Verification method that has worked every time

  1. Set a bench value to something specific and known.
  2. Screenshot the USB tool's reading (fuller flag panel = more cross-checks per shot).
  3. Attach a live debug session and read raw frame data straight from the console at the same moment — cross-check RPM between the screenshot and the log line to confirm they're actually simultaneous.
  4. Compute the byte offset/formula that reproduces the known value.
  5. Get a second data point or a stability check across many consecutive frames before changing code.

Do not guess offsets from the PDF's offset column labels alone. Always confirm against a live capture, and always check whether the frame in question is a template frame before trusting its bytes beyond 16.

Not started yet (deferred until data layer + connection stability are solid)

UI/UX gaps from Requrements.pdf: dashboard tile count (need 10, have 6), missing "SubSensor" next to main gauge, flag pills should be selectable (spec says 4, currently a fixed 7), datalog playback not wired to live display screens.

Environment notes

  • Test device: Samsung SM_S948W, adb -s R3GL40CPKMP (transport ID changes across reconnects, device serial stays the same).
  • Build/install cycle: flutter build apk --debug then adb -s R3GL40CPKMP install -r build\app\outputs\flutter-apk\app-debug.apk.
  • Live debug session (preferred method, used heavily and successfully this whole project): flutter run -d R3GL40CPKMP --debug (run in background). Pair with a Monitor that dedupes or does stateful filtering (e.g. only alert on entering/leaving a "stuck" run of N consecutive template frames) rather than raw tail+grep, which gets rate-limited. Known failure mode: the session can die with "Lost connection to device" if the phone's USB/ADB link drops — check adb devices and relaunch if so.
  • All parser changes should get a unit test in test/s300_parser_test.dart (or kpro_parser_test.dart) built from actual captured bytes.
  • git status shows all data-layer, DTC/debug-screen, and BT-connection changes as uncommitted modifications, plus the three reference PDFs and this handoff doc as untracked. Nothing has been committed this project.