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