exponenta event banner

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

В этом примере показано, как использовать функции автоматической передачи сообщений CAN Toolbox™ сети транспортных средств для передачи периодических сообщений. Он использует виртуальные каналы CAN MathWorks, подключенные в конфигурации с закольцовыванием. Поскольку этот пример основан на передаче и получении сообщений 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);

Изменение передаваемых данных

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

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