Documentation

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Periodic CAN Message Transmission

This example shows you how to use the automated CAN message transmit features of Vehicle Network Toolbox™ to send periodic messages. It uses MathWorks Virtual CAN channels connected in a loopback configuration. As this example is based on sending and receiving CAN messages on a virtual network, running Vehicle CAN Bus Monitor in conjunction may provide a more complete understanding of what the code is doing. To run Vehicle CAN Bus Monitor, open and configure it to use the same interface as the receiving channel of the example. Make sure to start Vehicle CAN Bus Monitor before beginning to run the example in order to see all of the messages as they occur.

Create the CAN Channels

Create CAN channels on which to use the automated message transmit commands.

txCh = canChannel('MathWorks', 'Virtual 1', 1);
rxCh = canChannel('MathWorks', 'Virtual 1', 2);

In this example, you will use a CAN database file to define and decode messages. Open the database and attach it to the CAN channels.

db = canDatabase('demoVNT_CANdbFiles.dbc');
txCh.Database = db;
rxCh.Database = db;

Create the CAN Messages

You can create CAN messages to register for periodic transmit using the database information.

msgFast = canMessage(db, 'EngineMsg')
msgSlow = canMessage(db, 'TransmissionMsg')
msgFast = 

  Message with properties:

   Message Identification
    ProtocolMode: 'CAN'
              ID: 100
        Extended: 0
            Name: 'EngineMsg'

   Data Details
       Timestamp: 0
            Data: [0 0 0 0 0 0 0 0]
         Signals: [1x1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1x1 can.Database]
        UserData: []


msgSlow = 

  Message with properties:

   Message Identification
    ProtocolMode: 'CAN'
              ID: 200
        Extended: 0
            Name: 'TransmissionMsg'

   Data Details
       Timestamp: 0
            Data: [0 0 0 0 0 0 0 0]
         Signals: [1x1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1x1 can.Database]
        UserData: []

Configure Messages for Periodic Transmit

To configure a message for periodic transmit, use the transmitPeriodic command to specify the channel, the message to register on the channel, a mode value, and the periodic rate.

transmitPeriodic(txCh, msgFast, 'On', 0.100);
transmitPeriodic(txCh, msgSlow, 'On', 0.500);

Start the Periodic Message Transmit

When you start a channel which has periodic messages registered, transmit begins immediately. Allow the channels run for a short time.

start(rxCh);
start(txCh);
pause(2);

Modify Transmitted Data

To update the live message or signal data sent onto the CAN bus, write new values into the message you originally created using either the Data property or the signals interface.

msgFast.Signals.VehicleSpeed = 60;
pause(1);
msgFast.Signals.VehicleSpeed = 65;
pause(1);
msgFast.Signals.VehicleSpeed = 70;
pause(1);

Receive the Messages

Stop the CAN channels and receive all periodically transmitted messages for analysis.

stop(txCh);
stop(rxCh);
msgRx = receive(rxCh, Inf, 'OutputFormat', 'timetable');
msgRx(1:15, :)
ans =

  15x8 timetable

        Time         ID     Extended          Name              Data        Length      Signals       Error    Remote
    _____________    ___    ________    _________________    ___________    ______    ____________    _____    ______

    0.0037941 sec    100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.0038103 sec    200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.1038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.2038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.30381 sec      100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.4038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.5038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.5038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.60383 sec      100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.7038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.8038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    0.90381 sec      100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    1.0038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 
    1.0038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    1.1038 sec       100     false      'EngineMsg'          [1x8 uint8]      8       [1x1 struct]    false    false 

Analyze the Periodic Transmit Behavior

You can analyze the distribution of messages by plotting the identifiers of each message against their timestamps. Notice the difference between how often the two messages appear according to their periodic rates.

plot(msgRx.Time, msgRx.ID, 'x')
ylim([0 400])
title('Message Distribution', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('CAN Identifier')

For further analysis, separate the two messages into individual timetables.

msgRxFast = msgRx(strcmpi('EngineMsg', msgRx.Name), :);
msgRxFast(1:10, :)
msgRxSlow = msgRx(strcmpi('TransmissionMsg', msgRx.Name), :);
msgRxSlow(1:10, :)
ans =

  10x8 timetable

        Time         ID     Extended       Name           Data        Length      Signals       Error    Remote
    _____________    ___    ________    ___________    ___________    ______    ____________    _____    ______

    0.0037941 sec    100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.1038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.2038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.30381 sec      100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.4038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.5038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.60383 sec      100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.7038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.8038 sec       100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.90381 sec      100     false      'EngineMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 


ans =

  10x8 timetable

        Time         ID     Extended          Name              Data        Length      Signals       Error    Remote
    _____________    ___    ________    _________________    ___________    ______    ____________    _____    ______

    0.0038103 sec    200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    0.5038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    1.0038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    1.5038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    2.0038 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    2.5039 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    3.0039 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    3.5039 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    4.0039 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 
    4.5039 sec       200     false      'TransmissionMsg'    [1x8 uint8]      8       [1x1 struct]    false    false 

Analyze the timestamps of each set of messages to see how closely the average of the differences corresponds to the configured periodic rates.

avgPeriodFast = mean(diff(msgRxFast.Time))
avgPeriodSlow = mean(diff(msgRxSlow.Time))
avgPeriodFast = 

  duration

   0.1 sec


avgPeriodSlow = 

  duration

   0.50001 sec

A plot of the received signal data reflects the updates in the message data sent on the CAN bus.

signalTimetable = canSignalTimetable(msgRx, 'EngineMsg');
signalTimetable(1:10, :)
plot(signalTimetable.Time, signalTimetable.VehicleSpeed)
title('Vehicle Speed from EngineMsg', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('Vehicle Speed')
ylim([-5 75])
ans =

  10x2 timetable

        Time         VehicleSpeed    EngineRPM
    _____________    ____________    _________

    0.0037941 sec         0             250   
    0.1038 sec            0             250   
    0.2038 sec            0             250   
    0.30381 sec           0             250   
    0.4038 sec            0             250   
    0.5038 sec            0             250   
    0.60383 sec           0             250   
    0.7038 sec            0             250   
    0.8038 sec            0             250   
    0.90381 sec           0             250   

View Messages Configured for Periodic Transmit

To see messages configured on a channel for periodic transmit, use the transmitConfiguration command.

transmitConfiguration(txCh)
Periodic Messages

ID  Extended      Name             Data        Rate (seconds)
--- -------- --------------- ----------------- --------------
100 false    EngineMsg       0 0 0 0 70 0 0 0  0.100000
200 false    TransmissionMsg 0 0 0 0 0 0 0 0   0.500000


Event Messages

None

Was this topic helpful?