Периодическая передача сообщения CAN

Этот пример показывает вам, как использовать автоматизированные функции передачи сообщения CAN Vehicle Network Toolbox™, чтобы отправить периодические сообщения. Это использует MathWorks Virtual CAN channels, соединенный в петлевой настройке. Когда этот пример основан на отправке и получении сообщений CAN в виртуальной сети, рабочий CAN Explorer в соединении может обеспечить больше полного понимания того, что делает код. Чтобы запустить CAN Explorer, откройте и сконфигурируйте его, чтобы использовать тот же интерфейс в качестве канала получения примера. Убедитесь, что запустили CAN Explorer прежде, чем начать запускать пример для того, чтобы видеть все сообщения, как они происходят.

Создайте каналы CAN

Создайте каналы CAN, на которых можно использовать автоматизированные команды передачи сообщения.

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

В этом примере вы будете использовать файл базы данных CAN, чтобы задать и декодировать сообщения. Откройте базу данных и присоедините ее к каналам CAN.

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

Создайте сообщения CAN

Можно создать сообщения CAN, чтобы указать для периодической передачи с помощью информации о базе данных.

msgFast = canMessage(db, 'EngineMsg')
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 = canMessage(db, 'TransmissionMsg')
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: []

Сконфигурируйте сообщения для периодической передачи

Чтобы сконфигурировать сообщение для периодической передачи, используйте transmitPeriodic команда, чтобы задать канал, сообщение, чтобы указать на канале, значении режима и периодическом уровне.

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

Запустите периодическую передачу сообщения

Когда вы запускаете канал, которому указали периодические сообщения, передача сразу начинается. Позвольте каналы, запущенные в течение короткого времени.

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

Измените Transmitted Data

Чтобы обновить живое сообщение или данные сигнала, отправленные на шину CAN, запишите новые значения в сообщение, вы первоначально создали использование или Свойство данных или интерфейс сигналов.

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

Получите сообщения

Остановите каналы CAN и получите все периодически передаваемые сообщения для анализа.

stop(txCh);
stop(rxCh);
msgRx = receive(rxCh, Inf, 'OutputFormat', 'timetable');
msgRx(1:15, :)
ans=15×8 timetable
        Time        ID     Extended           Name                   Data            Length      Signals       Error    Remote
    ____________    ___    ________    ___________________    ___________________    ______    ____________    _____    ______

    0.014177 sec    100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.014183 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.11415 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.21416 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.31416 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.41418 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51416 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51416 sec     200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.61416 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.71416 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.81417 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.91417 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.0142 sec      100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.0142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.1142 sec      100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 

Анализируйте периодическое поведение передачи

Можно анализировать распределение сообщений путем графического вывода идентификаторов каждого сообщения против их меток времени. Заметьте различие между тем, как часто два сообщения появляются согласно своим периодическим уровням.

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

Figure contains an axes. The axes with title Message Distribution contains an object of type line.

Для последующего анализа разделите два сообщения на отдельные расписания.

msgRxFast = msgRx(strcmpi('EngineMsg', msgRx.Name), :);
msgRxFast(1:10, :)
ans=10×8 timetable
        Time        ID     Extended        Name                Data            Length      Signals       Error    Remote
    ____________    ___    ________    _____________    ___________________    ______    ____________    _____    ______

    0.014177 sec    100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.11415 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.21416 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.31416 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.41418 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51416 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.61416 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.71416 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.81417 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.91417 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 

msgRxSlow = msgRx(strcmpi('TransmissionMsg', msgRx.Name), :);
msgRxSlow(1:10, :)
ans=10×8 timetable
        Time        ID     Extended           Name                   Data            Length      Signals       Error    Remote
    ____________    ___    ________    ___________________    ___________________    ______    ____________    _____    ______

    0.014183 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51416 sec     200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.0142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.5142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    2.0142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    2.5142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    3.0142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    3.5142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    4.0142 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    4.5143 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 

Анализируйте метки времени каждого набора сообщений, чтобы видеть, как тесно среднее значение различий соответствует сконфигурированным периодическим уровням.

avgPeriodFast = mean(diff(msgRxFast.Time))
avgPeriodFast = duration
   0.1 sec

avgPeriodSlow = mean(diff(msgRxSlow.Time))
avgPeriodSlow = duration
   0.50001 sec

График полученных данных сигнала отражает обновления в данных о сообщении, отправленных на шине CAN.

signalTimetable = canSignalTimetable(msgRx, 'EngineMsg');
signalTimetable(1:10, :)
ans=10×2 timetable
        Time        VehicleSpeed    EngineRPM
    ____________    ____________    _________

    0.014177 sec         0             250   
    0.11415 sec          0             250   
    0.21416 sec          0             250   
    0.31416 sec          0             250   
    0.41418 sec          0             250   
    0.51416 sec          0             250   
    0.61416 sec          0             250   
    0.71416 sec          0             250   
    0.81417 sec          0             250   
    0.91417 sec          0             250   

plot(signalTimetable.Time, signalTimetable.VehicleSpeed)
title('Vehicle Speed from EngineMsg', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('Vehicle Speed')
ylim([-5 75])

Figure contains an axes. The axes with title Vehicle Speed from EngineMsg contains an object of type line.

Просмотрите сообщения, сконфигурированные для периодической передачи

Чтобы видеть сообщения, сконфигурированные на канале для периодической передачи, используйте transmitConfiguration команда.

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