Recent Posts
SAE J1939 ECU Simulation And Data Monitoring Under Linux
Posted by
onOur 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 an 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, such as the Raspberry Pi, which includes full C source code for short-time-to-market developments.
The board's strength 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 a 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 Linux PC.
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, so no driver installation is required.
The JCOM.J1939.USB board uses a 5-pin terminal connector for the CAN/J1939 connection. The boards also feature an internal termination resistor of 120 Ohm, activated by inserting a wire jumper in the terminal block (the jumper is installed by default).
The connections (from top to bottom) are:
- CAN_H
- CAN Termination Wire Jumper
- CAN Termination Wire Jumper
- CAN_L
- GND
Important!
It may sound obvious, but it is 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 second), which indicates that the board is "awake" and working, but that doesn't prove 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 and 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)
- ECU NAME
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);
COM1939_Initialize(&sCOMPort[0]);
COM1939_SendMessageMode(MSGMODE_GATEWAY2);
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:
COM1939_AddFilter(PGN_SAMPLE_RX);
PGN_SAMPLE_RX is defined in config.h and can be replaced with any PGN. Of course, you can add more PGNs using the same function call (up to 80 PGNs).
To negotiate an address, use this line:
COM1939_SetProtocolParameters(msgNAME, SA_PREFERRED, ADDRESSRANGEBOTTOM, ADDRESSRANGETOP, OPMODE_EVENT, true);
Again, all parameters are set in config.h.
Please know that you need a valid J1939 node address before transmitting 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
To compile the program, run the following command in terminal mode:
gcc main.c COM1939.c CANInterface.c -o jCOM1939
You can use any name other than jCOM1939 for the executable file.
To run the program, type:
./jCOM1939
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. To use this program, please use "/dev/ttyUSB0" as your COM port.
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: