Main Content

Use Message Filters in CAN Communication

This example shows you how to use CAN message filters to allow only messages that contain specified identifiers to pass through a channel. It uses MathWorks® virtual CAN channels connected in a loopback configuration. This example describes the workflow for a CAN network, but the concept demonstrated also applies to a CAN FD network.

Create Transmitting and Receiving Channels

Create one channel for transmitting messages and another channel for receiving. Filters are set later on the receiving channel.

txCh = canChannel("MathWorks", "Virtual 1", 1)
txCh = 
  Channel with properties:

   Device Information
            DeviceVendor: 'MathWorks'
                  Device: 'Virtual 1'
      DeviceChannelIndex: 1
      DeviceSerialNumber: 0
            ProtocolMode: 'CAN'

   Status Information
                 Running: 0
       MessagesAvailable: 0
        MessagesReceived: 0
     MessagesTransmitted: 0
    InitializationAccess: 1
        InitialTimestamp: [0×0 datetime]
           FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

   Channel Information
               BusStatus: 'N/A'
              SilentMode: 0
         TransceiverName: 'N/A'
        TransceiverState: 'N/A'
       ReceiveErrorCount: 0
      TransmitErrorCount: 0
                BusSpeed: 500000
                     SJW: []
                   TSEG1: []
                   TSEG2: []
            NumOfSamples: []

   Other Information
                Database: []
                UserData: []

rxCh = canChannel("MathWorks", "Virtual 1", 2)
rxCh = 
  Channel with properties:

   Device Information
            DeviceVendor: 'MathWorks'
                  Device: 'Virtual 1'
      DeviceChannelIndex: 2
      DeviceSerialNumber: 0
            ProtocolMode: 'CAN'

   Status Information
                 Running: 0
       MessagesAvailable: 0
        MessagesReceived: 0
     MessagesTransmitted: 0
    InitializationAccess: 1
        InitialTimestamp: [0×0 datetime]
           FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

   Channel Information
               BusStatus: 'N/A'
              SilentMode: 0
         TransceiverName: 'N/A'
        TransceiverState: 'N/A'
       ReceiveErrorCount: 0
      TransmitErrorCount: 0
                BusSpeed: 500000
                     SJW: []
                   TSEG1: []
                   TSEG2: []
            NumOfSamples: []

   Other Information
                Database: []
                UserData: []

Create Messages

Create a few messages to be sent to the receiving channel multiple times throughout the example. Note that one message has an extended identifier.

txMsgs(1) = canMessage(250, false, 8);
txMsgs(2) = canMessage(500, false, 8);
txMsgs(3) = canMessage(1000, false, 8);
txMsgs(4) = canMessage(1500, true, 8);
txMsgs(5) = canMessage(2000, false, 8);

Receive Messages with No Filter

Set the channels online, transmit the messages on one channel, and receive on the other. Note that all messages sent are received. By default, a newly created channel with no filter configured receives all standard and extended identifiers.

