Main Content

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.

  1. 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.

  1. Change the bus speed of both channels to 250000, then view the channel BusSpeed property to verify the setting.

    configBusSpeed(canch1,250000)
    canch1.BusSpeed
    ans =
    
          250000
  2. 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: []
  3. 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: []
Notice that the channel 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 logical 0 (false) because the message is not an error.

  • Remote — A logical 0 (false) because the message is not a remote frame.

  • ID — The ID you specified.

  • Extended — A logical 0 (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.

  1. 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.

  2. Receive one message on canch2 and assign it to messagein. 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 from canch1.

    Refer to the receive function to understand more about its input arguments.

  3. 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 for MessagesAvailable.

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.

  1. Stop the first channel.

    stop(canch1)
  2. Check the channel status.

    canch1
    .
    .
    .
     Status Information
                     Running: 0
           MessagesAvailable: 1
            MessagesReceived: 0
         MessagesTransmitted: 1
  3. Stop the second channel.

    stop(canch2)
  4. 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.

  1. Clear each channel.

    clear canch1
    clear canch2
  2. Clear the CAN messages.

    clear messageout
    clear messagein
  3. Clear the unpacked value.

    clear value

Related Examples

More About