Supported platforms: CODESYS 2.3, CODESYS 3.5, CODESYS 3.5 SAFETY
J1939 is a CAN based protocol, that is used for communication with an engine, for example.
Required:
|
The code template depends on the used platform. This guide shows an example of
|
In SDK3.8 or newer J1939 PGN message's (source and/or destination) address can be manual or use address claiming. See Using Address Claiming for more details on using PGNs with address claiming. |
To start using J1939 (this example is configured using MultiTool 6.9):
1. In MultiTool, add a J1939 device (named "Engine" in this example) and make the needed configurations:
set the properties
add the J1939 device to a network
configure CAN bus
define the needed PGN messages
For more detailed description, refer to Epec MultiTool Creator manual.
2. MultiTool generates the initializations for J1939 to the code template and generates the following structures.
This example receives EEC1, HOURS, DM1 and ET1 PGNs.
Code template structure exampleCode template structure example
Code template example |
Description |
VAR_GLOBAL J1939_CAN2: J1939_CAN2; J1939_FB_CAN2: J1939; END_VAR
|
MultiTool generates J1939 global variable list to CODESYS IDE's Resources tab. |
TYPE J1939_CAN2 : STRUCT In: J1939_CAN2_IN; Out: J1939_CAN2_OUT; END_STRUCT END_TYPE
|
MultiTool generates a struct for J1939 messages:
|
TYPE J1939_CAN2_IN : STRUCT Engine : J1939_CAN2_IN_Engine; PGNs: ARRAY [1..G_J1939_CAN2_RX_PGNS] OF J1939_pPGN; END_STRUCT END_TYPE
|
MultiTool Creator generates separate structs for received and transmitted messages. It also generates a table for PGN messages to be used by library. Engine contains the PGN variables that are configured in MultiTool Creator for the device in question.
|
TYPE J1939_CAN2_IN_Engine : STRUCT (*PGN: EEC1, F004*) EEC1_EngTorqueMode: BYTE; EEC1_ActualEnginePercentTorqueHiRes: BYTE; EEC1_DriversDemandEngPercentTorque: BYTE; EEC1_ActualEngPercentTorque: BYTE; EEC1_EngSpeed: WORD; EEC1_SrcAddrssOfCtrllngDvcForEngCtrl: BYTE; EEC1_EngStarterMode: BYTE; J1939_CAN2_EEC1_Dummy_RX_1: BYTE; EEC1_EngDemandPercentTorque: BYTE; PGN_EEC1_SPNs:ARRAY[1..9] OF J1939_SPN; PGN_EEC1:J1939_PGN; (*PGN: HOURS, FEE5*) HOURS_EngTotalHoursOfOperation: DWORD; HOURS_EngTotalRevolutions: DWORD; PGN_HOURS_SPNs:ARRAY[1..2] OF J1939_SPN; PGN_HOURS:J1939_PGN; (*PGN: ET1, FEEE*) ET1_EngCoolantTemp: BYTE; ET1_EngFuelTemp: BYTE; ET1_EngOilTemp1: WORD; ET1_EngTurboOilTemp: WORD; ET1_EngIntercoolerTemp: BYTE; ET1_EngIntercoolerThermostatOpening: BYTE; PGN_ET1_SPNs:ARRAY[1..6] OF J1939_SPN; PGN_ET1:J1939_PGN; (*PGN: DM1, FECA*) DM1_ProtectLampStatus: BYTE; DM1_AmberWarningLampStatus: BYTE; DM1_RedStopLampState: BYTE; DM1_MalfunctionIndicatorLampStatus: BYTE; DM1_FlashProtectLamp: BYTE; DM1_FlashAmberWarningLamp: BYTE; DM1_FlashRedStopLamp: BYTE; DM1_FlashMalfuncIndicatorLamp: BYTE; DM1_DTC1: DWORD; DM1_DTC2: DWORD; DM1_DTC3: DWORD; DM1_DTC4: DWORD; DM1_DTC5: DWORD; PGN_DM1_SPNs:ARRAY[1..13] OF J1939_SPN; PGN_DM1:J1939_PGN; END_STRUCT END_TYPE
|
MultiTool generates a struct that contains the variables that are received from the device. These variables are raw values that you must scale if needed. MultiTool Creator generates PGN & SPN variables for received messages.
|
Application example of J1939 variable scalingApplication example of J1939 variable scaling
The following example describes how to access and scale the measurement values.
Application code example |
Description |
J1939_CAN2.In.Engine.EEC1_EngSpeed
|
Raw value for engine speed |
EngineRpm:=J1939_CAN2.In.Engine.EEC1_EngSpeed/8;
|
An example for scaling the engine RPM |
EngineHours:=DWORD_TO_WORD(J1939_CAN2.In.Engine.HOURS_EngTotalHoursOfOperation/20); |
An example for scaling the engine hours |
CoolantTemp:=BYTE_TO_SINT(J1939_CAN2.In.Engine.ET1_EngCoolantTemp)-40; |
An example for scaling the engine coolant temperature to Celsius degrees |
The following converts raw DTC signals to SPN-FMI error codes.
DM1 PGN message has 5 DTC variables by default but more DTCs can be added in MultiTool Creator.
Conversion method 4 is recommended but used method depends on J1939 device which sends the DM log. |
Definitions: |
|
DM1_SPNFMI: ARRAY [1..5] OF J1939_SPNFMI;
|
Code: |
|
IF J1939_CAN2.In.Engine.PGN_DM1.NewData THEN J1939_SPNFMI_Convert( i_SPNFMIConversionMethod := 4, i_pDTC_Data := ADR(J1939_CAN2.In.Engine.DM1_DTC1), i_NumberOfDTC := 5, i_pSPNFMI_Data := ADR(DM1_SPNFMI) ); END_IF
|
To start using J1939 (this example is configured using MultiTool 6.9):
1. In MultiTool, add a J1939 device (named "Engine" in this example) and make the needed configurations:
set the properties
add the J1939 device to a network
configure CAN bus
define the needed PGN messages
For more detailed description, refer to Epec MultiTool Creator manual.
2. MultiTool generates the initializations for J1939 to the code template and generates the following structures.
This example receives EEC1, HOURS, DM1 and ET1 PGNs.
Code template structure exampleCode template structure example
Code template example |
Description |
VAR_GLOBAL J1939_CAN2: J1939_CAN2; J1939_FB_CAN2: J1939; END_VAR
|
J1939Globals global variable list generated by MultiTool Creator in Device > Application > CodeTemplate > Globals Contains main variable for J1939 all application data. Contains function block instance for J1939. |
TYPE J1939_CAN2 : STRUCT In: J1939_CAN2_IN; Out: J1939_CAN2_OUT; END_STRUCT END_TYPE
|
MultiTool Creator generates a struct for J1939 messages:
|
TYPE J1939_CAN2_IN : STRUCT Engine : J1939_CAN2_IN_Engine; PGNs: ARRAY [1..4] OF J1939_pPGN; END_STRUCT END_TYPE
|
MultiTool Creator generates separate structs for received and transmitted messages. It also generates a table for PGN messages to be used by library. Engine contains the PGN variables that are configured in MultiTool Creator for the device in question.
|
TYPE J1939_CAN2_IN_Engine : STRUCT EEC1_EngTorqueMode: BYTE; EEC1_ActualEnginePercentTorqueHiRes: BYTE; EEC1_DriversDemandEngPercentTorque: BYTE; EEC1_ActualEngPercentTorque: BYTE; EEC1_EngSpeed: WORD; EEC1_SrcAddrssOfCtrllngDvcForEngCtrl: BYTE; EEC1_EngStarterMode: BYTE; J1939_CAN2_EEC1_Dummy_RX_1: BYTE; EEC1_EngDemandPercentTorque: BYTE; PGN_EEC1_SPNs: ARRAY[1..9] OF J1939_SPN; PGN_EEC1: J1939_PGN; HOURS_EngTotalHoursOfOperation: DWORD; HOURS_EngTotalRevolutions: DWORD; PGN_HOURS_SPNs: ARRAY[1..2] OF J1939_SPN; PGN_HOURS: J1939_PGN; ET1_EngCoolantTemp: BYTE; ET1_EngFuelTemp: BYTE; ET1_EngOilTemp1: WORD; ET1_EngTurboOilTemp: WORD; ET1_EngIntercoolerTemp: BYTE; ET1_EngIntercoolerThermostatOpening: BYTE; PGN_ET1_SPNs: ARRAY[1..6] OF J1939_SPN; PGN_ET1: J1939_PGN; DM1_ProtectLampStatus: BYTE; DM1_AmberWarningLampStatus: BYTE; DM1_RedStopLampState: BYTE; DM1_MalfunctionIndicatorLampStatus: BYTE; DM1_FlashProtectLamp: BYTE; DM1_FlashAmberWarningLamp: BYTE; DM1_FlashRedStopLamp: BYTE; DM1_FlashMalfuncIndicatorLamp: BYTE; DM1_DTC1: DWORD; DM1_DTC2: DWORD; DM1_DTC3: DWORD; DM1_DTC4: DWORD; DM1_DTC5: DWORD; PGN_DM1_SPNs: ARRAY[1..13] OF J1939_SPN; PGN_DM1: J1939_PGN; END_STRUCT END_TYPE
|
MultiTool Creator generates a struct that contains the variables that are received from the device. These variables are raw values that you must scale if needed. MultiTool Creator generates PGN & SPN variables for received messages.
|
Application example of J1939 variable scalingApplication example of J1939 variable scaling
The following example describes how to access and scale the measurement values.
Application code example |
Description |
J1939_CAN2.In.Engine.EEC1_EngSpeed
|
Raw value for engine speed |
EngineRpm:=J1939_CAN2.In.Engine.EEC1_EngSpeed/8;
|
An example for scaling the engine RPM |
EngineHours:=DWORD_TO_WORD(J1939_CAN2.In.Engine.HOURS_EngTotalHoursOfOperation/20); |
An example for scaling the engine hours |
CoolantTemp:=BYTE_TO_SINT(J1939_CAN2.In.Engine.ET1_EngCoolantTemp)-40; |
An example for scaling the engine coolant temperature to Celsius degrees |
The following converts raw DTC signals to SPN-FMI error codes.
DM1 PGN message has 5 DTC variables by default but more DTCs can be added in MultiTool Creator.
Conversion method 4 is recommended but used method depends on J1939 device which sends the DM log. |
Definitions: |
|
DM1_SPNFMI: ARRAY [1..5] OF EPEC_J1939.J1939_SPNFMI;
|
Code: |
|
IF J1939_CAN2.In.Engine.PGN_DM1.NewData THEN EPEC_J1939.J1939_SPNFMI_Convert( i_SPNFMIConversionMethod := 4, i_pDTC_Data := ADR(J1939_CAN2.In.Engine.DM1_DTC1), i_NumberOfDTC := 5, i_pSPNFMI_Data := ADR(DM1_SPNFMI) ); END_IF
|
The code template differs compared to other control units.
J1939 structures and global variable lists have been modified because of safety platform specific restrictions (see Safety project guidelines and Known issues).
Basically, the PGN and SPN variables and PGNs arrays have been moved to new global variable lists.
G_J1939_CANx_RPGN
G_J1939_CANx_TPGN
Also, the J1939 function block and application data are in separate global variable lists
G_J1939 (application data)
G_J1939_FB (function block instance)
To start using J1939 (this example is configured using MultiTool 6.9):
1. In MultiTool, add a J1939 device (named "Engine" in this example) and make the needed configurations:
set the properties
add the J1939 device to a network
configure CAN bus
define the needed PGN messages
For more detailed description, refer to Epec MultiTool Creator manual.
2. MultiTool generates the initializations for J1939 to the code template and generates the following structures.
This example adds:
Receive PGNs: EEC1, HOURS, DM1 and ET1
Transmit PGNs: TSC1
Code template exampleCode template example
Code template example |
Description |
VAR_GLOBAL CAN2: J1939_CAN2; END_VAR |
G_J1939 global variable list generated by MultiTool in Device > Application > CodeTemplate > Globals > J1939 Contains main variable for J1939 all application data. |
VAR_GLOBAL CAN2: EPEC_J1939.J1939; END_VAR |
G_J1939_FB global variable list generated by MultiTool in Device > Application > CodeTemplate > Globals > J1939 Contains function block instance for J1939. |
VAR_GLOBAL PGNs: ARRAY[1..G_J1939_CAN2_RX_PGNS] OF J1939_pPGN; Engine_EEC1_SPNs: ARRAY[1..9] OF J1939_SPN; Engine_EEC1: J1939_PGN; Engine_HOURS_SPNs: ARRAY[1..2] OF J1939_SPN; Engine_HOURS: J1939_PGN; Engine_ET1_SPNs: ARRAY[1..6] OF J1939_SPN; Engine_ET1: J1939_PGN; Engine_DM1_SPNs: ARRAY[1..13] OF J1939_SPN; Engine_DM1: J1939_PGN; END_VAR |
G_J1939_CAN2_RPGN global variable list generated by MultiTool in Device > Application > CodeTemplate > Globals > J1939
MultiTool generates PGN & SPN variables for received messages. It also generates a table for PGN messages to be used by library. |
VAR_GLOBAL PGNs: ARRAY[1..G_J1939_CAN2_TX_PGNS] OF J1939_pPGN; Engine_TSC1_SPNs: ARRAY[1..9] OF J1939_SPN; Engine_TSC1: J1939_PGN; END_VAR |
G_J1939_CAN2_TPGN global variable list generated by MultiTool in Device > Application > CodeTemplate > Globals > J1939
MultiTool generates PGN & SPN variables for transmitted messages. It also generates a table for PGN messages to be used by library. |
TYPE J1939_CAN2 : STRUCT In: J1939_CAN2_IN; Out: J1939_CAN2_OUT; END_STRUCT END_TYPE
|
MultiTool generates a struct for J1939 message's application data:
|
TYPE J1939_CAN2_IN : STRUCT Engine: J1939_CAN2_IN_Engine; END_STRUCT END_TYPE
|
MultiTool generates struct for received data. Engine contains the application variables that are configured in MultiTool Creator for the device in question.
|
TYPE J1939_CAN2_IN_Engine : STRUCT EEC1_EngTorqueMode: BYTE; EEC1_ActualEnginePercentTorqueHiRes: BYTE; EEC1_DriversDemandEngPercentTorque: BYTE; EEC1_ActualEngPercentTorque: BYTE; EEC1_EngSpeed: WORD; EEC1_SrcAddrssOfCtrllngDvcForEngCtrl: BYTE; EEC1_EngStarterMode: BYTE; EEC1_Dummy_RX_1: BYTE; EEC1_EngDemandPercentTorque: BYTE; HOURS_EngTotalHoursOfOperation: DWORD; HOURS_EngTotalRevolutions: DWORD; ET1_EngCoolantTemp: BYTE; ET1_EngFuelTemp: BYTE; ET1_EngOilTemp1: WORD; ET1_EngTurboOilTemp: WORD; ET1_EngIntercoolerTemp: BYTE; ET1_EngIntercoolerThermostatOpening: BYTE; DM1_ProtectLampStatus: BYTE; DM1_AmberWarningLampStatus: BYTE; DM1_RedStopLampState: BYTE; DM1_MalfunctionIndicatorLampStatus: BYTE; DM1_FlashProtectLamp: BYTE; DM1_FlashAmberWarningLamp: BYTE; DM1_FlashRedStopLamp: BYTE; DM1_FlashMalfuncIndicatorLamp: BYTE; DM1_DTC1: DWORD; DM1_DTC2: DWORD; DM1_DTC3: DWORD; DM1_DTC4: DWORD; DM1_DTC5: DWORD; END_STRUCT END_TYPE |
MultiTool generates a struct that contains the application variables that are received from the device. These variables are raw values that you must scale if needed. |
TYPE J1939_CAN2_OUT : STRUCT Engine: J1939_CAN2_OUT_Engine; END_STRUCT END_TYPE |
MultiTool generates struct for transmitted data. Engine contains the application variables that are configured in MultiTool for the device in question. |
TYPE J1939_CAN2_OUT_Engine : STRUCT TSC1_EngOverrideCtrlMode: BYTE; TSC1_EngRqedSpeedCtrlConditions: BYTE; TSC1_OverrideCtrlModePriority: BYTE; TSC1_Dummy_TX_1: BYTE; TSC1_EngRqedSpeed_SpeedLimit: WORD; TSC1_EngRqedTorque_TorqueLimit: BYTE; TSC1_TransmissionRate: BYTE; TSC1_ControlPurpose: BYTE; TSC1_EngineRequestedTorqueHiRes: BYTE; END_STRUCT END_TYPE |
MultiTool generates a struct that contains the application variables that are transmitted to the device. These variables are raw values that you must scale if needed. |
Application example of J1939 variable scalingApplication example of J1939 variable scaling
Application code example |
Description |
G_J1939.CAN2.In.Engine.EEC1_EngSpeed
|
Raw value for engine speed |
EngineRpm := G_J1939.CAN2.In.Engine.EEC1_EngSpeed/WORD#8; |
An example for scaling the engine RPM |
EngineHours := DWORD_TO_WORD(G_J1939.CAN2.In.Engine.HOURS_EngTotalHoursOfOperation/DWORD#20); |
An example for scaling the engine hours |
CoolantTemp := BYTE_TO_SINT(G_J1939.CAN2.In.Engine.ET1_EngCoolantTemp)-SINT#40; |
An example for scaling the engine coolant temperature to Celsius degrees |
G_J1939.CAN2.Out.Engine.TSC1_EngRqedSpeed_SpeedLimit := RequiredRpm * WORD#8; |
An example of setting engine's requested rpm to transmit message. |
IF G_J1939_CAN2_RPGN.Engine_EEC1.Status = EPEC_J1939.J1939_PGNStatus.J1939_PGN_Timeout THEN ;(*do something*) END_IF |
An example of accessing the PGN variable to check message's status |
The following converts raw DTC signals to SPN-FMI error codes.
DM1 PGN message has 5 DTC variables by default but more DTCs can be added in MultiTool Creator.
Conversion method 4 is recommended but used method depends on J1939 device which sends the DM log. |
Definitions: |
|
DM1_SPNFMI: ARRAY [1..5] OF EPEC_J1939.J1939_SPNFMI;
|
Code: |
|
IF G_J1939_CAN2_RPGN.Engine_DM1.NewData THEN EPEC_J1939.J1939_SPNFMI_Convert( i_SPNFMIConversionMethod := 4, i_pDTC_Data := ADR(G_J1939.CAN2.In.Engine.DM1_DTC1), i_NumberOfDTC := 5, i_pSPNFMI_Data := ADR(DM1_SPNFMI) ); END_IF
|
Epec MultiTool Creator manual (available in Epec extranet)
Training material for frame unit (available in Epec extranet)
Source file topic100326.htm
Last updated 19-Dec-2024