Transmit and Receive CAN Messages
Discover Installed Hardware
In the example, you discover your system CAN devices with canChannelList
,
then create two CAN channels using canChannel
. Later, you edit the properties of the first channel and create a
message using canMessage
, then transmit the message from the
first channel using transmit
, and receive it on the other channel
using receive
.
Get information about the CAN hardware devices on your system.
info = canChannelList
info = 14×6 table Vendor Device Channel DeviceModel ProtocolMode SerialNumber _____________ _______________________ _______ _____________________ _____________ ____________ "MathWorks" "Virtual 1" 1 "Virtual" "CAN, CAN FD" "0" "MathWorks" "Virtual 1" 2 "Virtual" "CAN, CAN FD" "0" "Vector" "VN1610 1" 1 "VN1610" "CAN, CAN FD" "18959" "Vector" "VN1610 1" 2 "VN1610" "CAN, CAN FD" "18959" "Vector" "Virtual 1" 1 "Virtual" "CAN, CAN FD" "0" "Vector" "Virtual 1" 2 "Virtual" "CAN, CAN FD" "0" "PEAK-System" "PCAN-USB Pro" 1 "PCAN-USB Pro" "CAN, CAN FD" "0" "PEAK-System" "PCAN-USB Pro" 2 "PCAN-USB Pro" "CAN, CAN FD" "0" "Kvaser" "USBcan Professional 1" 1 "USBcan Professional" "CAN" "10680" "Kvaser" "USBcan Professional 1" 1 "USBcan Professional" "CAN" "10680" "Kvaser" "Virtual 1" 1 "Virtual" "CAN, CAN FD" "0" "Kvaser" "Virtual 1" 2 "Virtual" "CAN, CAN FD" "0" "NI" "9862 CAN/HS (CAN1)" 1 "9862" "CAN, CAN FD" "17F5094" "NI" "9862 CAN/HS (CAN2)" 1 "9862" "CAN, CAN FD" "17F50B2"
Note
To modify this example for a hardware CAN device, make a loopback connection between the two channels.
Create CAN Channels
Create two MathWorks® virtual CAN channels.
canch1 = canChannel('MathWorks','Virtual 1',1) canch2 = canChannel('MathWorks','Virtual 1',2)
canch1 = 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: [] canch2 = 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: []
For each channel, notice that its initial Running
value is
0
(stopped), and its bus speed is 500000
.
Note
You cannot use the same variable to create multiple channels sequentially. Clear any channel before using the same variable to construct a new CAN channel.
You cannot create arrays of CAN channel objects. Each object you create must be assigned to its own scalar variable.
Configure Channel Properties
You can set the behavior of your CAN channel by configuring its property values. For
this exercise, change the bus speed of channel 1 to 250000 using the configBusSpeed
function.
Tip
Configure property values before you start the channel.
Change the bus speed of both channels to
250000
, then view the channelBusSpeed
property to verify the setting.configBusSpeed(canch1,250000) canch1.BusSpeed
ans = 250000
You can also see the updated bus speed in the channel display.
canch1
canch1 = 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: 250000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
In a similar way, change the bus speed of the second channel.
configBusSpeed(canch2,250000)
Start the Channels
After you configure their properties, start both channels. Then view the updated status information of the first channel.
start(canch1) start(canch2) canch1
canch1 = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 1 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 1 MessagesAvailable: 0 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-May-2019 15:43:40 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: 250000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
Running
property value is now 1
(true).Create a Message
After you set all the property values as desired and your channels are running, you are
ready to transmit and receive messages on the CAN bus. For this exercise, transmit a message
using canch1
and receive it using canch2
. To transmit
a message, create a message object and pack the message with the required data.
Build a CAN message with a standard type ID of 500, and a data length of 8 bytes.
messageout = canMessage(500,false,8)
messageout = Message with properties: Message Identification ProtocolMode: 'CAN' ID: 500 Extended: 0 Name: '' Data Details Timestamp: 0 Data: [0 0 0 0 0 0 0 0] Signals: [] Length: 8 Protocol Flags Error: 0 Remote: 0 Other Information Database: [] UserData: []
Some of the properties of the message indicate:
Error
— A logical0
(false) because the message is not an error.Remote
— A logical0
(false) because the message is not a remote frame.ID
— The ID you specified.Extended
— A logical0
(false) because you did not specify an extended ID.Data
— A uint8 array of 0s, with size specified by the data length.
See the canMessage
function to understand more about its
input arguments.
Pack a Message
After you create the message, pack it with the required data.
Use the pack
function to pack your message with these
input parameters: a Data
value of 25, start bit of 0, signal size of
16, and byte order using little-endian format. View the message Data
property to verify the settings.
pack(messageout,25,0,16,'LittleEndian')
messageout.Data
ans = 1×8 uint8 row vector 25 0 0 0 0 0 0 0
The only message property that changes from packing is Data
. See
the pack
function to understand more about its input arguments.
Transmit a Message
Now you can transmit the packed message. Use the transmit
function, supplying the channel canch1
and the
message as input arguments.
transmit(canch1,messageout) canch1
canch1 = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 1 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 1 MessagesAvailable: 1 MessagesReceived: 0 MessagesTransmitted: 1 InitializationAccess: 1 InitialTimestamp: 23-May-2019 15:43:40 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: 250000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
MATLAB® displays the updated channel. In the Status Information section, the
MessagesTransmitted
value increments by 1 each time you transmit a
message. The message to be received is available to all devices on the bus, so it shows up
in the MessagesAvailable
property even for the transmitting
channel.
See the transmit
function to understand more about its
input arguments.
Receive a Message
Use the receive
function to receive the available message
on canch2
.
To see messages available to be received on this channel, type:
canch2
canch2 = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 1 MessagesAvailable: 1 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-May-2019 15:43:40 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: 250000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
The channel status information indicates 1 for
MessagesAvailable
.Receive one message on
canch2
and assign it tomessagein
. A short pause assures that the message transmission is complete.messagein = receive(canch2,1)
messagein = Message with properties: Message Identification ProtocolMode: 'CAN' ID: 500 Extended: 0 Name: '' Data Details Timestamp: 0.0312 Data: [25 0 0 0 0 0 0 0] Signals: [] Length: 8 Protocol Flags Error: 0 Remote: 0 Other Information Database: [] UserData: []
Note the received message
Data
property. This matches the data transmitted fromcanch1
.Refer to the
receive
function to understand more about its input arguments.To check if the channel received the message, view the channel display.
canch2
canch2 = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 1 MessagesAvailable: 0 MessagesReceived: 1 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: 23-May-2019 15:43:40 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: 250000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
The channel status information indicates 1 for
MessagesReceived
, and 0 forMessagesAvailable
.
Unpack a Message
After your channel receives a message, specify how to unpack the message and interpret
the data in the message. Use unpack
to specify the parameters for unpacking a
message; these should correspond to the parameters used for packing.
value = unpack(messagein,0,16,'LittleEndian','int16')
value = int16 25
Refer to the unpack
function to understand more about its
input arguments.
Save and Load CAN Channels
You can save a CAN channel object to a file using the save
function anytime during the CAN communication session.
To save canch1
to the MATLAB file mycanch.mat
, type:
save mycanch.mat canch1
If you have saved a CAN channel in a MATLAB file, you can load the channel into MATLAB using the load
function. For example, to reload the
channel from mycanch.mat
which was created earlier, type:
load mycanch.mat
The loaded CAN channel object reconnects to the specified hardware and reconfigures itself to the specifications when the channel was saved.
Disconnect Channels and Clean Up
Disconnect the Configured Channels
When you no longer need to communicate with your CAN bus, use the stop
function to disconnect the CAN channels that you configured.
Stop the first channel.
stop(canch1)
Check the channel status.
canch1
. . . Status Information Running: 0 MessagesAvailable: 1 MessagesReceived: 0 MessagesTransmitted: 1
Stop the second channel.
stop(canch2)
Check the channel status.
canch2
. . . Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 1 MessagesTransmitted: 0
Clean Up the MATLAB Workspace
When you no longer need these objects and variables, remove them from the MATLAB workspace with the clear
command.
Clear each channel.
clear canch1 clear canch2
Clear the CAN messages.
clear messageout clear messagein
Clear the unpacked value.
clear value