Guides · 2026-08-29 · 6 min

Reading J1939 on Android

How SAE J1939 sits on top of CAN, what PGNs and SPNs actually are, and how to get a readable trace from a truck or machine using an Android phone and a USB CAN adapter.

J1939 is not a separate bus. It is an application layer defined by SAE that runs on 29-bit extended CAN at 250 kbit/s (and, on newer machines, 500 kbit/s). Heavy trucks, agricultural machinery, construction equipment and marine engines nearly all speak it. If you can capture CAN frames, you already have the raw material — the work is turning identifiers into parameters.

PGN and SPN in one paragraph each

A Parameter Group Number (PGN) identifies the message. It is encoded inside the 29-bit CAN identifier along with priority, source address and, for peer-to-peer messages, a destination address. Broadcast engine data such as Electronic Engine Controller 1 (EEC1) arrives as a PGN roughly every 20 ms from the engine controller's source address.

A Suspect Parameter Number (SPN) identifies one signal inside that message: engine speed, coolant temperature, accelerator pedal position. Each SPN has a defined start bit, length, scale factor and offset. Engine speed, for example, is 16 bits at 0.125 rpm per bit — a raw value of 8000 is 1000 rpm, not 8000.

Wiring up

  • A phone or tablet running Android 11 or newer. For a USB adapter the device must support USB OTG / host mode.
  • A CAN adapter: a PEAK PCAN-USB (or PCAN-USB FD) or a CANable/SLCAN-class adapter.
  • A cable to the vehicle's diagnostic connector. Heavy vehicles typically use a 9-pin Deutsch (J1939-13) connector rather than the 16-pin OBD-II socket found on cars.
  • Termination awareness: the bus is already terminated at both ends. Do not add a third terminating resistor by enabling one on the adapter unless you are replacing an end node.

Getting a first trace

Set the bitrate to 250 kbit/s and open the live monitor in listen-only mode if your adapter supports it. On a running vehicle you should see a dense stream of extended identifiers within a second. If the trace is empty, the usual causes are the wrong bitrate, CAN High and CAN Low swapped, or a connector that only exposes the body bus rather than the powertrain bus.

Once frames are flowing, group by identifier to see how many distinct messages are on the bus and at what rate. A typical medium-duty truck at idle shows a few dozen recurring PGNs. This grouping alone often answers the question you came with: whether a controller is transmitting at all.

From frames to named signals

ProtocolWatcher decodes J1939 PGNs and SPNs directly, so common engine and transmission parameters show up named and scaled without any extra setup. For proprietary or OEM-specific messages, import a DBC file and the same live view will decode those signals too, including on the live plot.

Where a value looks implausible — coolant temperature at 200 °C, engine speed pinned at zero on a running engine — check the SPN's byte order before assuming a fault. J1939 signals are little-endian, and a decoder configured big-endian produces exactly this class of nonsense.

Keeping the evidence

Export the capture to CSV for spreadsheet work, or to ASC or BLF if it will be opened later in desktop CAN tooling. A capture can also be replayed through the live UI at 1×, 2× or 4×, which is a practical way to re-examine an intermittent fault at the desk instead of under the vehicle.

Trying it without a vehicle

Demo Mode simulates the protocols, including CAN traffic, so the workflow above can be walked through before buying an adapter or booking bay time.