canFMSGetPGN (Function)

Top  Previous  Next

Architecture:

X32 / NX32 / NX32L

Firmware version:

2.60 / 1.00.00


This function can be used to extract the FMS/J1939 PGN from a CAN message received with canReceiveMessage.

To create a CAN filter from a PGN, please see canFMSFilterCreate.

 

 

Input:

Id   : DINT (16#0...16#FFFFFFFF) (Default 0)

The CAN message ID to extract PGN from.

 

 

Returns: DINT

>0

- The extracted PGN.

 

Declaration:

FUNCTION canFMSGetPGN : DINT;
VAR_INPUT
   Id    : DINT := 0;
END_VAR;

 

 

Example:

INCLUDE rtcu.inc
 
VAR
   can   : canReceiveMessage;
   buf   : ARRAY[1..8] OF SINT;
END_VAR;
 
FUNCTION_BLOCK ParseCruiseControl;
VAR_INPUT
   data   : PTR;
END_VAR;
VAR_OUTPUT
   speed  : DINT;      // Wheel based speed (SPN84)
   clutch : BOOL;      // Clutch switch (SPN 598), TRUE=pressed, FALSE=released
   break  : BOOL;      // Break switch (SPN 597), TRUE=pressed, FALSE=released
   cruise : BOOL;      // Cruise control active (SPN 595), TRUE=switched on, FALSE=switched off
   val    : SINT;      // Unknown data in byte 7. (SPN 976)
END_VAR;
VAR
   can    : ARRAY [1..8] OF SINT;
   temp   : SINT;
   high   : DINT;
END_VAR;
   // Copy CAN data to local buffer
   memcpy(dst := ADDR(can), src := data, len := 8);
 
   // Extract Wheel based speed.
   speed := shl32(in := can[2], n := 8) + can[3];
 
   // Extract Clutch switch
   IF shr8(in := can[4], n := 6) = 1 THEN
      clutch := TRUE;
   ELSE
      clutch := FALSE;
   END_IF;
 
   // Extract Break switch
   temp := shr8(in := can[4], n := 4) AND 16#03;
   IF temp = 1 THEN
      break := TRUE;
   ELSE
      break := FALSE;
   END_IF;
 
   // Extract Cruise control active
   IF (can[4] AND 16#03) = 1 THEN
      cruise := TRUE;
   ELSE
      cruise := FALSE;
   END_IF;
 
   // Extract Unknown data
   val := can[7] AND 16#1F;
END_FUNCTION_BLOCK;
 
FUNCTION ParseEngineSpeed : DINT;
VAR_INPUT
   data : PTR;
END_VAR;
VAR
   can  : ARRAY [1..8] OF SINT;
   tick : DINT;      // Engine speed (SPN190)
END_VAR;
   // Copy CAN data to local buffer
   memcpy(dst := ADDR(can), src := data, len := 8);
 
   // Extract engine speed
   tick             := shl32(in := can[4], n := 8) + can[5];
   ParseEngineSpeed := tick * 125/1000; // Convert from ticks to RPM's
END_FUNCTION;
 
PROGRAM example;
VAR
   PGN  : DINT;
   CCVS : ParseCruiseControl;
END_VAR;
 
   // Initializing
   canOpen(baud := 250);
   can.data := ADDR(buf);
   canFMSFilterCreate(PGN := 65265);
   canFMSFilterCreate(PGN := 61444);
 
BEGIN
   can();
   IF can.ready THEN
      PGN := canFMSGetPGN(id := can.id);
      IF PGN = 65265 THEN
         CCVS(data := ADDR(buf));
         DebugFmt(message := "speed= \4", v4 := CCVS.speed);
         DebugFmt(message := "clutch= \1", v1 := INT(CCVS.clutch));
         DebugFmt(message := "break= \1", v1 := INT(CCVS.break));
         DebugFmt(message := "cruise= \1", v1 := INT(CCVS.cruise));
         DebugFmt(message := "unknown= \1", v1 := CCVS.val);
      ELSIF PGN = 61444 THEN
         DebugFmt(message := "rpm= \4", v4 := ParseEngineSpeed(data := ADDR(buf)));
      END_IF;
   END_IF;
END;
 
END_PROGRAM;