canFilterCreateX (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.50 (2.62 : changed filtering) / 1.00.00


This will create a receive filter similar to canFilterCreate, except that it offers some advanced filtering options on top of the simple ID filtering.

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.

 

Grouping: (only supported on NX32/NX32L, requires firmware V5.04 / R1.31.00 or newer)

A group is a sequence of CAN messages with the same identifier, but with differing data contents.

By defining a group, the advanced filter options below can be applied on the group as a whole, instead of each individual message.

Because a group contains multiple messages with the same identifier, the 'Contents changed filtering' cannot be used with a group.

The start of the group is determined by applying a bit mask to the data contents of a received message, and then comparing it with a data sequence.

Once a message with a matching data content is received, it and the next messages will be accepted (the number of messages are configured in the group parameter).

The start data sequence is 8 bytes, which is configured using the change_hi_mask parameter, and the start bit mask is 8 bytes which is configured using the change_lo_mask.

 

For example, if a group of messages have the following content:

Message: 01 00 A0 2A 1B 04 78 05

Message: 02 58 30 1B 04 00 00 00

Message: 03 00 AA 2A 1A 04 78 05

Message: 04 4C 30 1A 04 00 00 00

 

The start data sequence would be:

Start: 01 00 00 00 00 00 00 00

 

And the bit mask would be:

Mask: FF 00 00 00 00 00 00 00

 

Time_interval filtering: (only supported on NX32/NX32L, requires firmware V5.04 / R1.31.00 or newer)

When you have a message that needs to be read at a regular interval, whether the contents change or not, then this filter option is the one to use.

This option will set a time interval in which incoming messages are ignored.

For example, if time_interval is set to 5000, then for the first 5 seconds all incoming messages are ignored, the next incoming message is then accepted, and for the next 5 seconds all incoming messages are ignored. This repeats until the filter is destroyed.

Both the timeout and time_interval options cannot be enabled simultaneously.

The time_interval is the first advanced filtering done.

 

Downsampling:

When you have a message that is sent far too often, and where the contents are changing too regularly, then this filter option is the one to use.

This option will count the incoming messages, and the messages will be ignored until the counter reaches the selected number.

For example, if downsample is set to 3, then the 1st and 2nd incoming messages are ignored and the 3rd is received, the 4th and 5th are ignored and the 6th is received - this repeats until the filter is destroyed.

Downsampling is done after the time_interval filtering, but before any other advanced filtering.

 

Contents changed filtering:

This option will compare an incoming message with the last received message, and if they are identical, then the incoming message is ignored.

The last received message is stored for the whole filter - not the individual IDs. As such, the option will not work as expected in a filter with a length higher than 1.

The two bit masks, change_hi_mask and change_lo_mask, allow for a fine grained-control of the comparison between the message data of the incoming message and the last message.

The change_hi_mask controls which parts of the message data, down to the individual bits, that are ignored in a comparison where they change from low state to high state.

Like the change_hi_mask, the change_lo_mask controls which parts of the message data are ignored in the comparison - except for changes from high state to low state.

Each mask is an array of 8 bytes, where each byte is used to determine which bits of the corresponding message data byte will be ignored during the comparison (byte 1 in mask is used to filter byte 1 in data).

 

Timeout filtering:

If all the incoming messages have been filtered away in the timeout period, then the next incoming message will bypass the advanced filtering and be received.

 

Message limit filtering:

This option will automatically disable the filter after a number of messages are received. This is a similar behaviour to the canFilterCreateOnce function - except that it is not limited to only one message.

If a limit is selected for the filter, it is recommended to check if a filter is still active (the limit of valid messages received is not reached) before creating it again.

When using more than one filter with limits, it is mandatory to destroy the filter with canFilterDestroy before creating the filter again. If only one limited filter is used, destroying the filter is optional.

 

Destination filtering:

This filter option allows for logging CAN messages without having to handle them in the application, and to handle CAN messages in the application without logging them.

 

 

Input:

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

The port of the CAN bus.

 

xtd : BOOL

Filter for standard or extended identifiers. Set to TRUE for extended identifiers.

 

startID : DINT (16#0...16#1FFF_FFFF)

The first identifier that is accepted.

 

length : DINT (16#1...16#2000_0000)

The length of the range of identifiers that are accepted. For a single identifier, the length should only be set to 1.

 

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 is used when checked for low state to high state differences.

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

Note: the bit mask must be exactly 8 bytes long.

 

change_lo_mask : PTR

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

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

Note: the bit mask must be exactly 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).

 

group : SINT (0,2...127, default 0) (only supported on NX32/NX32L, requires firmware V5.04 / R1.31.00 or newer)

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

The group is disabled 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).

 

time_interval : INT (0,100...32767, default 0) (only supported on NX32/NX32L, requires firmware V5.04 / R1.31.00 or newer)

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 start ID.

-2

- Illegal length.

-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 group and changed is enabled.

-12

- Illegal time_interval.

-13

- Both time_interval and timeout is enabled.

 

Declaration:

FUNCTION canFilterCreateX : SINT;
VAR_INPUT
  port           : SINT := 1;
  xtd           : BOOL;
  startid       : DINT;
  length         : 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
  canRX : canReceiveMessage;
  buf   : ARRAY[1..8] OF SINT;
END_VAR;
 
PROGRAM CANExample;
VAR
  FilterID : ARRAY[1..4] OF SINT;
  timer     : TON;
  mask_hi   : ARRAY [1..8] OF SINT;
  mask_lo   : ARRAY [1..8] OF SINT;
END_VAR;
 
// Open can
canOpen(baud := 250);
canRX(data := ADDR(buf));
 
// Open filters
timer.pt := 1000;
FilterID[1] := canFilterCreateX(xtd := TRUE, startID := 16#0EFDD600, length := 6);
 
// Define High mask
mask_hi[1] := 16#C0;
mask_hi[2] := 16#00;
mask_hi[3] := 16#00;
mask_hi[4] := 16#03;
mask_hi[5] := 16#00;
mask_hi[6] := 16#00;
mask_hi[7] := 16#00;
mask_hi[8] := 16#00;
 
// Define Low mask
mask_lo[1] := 16#C0;
mask_lo[2] := 16#00;
mask_lo[3] := 16#00;
mask_lo[4] := 16#00;
mask_lo[5] := 16#00;
mask_lo[6] := 16#00;
mask_lo[7] := 16#00;
mask_lo[8] := 16#00;
 
FilterID[4] := canFilterCreateX(xtd := TRUE, startID := 16#0EFDD700, length := 1,
                              changed := TRUE,
                               change_hi_mask := ADDR(mask_hi),
                               change_lo_mask := ADDR(mask_lo));
 
BEGIN
  ...
  canRX();
  IF canRX.ready THEN
    DebugMsg(message := "Message received!");
    DebugFmt(message := "canRX.xtd= \1", v1 := INT(canRX.xtd));
    DebugFmt(message := "canRX.ID= \4", v4 := canRX.ID);
    DebugFmt(message := "canRX.DataSize= \1", v1 := INT(canRX.DataSize));
  END_IF;
  ...
  timer(trig := TRUE);
  IF timer.q THEN
    IF canFilterStatus(filterid := FilterID[2]) <> 1 THEN
        canFilterDestroy(filterid := FilterID[2]);
        FilterID[2] := canFilterCreateX(xtd := TRUE, startID := 16#0E00FDD3, length := 1, limit := 10);
    END_IF;
    IF canFilterStatus(filterid := FilterID[3]) <> 1 THEN
        canFilterDestroy(filterid := FilterID[3]);
        FilterID[3] := canFilterCreateX(xtd := TRUE, startID := 16#0E00FDD4, length := 1, limit := 10);
    END_IF;
     timer(trig := FALSE);
  END_IF;
  ...
END;
 
END_PROGRAM;