canFMSFilterCreate (Function)

Top  Previous  Next

Architecture:

X32 / NX32 / NX32L

Firmware version:

2.60 / 1.00.00


This creates a receive filter similar to canFilterCreateX, except that the filter will be for a single FMS/J1939 message.

When a filter has been successfully created, the function returns an ID for the filter.

This ID can be used to check the status of the filter with canFilterStatus.

 

Please see the canFilterCreate function for more information on working with receive filters and canFilterCreateX for more information on the advanced filter options.

 

The J1939 standard is a vehicle bus standard used for communication and diagnostics among vehicle components.

The FMS (Fleet Management System interface) is a subset of the J1939 standard and is defined as a standard interface to vehicle data of commercial vehicles.

All FMS/J1939 messages contain 8 bytes of data and a standard header containing an index called PGN (Parameter Group Number) which is embedded in the CAN message's 29-bit identifier (extended identifier).

(The full definition of the header is: <priority:3 bit><reserve:1 bit><PGN:17 bit><source address:8 bit>)

 

 

Input:

port : SINT (1/2) (default 1)

The port of the CAN bus.

 

PGN : DINT (16#0...16#1_FFFF)

The PGN number of the FMS/J1939 message.

 

downsample : SINT (1..127, Default 1)

Only accepts each x incoming message - thus allowing logging for a longer period.

 

changed : BOOL

TRUE

- Only accepts an incoming message if contents are different from the last received message.

FALSE

- All incoming messages are accepted.

 

change_hi_mask : PTR

Address of a bit mask that is used to determine which parts of the message data are used when checking for low state to high state differences.

If change_hi_mask is not used, all parts of the message data are used. This parameter is ignored if changed is FALSE.

Note: the bit mask must be 8 bytes long.

 

change_lo_mask : PTR

Address of a bit mask that is used to determine which parts of the message data are used when checking for high state to low state differences.

If change_lo_mask is not used, all parts of the message data are used. This parameter is ignored if changed is FALSE.

Note: the bit mask must be 8 bytes long.

 

destination : SINT (1...3, default 3)

1

- The received messages are forwarded to the application.

2

- The received messages are forwarded to the logger.

3

- The received messages are forwarded to both the application and the logger.

 

limit : SINT (0...127)

The number of received messages before the filter is disabled. There is no limit if set to 0 (zero).

 

timeout : SINT (0...127)

The number of seconds without receiving a message before the next incoming message is automatically accepted.

The timeout is disabled if set to 0 (zero).

 

group : SINT (0,2...127, default 0) (only supported from on NX32/NX32L firmware V5.04 / 1.31.00)

The number of messages in sequence that are part of the group.

The group is disabled if set to 0 (zero).

 

time_interval : INT (0,100...32767, default 0) (only supported from on NX32/NX32L firmware V5.04 / 1.31.00)

The number of milliseconds after receiving a message, where incoming messages are ignored.

The time_interval is disabled if set to 0 (zero).

 

 

Returns: SINT

>0

- ID of the new filter.

-1

- Illegal PGN.

-3

- No free filters.

-4

- Illegal downsample.

-5

- Illegal limit.

-6

- Illegal timeout.

-7

- Illegal destination.

-8

- The CAN bus is not open.

-10

- Illegal group.

-11

- Both the group and change is enabled.

-12

- Illegal time_interval.

-13

- Both the time_interval and timeout is enabled.

 

Declaration:

FUNCTION canFMSFilterCreate : SINT;
VAR_INPUT
   port           : SINT := 1;
   PGN            : DINT;
   downsample     : SINT := 1;
   changed        : BOOL;
   destination    : SINT := 3;
   limit          : SINT;
   timeout        : SINT;
   group          : SINT := 0;
   time_interval  : INT  := 0;
   change_hi_mask : PTR;
   change_lo_mask : PTR;
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;