FirmGod

J1939 PGN Decoder

Split a 29-bit J1939 identifier into priority, PGN, source and destination, or build the identifier for a PGN. PDU1 and PDU2 as SAE J1939-21 defines them.

Spaces are ignored, and a 0x prefix always means hexadecimal whatever the selector says.

Examples
PGN 652650xFEF1

Cruise Control/Vehicle Speed (CCVS1)

Identifier0x18FEF100 · 419361024
PGN0xFEF1 · 65265
PDU formatPDU2 — PF 254 ≥ 240, broadcast
Priority6 (110)
Source address0x00 · 0
Group extension0xF1 · 241
Data page / extended data pageDP 0 · EDP 0
ReachesEvery node
Bit layout110 0 0 11111110 11110001 00000000

Fields left to right: priority, EDP, DP, PDU format, PDU specific, source address.

Common PGNs

A short list of the messages that fill an ordinary capture, not a J1939 database. Anything else belongs in your own DBC.

59392Acknowledgement (ACKM)
59904Request (RQST)
60160Transport Protocol, Data Transfer (TP.DT)
60416Transport Protocol, Connection Management (TP.CM)
60928Address Claimed (AC)
61443Electronic Engine Controller 2 (EEC2)
61444Electronic Engine Controller 1 (EEC1)
65226Active Diagnostic Trouble Codes (DM1)
65227Previously Active Diagnostic Trouble Codes (DM2)
65247Electronic Engine Controller 3 (EEC3)
65253Engine Hours, Revolutions (HOURS)
65262Engine Temperature 1 (ET1)
65263Engine Fluid Level/Pressure 1 (EFL/P1)
65265Cruise Control/Vehicle Speed (CCVS1)
65266Fuel Economy, Liquid (LFE1)
65269Ambient Conditions (AMB)
65270Inlet/Exhaust Conditions 1 (IC1)
65271Vehicle Electrical Power 1 (VEP1)
65272Transmission Fluids 1 (TRF1)
65276Dash Display (DD)

How a J1939 identifier is laid out

J1939 runs on CAN with 29-bit extended identifiers, and SAE J1939-21 gives every bit of that identifier a job. Nothing is left for an implementer to choose, which is what allows a node from one manufacturer to make sense of a bus built by another:

  • Bits 28–26, priority — three bits, 0 highest. Used for arbitration only.
  • Bit 25, EDP and bit 24, DP — the extended data page and data page.
  • Bits 23–16, PF — the PDU format, which decides how the next byte is read.
  • Bits 15–8, PS — the PDU specific byte: a destination address or a group extension.
  • Bits 7–0, SA — the source address of the node that sent the frame.

The parameter group number is assembled from EDP, DP, PF and sometimes PS. Priority and source address are never part of it. That is the point of the split: the PGN identifies what the message is, while the identifier as a whole also says who sent it and how urgently.

The one rule that catches everybody

Whether PS belongs to the PGN depends on PF, and there is no separate flag for it:

  • PF below 240 — PDU1, addressed. PS is a destination address. The PGN's low byte is zero.
  • PF 240 or above — PDU2, broadcast. PS is a group extension and is part of the PGN.

Getting this backwards is the most common J1939 mistake, and it is self-concealing. A request sent to node 0x21 has the identifier 0x18EA21FE. Reading the middle two bytes as the PGN gives 0xEA21, which appears in no standard and no database, so the message looks like an unknown proprietary group. The actual PGN is 0xEA00 — 59904, the Request message — and 0x21 is simply who it was sent to. Treating the destination as part of the PGN turns one well-known message into 256 imaginary ones.

What priority does and does not do

CAN arbitration is decided bit by bit on the wire, and a dominant bit wins. Because priority occupies the top three bits of the identifier, a frame with priority 3 beats one with priority 6 whenever both start transmitting at once. The loser backs off and retries.

What priority does not do is change which message you are looking at. The same PGN can be sent at different priorities by different nodes, and it is still the same parameter group with the same signal layout. This is why a filter written against a full identifier can silently miss traffic: a node that raises its priority changes its identifier without changing what it is sending.

Addresses, and the two that are not nodes

Every node on a J1939 bus owns an address from 0 to 253, claimed at startup with the Address Claimed message (PGN 60928) and defended if another node claims the same one. Two values are reserved:

  • 254, the null address — used as a source by a node that has not won an address. Seeing it as a source means address claiming has failed or has not finished.
  • 255, the global address — used as a destination to address every node at once. A PDU1 message sent to 255 reaches the whole bus.

Reading a capture

Most of an ordinary heavy-vehicle capture is a handful of PDU2 messages repeating at fixed rates: engine speed and torque in EEC1, road speed in CCVS1, temperatures in ET1. They are broadcast because every node that cares can use them, and they carry no destination.

The PDU1 traffic is where the conversations are — requests, acknowledgements, transport protocol sessions for messages longer than eight bytes, and address claiming. If you are looking at a bus and trying to work out what talks to what, the addressed messages are the ones to follow.

This decoder names a small set of the parameter groups that fill a normal capture. It is not a J1939 database and does not try to be one; the standard defines thousands of parameter groups and their signal layouts are not freely redistributable. For anything outside the short list, the PGN this gives you is what you look up in your own DBC.

Building an identifier

Going the other way — from a PGN to the identifier you need to transmit — is where the PDU1 rule bites again. A PDU2 PGN carries its group extension, so the identifier follows directly from the PGN, the priority and your own source address. A PDU1 PGN needs a destination supplied separately, because the PGN deliberately does not contain one.

This tool refuses a PDU1 PGN whose low byte is not zero rather than quietly masking it off. A value like 0xEA21 in that field means the caller believes the destination is part of the parameter group, and encoding it anyway would produce a frame that does not mean what they think it means.

Frequently asked questions

Why does my PGN come out different from the one in the DBC?

Almost always because the message is PDU1 and the destination address was included. When PF is below 240 the PDU specific byte is a destination, not part of the parameter group, so the PGN ends in a zero byte. Reading 0xEA21 as the PGN of a request sent to node 0x21 gives a number that appears in no database; the PGN is 0xEA00, which is 59904.

What is the difference between PDU1 and PDU2?

It is decided entirely by the PDU format byte. Below 240 the message is addressed to one node and the next byte carries that address. At 240 and above the message is broadcast and the next byte is a group extension that belongs to the PGN. There is no flag saying which it is — the value of PF is the flag.

Does priority change the PGN?

No. Priority occupies the top three bits of the identifier and is deliberately outside the PGN, so the same parameter group can be sent at different priorities without becoming a different message. It affects arbitration only: a lower number wins the bus.

What are addresses 254 and 255 for?

254 is the null address, used as a source by a node that has not successfully claimed an address yet. 255 is the global address, used as a destination to reach every node at once. A PDU1 message sent to 255 is effectively a broadcast even though its format is the addressed one.

Why are some PGNs above 65535?

The data page and extended data page bits sit above the PDU format byte and are part of the PGN, which makes it 18 bits rather than 16. Most traffic has both bits clear, so most PGNs fit in 16 bits; the higher ranges are reserved for ISO 11992 and for NMEA 2000, which builds on the same identifier layout.

Can I use this for NMEA 2000?

The identifier layout is the same, so priority, PGN, source and destination all decode correctly. What differs is the meaning of the parameter groups and the data page usage, so the names shown here will not match an NMEA 2000 message even when the arithmetic does.