Site Information

 Loading... Please wait...

SAE J1939 ECU Simulation And Data Monitoring Under Linux

Posted by Wilfried Voss on

SAE J1939 ECU Simulator Board With USB Port to simulate J1939 data traffic under Linux

Our   jCOM.J1939.USB gateway board is a high-performance, low-latency vehicle network adapter for SAE J1939 applications. It allows any host device with a USB COM port to monitor SAE J1939 data traffic and communicate with a SAE J1939 vehicle network.

The board supports the full SAE J1939 protocol according to J1939/81 Network Management (Address Claiming) and J1939/21 Transport Protocol (TP). It is also supported by an extensive programming interface for Linux systems, for instance the Raspberry Pi, including full C source code for short time-to-market developments.

The strength of the board lies in the fact that the entire SAE J1939 protocol, including all timing requirements, is stored on-chip, thus taking the burden off the host system (usually a PC system running Windows or Linux). The board uses a USB COM port to communicate with the PC, i.e. all data transfer is handled through standard COM port access (For example, under Linux using /dev/ttyUSB0). The communication protocol between the board and the main system is well documented, allowing a portation to any computer system with USB connection. A working source code library exists for the Linux operating system (C using the standard gcc compiler).

With all its features, the jCOM.J1939.USB allows the simulation of an SAE J1939 ECU (Electronic Control Unit) or J1939 data monitoring using a PC running Linux.

Connecting the jCOM.J1939.USB Board

Connect the jCOM.J1939.USB board to any free USB port on your Linux system. The operating system will recognize the new USB connection automatically, meaning there is no driver installation required.

For the CAN/J1939 connection, the jCOM.J1939.USB board uses a 5-pin terminal connector. The boards also features an internal termination resistor of 120 Ohm, which is activated by inserting a wire jumper in the terminal block (the jumper is installed per default).

The connections (from top to bottom) are:

  • CAN_H
  • CAN Termination Wire Jumper
  • CAN Termination Wire Jumper
  • CAN_L
  • GND


It may sound obvious, but it is, nevertheless, overseen frequently: You will need a second SAE J1939 node (or an entire network) to check the board's full functionality. The board comes with a "heartbeat" function (i.e. a heartbeat message sent per USB every one second), which indicates that the board is "awake" and working, but that doesn't proof any SAE J1939 functionality. 

On-Board LEDs

The jCOM.J1939.USB board comes with three LEDs:

  • PWR - Directly connected to power.
  • LED2 - Indicates USB port activity (including heartbeat message)
  • LED1 - CAN / SAE J1939 activity

Upon powering up the board you will see the power LED plus the USB LED blinking with a one second frequency (heartbeat).

Programming the jCOM.J1939.USB Using C

The jCOM.J1939.USB C source code contains of the following files:

  • main.c
  • config.h
  • COM1939.c
  • COM1939.h
  • CANInterface.c
  • CANInterface.c

The config.h file is important, because it allows some user/application settings such as:

  • Preferred Node Address (for Address Claim Process)
  • Negotiable Node Address Range (also for Address Claim Process)

The COM1939 and CANInterface modules manage the communication between the Linux system and the jCOM.J1939.USB board. These modules need no further detailed attention, unless you want to spend the time to understand and extend them. 

The most important module, when it comes to mere application programming, is main.c

To initialize the board, use the following lines:

strcpy(sCOMPort, COMPORT);

In order to call the SAE J1939 protocol stack, you need only one line:

int nStatus = COM1939_Receive(&lPGN, &nPriority, &nSourceAddress, &nDestAddress, &nData[0], &nDataLen);

This function call receives messages from the J1939 network. However, before you can receive any messages, you will need to set message filters for the PGNs you need:


PGN_SAMPLE_RX is defined in config.h and it can be replaced with any PGN. And, of course, you can add more PGNs using the same function call (up to 80 PGNs).

To negotiate an address, use this line:


Again, all parameters are set in config.h.

Please, be aware that you need a valid J1939 node address before you can transmit data into the network. To transmit data, use the following line:

COM1939_Transmit(6, PGN_SAMPLE_TX, nSA, DEST_ADDR_SAMPLE, &SampleTxData[0], 8);

For further details, have a closer look at the main.c file. The code explains all functionality is an easy-to-comprehend form.

Compile and Run the C Program

In order to compile the program, run the following command in terminal mode:

gcc main.c COM1939.c CANInterface.c -o jCOM1939

Naturally, you can use any other name than jCOM1939 for the executable file.

To run the program, type:


Further Information

Download the C Source Code

Attention! If you use the Microsoft Edge browser, look at the bottom of the browser for the download file.

Note: I have extended this program to support data logging, i.e. writing the SAE J1939 data to a text file. In order to use this program, please assure you use "/dev/ttyUSB0" as your COM port. For more information, see SAE J1939 Data Stream Recording With Raspberry Pi.

All sample programs and other code samples and projects as introduced on this website are free software; you can redistribute and/or modify them. The programs are introduced in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. With downloading any of these programs, you confirm that these code samples and projects were created for demonstration and educational purpose only. 

Some Screen Shots

To edit or view any of the program modules use the internal editor, for instance:

nano config.h

After executing the jCOM1939 program, the screen will show the COM port status, either successful (as shown here; we used a Raspberry Pi for our tests) or with an error message:

Type 'h' for help:

Type 'b' to check the reception of the heartbeat message:

Type 'f' to apply the message filter, type 'd' to delete the message filter:

Type 'c' to initiate the address claim process:

Type 't' to transmit a J1939 data frame: