Supported platforms: CODESYS 3.5
This section describes how to define J1939 messages to be send with a fixed interval.
The CAN-message sending is independent of the application cycle (see also limitations below).
This example uses MultiTool Creator generated PGNs, but it is also possible to define PGNs manually.
|
Some engines require a certain message interval for TSC1 message. In some cases the software cycle time affects so that the TSC1 message is not sent in the correct time frame. In this case, the engine may not respond to the RPM (rounds per minute) request. In this case, use the interrupt functionality described here. The interrupt functionality sends the TSC1 message in the correct time frame regardless of the software cycle time.
|
|
Required:
|
|
Limitations:
|
|
Example uses MultiTool Creator and code template so CAN channel is automatically initialized. |
1. Open MultiTool Creator, create 5050 C3.5 control unit and add Transmit PGN. This example uses TSC1 which is sent to engine in address 0.
2. Create CODESYS 3.5 project
Definitions: |
|
bInit: BOOL := TRUE; tsc1CanApiHandler: EPEC_5050INT.CanApiTimeTriggeredMsg; usedCobId: DWORD;
|
Code: |
|
IF bInit THEN bInit := FALSE; (* Set TSC1 PGN *) (* Time triggered CAN message supports only data length <= 8 *) IF J1939_CAN2.Out.Engine.PGN_TSC1.DataLength <= 8 THEN (* Set cycle time to 0ms to prevent message sending by J1939 server *) J1939_CAN2.Out.Engine.PGN_TSC1.CycleTime := 0; (* Set data length *) tsc1CanApiHandler.i_Dlc := WORD_TO_BYTE(J1939_CAN2.Out.Engine.PGN_TSC1.DataLength);
(* Set init data for message *) EPEC_J1939.J1939_BuildPGN( i_pBasePGN := ADR(J1939_CAN2.Out.Engine.PGN_TSC1), i_pDataBuffer := ADR(tsc1CanApiHandler.i_Data) );
(* Init cobid for time triggered message *) (* build used cobid from PGN *) usedCobId:=BYTE_TO_DWORD(J1939_CAN2.Out.Engine.PGN_TSC1.Priority); usedCobId:=SHL(usedCobId,1) OR 0; usedCobId:=SHL(usedCobId,1) OR BYTE_TO_DWORD(J1939_CAN2.Out.Engine.PGN_TSC1.DataPage); usedCobId:=SHL(usedCobId,8) OR WORD_TO_DWORD(SHR(J1939_CAN2.Out.Engine.PGN_TSC1.PGN_Number,8) AND 16#FF);
IF 16#F000 > J1939_CAN2.Out.Engine.PGN_TSC1.PGN_Number THEN usedCobId:=SHL(usedCobId,8) OR BYTE_TO_DWORD(J1939_CAN2.Out.Engine.PGN_TSC1.Destination); ELSE usedCobId:=SHL(usedCobId,8) OR WORD_TO_DWORD(J1939_CAN2.Out.Engine.PGN_TSC1.PGN_Number AND 16#FF); END_IF
usedCobId := SHL(usedCobId,8) OR BYTE_TO_DWORD(J1939_CAN2.Out.Engine.PGN_TSC1.SourceAddress); usedCobId := usedCobId OR EPEC_CANVXD.MASK_29BIT; (* Set bit on which defines message as 29bit *)
(* Init time triggered message *) tsc1CanApiHandler.InitCobId( i_CanChannel := 1, (*CAN2*) i_CobId := usedCobId, i_TimeInterval := T#10MS );
tsc1CanApiHandler.i_Enable := TRUE; END_IF ELSE (* J1939 variables are accessed normally through J1939 structure*) J1939_CAN2.Out.Engine.TSC1_EngRqedSpeed_SpeedLimit := WORD#1000 * 8; (*1000 rpm to raw value*)
(* Update PGN data to Api handler input*) EPEC_J1939.J1939_BuildPGN( i_pBasePGN := ADR(J1939_CAN2.Out.Engine.PGN_TSC1), i_pDataBuffer := ADR(tsc1CanApiHandler.i_Data) );
(* Function block instance must be called at least with 100ms interval *) tsc1CanApiHandler(); END_IF
|
Source file topic000985.htm
Last updated 21-Feb-2025