canFMSFilterCreate (Function)

Top  Previous  Next

Architecture:

X32 / NX32 / NX32L

Device support:

MX2 pro, DX4 pro, CX1 pro-c/warp-c, MX2 turbo/encore/warp, NX-200, NX-400, LX2, LX5

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;