After receiving the Top Docker Author badge last week for my Offline AI post (thanks everyone! ๐), many of you asked about my workflow for hardware and vehicle networks.
So today, I'm switching gears from AI to Heavy Duty Vehicles.
If you work with CAN Bus or SAE J1939 (Trucks, Buses, Machinery), you know the pain:
- Professional tools are expensive: A Vector CANalyzer license costs thousands of dollars.
- Hex dumps are unreadable: Seeing
18FEF100means nothing unless you memorize the J1939 spec. - Hardware dependency: You usually need a physical adapter (PCAN, Kvaser) just to test your code.
To solve this, I built a Python-based J1939 Sniffer that decodes PGNs automatically and includes a Simulation Mode for hardware-free development.
๐๏ธ The Challenge: Parsing 29-bit IDs
Standard CAN (11-bit) is simple. But J1939 uses 29-bit Extended Identifiers, which pack a lot of data:
- Priority (3 bits)
- PGN (Parameter Group Number) (18 bits) <--- The most important part
- Source Address (8 bits)
If you get a raw ID like 0x18FEF100, you need to extract the PGN to know what the message actually is.
The Python Logic
Here is the core logic I used to extract the PGN and Source Address from a raw integer ID:
def parse_j1939_id(can_id):
"""
Extract PGN and Source Address from a 29-bit CAN ID.
Format: [Priority(3)] [Reserved(1)] [Data Page(1)] [PDU Format(8)] [PDU Specific(8)] [Source Address(8)]
"""
# Shift right by 8 bits to drop Source Address
# Mask with 0x3FFFF to keep only the 18-bit PGN
pgn = (can_id >> 8) & 0x3FFFF
# Mask with 0xFF to get the last 8 bits
source_address = can_id & 0xFF
# Shift right by 26 bits to get Priority
priority = (can_id >> 26) & 0x7
return pgn, source_address, priority
๐ ๏ธ The Solution: A GUI Sniffer
I wrapped this logic into a Tkinter GUI using the python-can library. It listens to the bus, parses the ID, and looks up the PGN in a built-in dictionary.
The Result
Instead of staring at 18FEF100, the tool tells you: ๐ CCVS - Vehicle Speed
Instead of 0CF00400, it shows: ๐ EEC1 - Engine Speed (RPM)
Features
๐ Auto-Decode: Built-in dictionary for common PGNs (RPM, Temp, Speed, Battery).
๐ฎ Simulation Mode: Click "Start Demo" to generate fake J1939 traffic. Perfect for testing UI logic without sitting in a truck.
๐ Universal Support: Works with Vector, Peak-System (PCAN), Kvaser, and slcan via python-can.
๐ฅ Try it yourself
I have open-sourced the project structure and the J1939 parsing logic on GitHub. You can use it as a template for your own ECU tools.
๐ GitHub Repository: Python-CAN-Bus-J1939-Sniffer-GUI
๐ For those who want the full package: If you want the complete, production-ready source code (including the GUI, Simulation Mode, and Multi-threading), I've made it available on Gumroad.
๐ฅ Black Friday Deal: Use code BLACKFRIDAY for 15% OFF all my engineering tools.
๐ Get the Full Source Code(link)
Happy Hacking! ๐
Top comments (0)