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.
One channel will transmit messages the other. Filters are set on the receiving channel.
txCh = canChannel('MathWorks', 'Virtual 1', 1); rxCh = canChannel('MathWorks', 'Virtual 1', 2);
These messages are sent to the receiving channel multiple times throughout the example. Note that one of the messages 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);
Set the channels online, transmit the messages, and receive them. Note that all messages sent were received. The filter settings on a newly created channel are fully open for both standard and extended identifiers.
start(rxCh); start(txCh); transmit(txCh, txMsgs); pause(0.5); rxMsgs1 = receive(rxCh, Inf, 'OutputFormat', 'timetable') stop(rxCh); stop(txCh);
rxMsgs1 = 5x8 timetable Time ID Extended Name Data Length Signals Error Remote _____________ ____ ________ __________ ___________________ ______ ____________ _____ ______ 0.0091838 sec 250 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0091875 sec 500 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0091922 sec 1000 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0091959 sec 1500 true {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0091991 sec 2000 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false
Plot the identifiers of the received messages to see that all messages sent were 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')
Use the filterAllowOnly
command to specify messages to receive by CAN identifier and identifier type.
filterAllowOnly(rxCh, [500 2000], 'Standard');
Display the channel to view the configured state of the message filters.
rxCh
rxCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 5 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-Feb-2021 17:16:16 FilterHistory: 'Standard ID Filter: Allow Only | 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: []
Transmit the messages again to the receiving channel. Note that fewer messages were received this time.
start(rxCh); start(txCh); transmit(txCh, txMsgs); pause(0.5); rxMsgs2 = receive(rxCh, Inf, 'OutputFormat', 'timetable') stop(rxCh); stop(txCh);
rxMsgs2 = 3x8 timetable Time ID Extended Name Data Length Signals Error Remote _____________ ____ ________ __________ ___________________ ______ ____________ _____ ______ 0.0057236 sec 500 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0057319 sec 1500 true {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0057391 sec 2000 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false
Add the new receive data to the plot to see which messages are blocked by the filter. The message with the extended identifier was numerically supposed to be blocked, but it passed 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')
You can reset the message filters to their default open state with the filterAllowAll
command.
filterAllowAll(rxCh, 'Standard');
Display the channel to view the configured state of the message filters.
rxCh
rxCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 3 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-Feb-2021 17:16:18 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: []
Transmit and receive a third time to see that all messages are once again passing through the filter and into the channel.
start(rxCh); start(txCh); transmit(txCh, txMsgs); pause(0.5); rxMsgs3 = receive(rxCh, Inf, 'OutputFormat', 'timetable') stop(rxCh); stop(txCh);
rxMsgs3 = 5x8 timetable Time ID Extended Name Data Length Signals Error Remote _____________ ____ ________ __________ ___________________ ______ ____________ _____ ______ 0.0082374 sec 250 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.00824 sec 500 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0082424 sec 1000 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0082445 sec 1500 true {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false 0.0082466 sec 2000 false {0x0 char} {[0 0 0 0 0 0 0 0]} 8 {0x0 struct} false false
With the new data added to the plot, observe that the first and third transmits are identical as the message filters were 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')
The filterAllowOnly
command can also reference messages by name when using a CAN database file.
db = canDatabase('demoVNT_CANdbFiles.dbc'); rxCh.Database = db; filterAllowOnly(rxCh, 'EngineMsg'); rxCh
rxCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 5 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-Feb-2021 17:16:19 FilterHistory: 'Standard ID Filter: Allow Only | 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: [1x1 can.Database] UserData: []
The filterBlockAll
command lets you quickly set the filter to block all messages of either standard or extended identifier type.
filterBlockAll(rxCh, 'Extended');
rxCh
rxCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 5 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-Feb-2021 17:16:19 FilterHistory: 'Standard ID Filter: Allow Only | Extended ID Filter: Block 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: [1x1 can.Database] UserData: []