start(rxCh);
start(txCh);
transmit(txCh, txMsgs);
pause(0.5);
rxMsgs1 = receive(rxCh, Inf, "OutputFormat", "timetable")
rxMsgs1=5×8 timetable
        Time         ID     Extended       Name              Data            Length      Signals       Error    Remote
    ____________    ____    ________    __________    ___________________    ______    ____________    _____    ______

    0.038957 sec     250     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.038959 sec     500     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.038961 sec    1000     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.038963 sec    1500     true       {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.038964 sec    2000     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 

Stop both receiving and transmitting channels.

stop(rxCh);
stop(txCh);

Plot identifiers of the received messages to see that all messages sent are received by the channel.

plot(1, rxMsgs1.ID, "x")
h_gca = gca;
h_gca.XTick = 0:1:2;
h_gca.XTickLabel = ["", "Transmit 1", ""];
axis([0 2 0 2047])
xlabel("Message Transmits")
ylabel("CAN Identifiers")

Receive Messages with Filters Configured by Identifier

Use the filterAllowOnly command to allow only specified messages by CAN identifier and identifier type. Configure the receiving channel to only receive messages with standard identifiers 500 and 2000.

filterAllowOnly(rxCh, [500 2000], "Standard");

Display the FilterHistory property of the channel to view the configured state of the message filters.

rxCh.FilterHistory
ans = 
'Standard ID Filter: Allow Only | Extended ID Filter: Allow All'

Transmit the messages again to the receiving channel. Note that fewer messages are received this time.

start(rxCh);
start(txCh);
transmit(txCh, txMsgs);
pause(0.5);
rxMsgs2 = receive(rxCh, Inf, "OutputFormat", "timetable")
rxMsgs2=3×8 timetable
        Time         ID     Extended       Name              Data            Length      Signals       Error    Remote
    ____________    ____    ________    __________    ___________________    ______    ____________    _____    ______

    0.037472 sec     500     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037473 sec    1500     true       {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037474 sec    2000     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 

Stop both receiving and transmitting channels.

stop(rxCh);
stop(txCh);

Add the newly received data to the plot to see which messages passed the filters. The message with extended identifier 1500 is not blocked by the filter because the filter was only configured for standard identifiers.

plot(1, rxMsgs1.ID, "x", 2, rxMsgs2.ID, "x");
h_gca = gca;
h_gca.XTick = 0:1:3;
h_gca.XTickLabel = ["", "Transmit 1", "Transmit 2", ""];
axis([0 3 0 2047])
xlabel("Message Transmits")
ylabel("CAN Identifiers")

Reset the Message Filters

Reset the message filters to the default states with the filterAllowAll command so that all standard identifiers are allowed.

filterAllowAll(rxCh, "Standard");

Display the FilterHistory property of the channel to view the configured state of the message filters.

rxCh.FilterHistory
ans = 
'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

Transmit and receive for a third time to see that all messages are once again passing through the filters and received by the receiving channel.

start(rxCh);
start(txCh);
transmit(txCh, txMsgs);
pause(0.5);
rxMsgs3 = receive(rxCh, Inf, "OutputFormat", "timetable")
rxMsgs3=5×8 timetable
        Time         ID     Extended       Name              Data            Length      Signals       Error    Remote
    ____________    ____    ________    __________    ___________________    ______    ____________    _____    ______

    0.037884 sec     250     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037885 sec     500     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037885 sec    1000     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037888 sec    1500     true       {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 
    0.037888 sec    2000     false      {0×0 char}    {[0 0 0 0 0 0 0 0]}      8       {0×0 struct}    false    false 

Stop both receiving and transmitting channels.

stop(rxCh);
stop(txCh);

With the new data added to the plot, observe that the first and third transmits are identical as the message filters are fully open in both cases.

plot(1, rxMsgs1.ID, "x", 2, rxMsgs2.ID, "x", 3, rxMsgs3.ID, "x")
h_gca = gca;
h_gca.XTick = 0:1:4;
h_gca.XTickLabel = ["", "Transmit 1", "Transmit 2", "Transmit 3", ""];
axis([0 4 0 2047])
xlabel("Message Transmits")
ylabel("CAN Identifiers")

Receive Messages with Filters Configured by Name

The filterAllowOnly command can also filter messages by name when using a DBC file. Allow only messages with name EngineMsg.

db = canDatabase("demoVNT_CANdbFiles.dbc");
rxCh.Database = db;
filterAllowOnly(rxCh, "EngineMsg");
rxCh.FilterHistory
ans = 
'Standard ID Filter: Allow Only | Extended ID Filter: Allow All'

Block All Messages of a Specific Identifier Type

The filterBlockAll command allows you to easily set the filters to block all messages of either standard or extended identifier type. Block all messages with extended identifiers.

filterBlockAll(rxCh, "Extended");
rxCh.FilterHistory
ans = 
'Standard ID Filter: Allow Only | Extended ID Filter: Block All'

Stop the Channels

Stop both receiving and transmitting channels and clear them from the workspace.

stop(rxCh);
stop(txCh);
clear rxCh txCh

Close the DBC File

Close access to the DBC file by clearing its variable from the workspace.

clear db