Периодическая коммуникация CAN в MATLAB

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

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

Этот пример описывает рабочий процесс для сети CAN, но концепция, продемонстрированная также, применяется к сети CAN FD.

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

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

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

Откройте файл DBC, который содержит сообщение и определения сигнала, и присоедините его к обоим каналам CAN.

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

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

Создайте сообщения CAN EngineMsg и TransmissionMsg использование информации о базе данных.

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, запишите новые значения непосредственно в VehicleSpeed сигнал в сообщении EngineMsg.

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

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

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

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

stop(txCh);
stop(rxCh);
msgRx = receive(rxCh, Inf, "OutputFormat", "timetable");

Просмотрите первые несколько строк полученных сообщений с помощью head функция.

head(msgRx)
ans=8×8 timetable
        Time        ID     Extended           Name                   Data            Length      Signals       Error    Remote
    ____________    ___    ________    ___________________    ___________________    ______    ____________    _____    ______

    0.011398 sec    100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.011401 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.1114 sec      100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.21142 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.31141 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.4114 sec      100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51141 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51141 sec     200     false      {'TransmissionMsg'}    {[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 object. The axes object with title Message Distribution contains an object of type line.

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

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

    0.011398 sec    100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.1114 sec      100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.21142 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.31141 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.4114 sec      100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51141 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.61144 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.71141 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 

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

    0.011401 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    0.51141 sec     200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.0114 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    1.5115 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    2.0114 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    2.5115 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    3.0115 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1x1 struct}    false    false 
    3.5115 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

Используйте canSignalTimetable данным сигнала перепакета из сообщения EngineMsg в расписание сигнала.

signalTimetable = canSignalTimetable(msgRx, "EngineMsg");
head(signalTimetable)
ans=8×2 timetable
        Time        VehicleSpeed    EngineRPM
    ____________    ____________    _________

    0.011398 sec         0             250   
    0.1114 sec           0             250   
    0.21142 sec          0             250   
    0.31141 sec          0             250   
    0.4114 sec           0             250   
    0.51141 sec          0             250   
    0.61144 sec          0             250   
    0.71141 sec          0             250   

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

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

Figure contains an axes object. The axes object 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

Закройте каналы и файл DBC

Закройте доступ к каналам и файлу DBC путем очищения их переменных из рабочей области.

clear rxCh txCh
clear db