Skip to content

Fix: J1939 decoded wrong values from wrong bytes and wrong messages - #28

Merged
Sherin-SEF-AI merged 1 commit into
mainfrom
fix/j1939-layouts
Sep 23, 2026
Merged

Sherin-SEF-AI merged 1 commit into
mainfrom
fix/j1939-layouts

Conversation

@Sherin-SEF-AI

@Sherin-SEF-AI Sherin-SEF-AI commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

The defects

The J1939 table produced confident wrong numbers, and nothing tested a layout. Checked against SAE J1939-71 and against the 145,534-frame truck log in the acceptance corpus:

Was Is
Coolant temperature read from EFL/P1 byte 6 (half of crankcase pressure) ET1 byte 1, which was not decoded at all
0xF005 labelled ETC1, fields at the wrong bytes 0xF005 is ETC2; ETC1 is 0xF002
EBC2 wheel speeds under 0xFE68, ERC1 under 0xF006 0xFEBF, 0xF000
VEP voltages read from the current bytes bytes 5-6 and 7-8
Barometric pressure read from cab temperature's low byte byte 1
"Cruise Control Active = 195" (a whole-byte read of the parking brake byte) a two-bit state in byte 4
Only all-ones meant "not available" J1939 error (0xFE, 0xFExx) and reserved ranges handled
SA 0x21 "Brakes", 0x3D "Retarder", most others the J1939 preferred address table (0x0B is the brakes)
Scan kept the first sender of each PGN one row per PGN and sender; counts cover every frame

The fix

canlab/core/j1939_db.py holds the layouts as bit fields: 26 decoded PGNs, 152 parameters, 30 more named, Proprietary B named as such, the preferred source address table, two-bit states, error and reserved ranges, park as a gear, ASCII transmission ranges. decode_pgn keeps its return shape; an error code is the string "error", and not-available is left out. decode_spns returns SPN numbers and status for tools that need to cite them.

Verified on the real truck

  • The brakes' EBC2 front axle speed and the engine's CCVS wheel speed differ by 0.33 km/h on average over 1,957 pairs, r 0.9997.
  • Absolute inlet pressure minus boost pressure: 102 kPa; the barometer reads 101.
  • VD and HRVD both give 464,671 km; lifetime distance over fuel is 2.464 km/L against the ECU's reported 2.475.
  • Coolant 90-97 °C, oil 102-104 °C, battery 14.05 V from four ECUs, 4 °C ambient in January; position decodes to Pennsylvania, consistent with a 12 V North American truck.

Those checks are now in acceptance_stress.py (7/7). tests/test_j1939_spns.py pins 22 layouts with frames copied from the truck, plus the value ranges, no overlapping parameters, and the per-sender scan.

pytest -q: 699 passed. acceptance_new_sources.py: 57/57. ruff clean.

The PGN table produced confident wrong numbers. Checked against SAE
J1939-71 and against the 145,534-frame truck log in the corpus:

- Coolant temperature was read from byte 6 of EFL/P1, which is half of
  the crankcase pressure. It lives in ET1, which was not decoded at all.
- 0xF005 was labelled ETC1; it is ETC2, and its three fields were at the
  wrong bytes. EBC2's wheel speeds were filed under 0xFE68 and ERC1
  under 0xF006.
- VEP battery voltages were read from the current bytes, barometric
  pressure from cab temperature's low byte, oil level from the blow-by
  byte.
- Cruise control active and enable were whole-byte reads of byte 1, the
  parking brake and axle switch byte: "Cruise Control Active = 195".
- Only all-ones was treated as "not available", so J1939 error codes
  (0xFE, 0xFExx) and reserved ranges were decoded as readings.
- Most source address names did not match the preferred address table:
  0x21 was "Brakes" (it is the body controller; brakes are 0x0B).
- The scan kept the first sender of each PGN and dropped the rest, so
  DM1 from nine ECUs was one row with one ECU's count.

The table now lives in core/j1939_db.py as bit fields: 26 decoded PGNs
with 152 parameters, 30 more named, the preferred address table, two-bit
states, error and reserved ranges, park as a gear, ASCII ranges. The
scan is a row per PGN and sender.

On the truck log the corrected layouts agree with each other: the
brakes' front axle speed and the engine's wheel speed differ by 0.33
km/h over 1,957 pairs (r 0.9997); absolute inlet pressure minus boost is
the barometer; VD and HRVD give the same 464,671 km; lifetime distance
over fuel matches the ECU's reported economy to 0.5%. Those checks are
now in the stress run, and 22 unit tests pin the layouts with frames
copied from the truck.
@Sherin-SEF-AI
Sherin-SEF-AI merged commit 9d07dbb into main Sep 23, 2026
2 checks passed
@Sherin-SEF-AI
Sherin-SEF-AI deleted the fix/j1939-layouts branch September 23, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant