メインコンテンツ

このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。

MATLAB における定期的な CAN 通信

この例では、定期的にメッセージを送信するための CAN チャネルとメッセージを構成する方法を示します。ループバック構成で接続されている MathWorks® バーチャル CAN チャネルを使用します。

この例は仮想ネットワーク上での CAN メッセージの送受信に基づいているため、CAN エクスプローラーを併せて実行すると、コードが何を実行しているかをより完全に理解できるようになります。CAN エクスプローラーを実行するには、それを開いて、例の受信チャネルと同じインターフェイスを使用するように設定します。発生したすべてのメッセージを確認するには、例の実行を開始する前に必ず CAN エクスプローラーを起動してください。

この例では、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: [1×1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1×1 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: [1×1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

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

定期的な送信メッセージの設定

メッセージの定期送信を有効にするには、送信チャネル、チャネルに登録するメッセージ、状態値、および定期レートを指定して、transmitPeriodic コマンドを使用します。

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

定期送信を開始する

受信チャネルを開始します。

start(rxCh);

前の手順で設定した定期送信を使用して送信チャネルを開始します。生理の伝達は直ちに始まります。チャネルを 2 秒間実行します。

start(txCh);
pause(2);

送信データの更新

CAN バスに送信されるライブ メッセージまたは信号データを更新するには、メッセージ EngineMsgVehicleSpeed 信号に新しい値を直接書き込みます。

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)
        Time        ID     Extended           Name                   Data            Length      Signals       Error    Remote
    ____________    ___    ________    ___________________    ___________________    ______    ____________    _____    ______

    0.031922 sec    100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.031924 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.13752 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.24011 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.35028 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.45648 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.53209 sec     200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.56215 sec     100     false      {'EngineMsg'      }    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 

周期的伝送の挙動を解析する

受信した各メッセージの識別子をタイムスタンプに対してプロットして、メッセージの分布を解析します。設定された定期的なレートに応じて 2 つのメッセージが表示される頻度の違いに注意してください。

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

さらに解析するには、2 つのメッセージを個別の timetable に分けます。

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

    0.031922 sec    100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.13752 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.24011 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.35028 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.45648 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.56215 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.66495 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.77479 sec     100     false      {'EngineMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
msgRxSlow = msgRx(strcmpi("TransmissionMsg", msgRx.Name), :);
head(msgRxSlow)
        Time        ID     Extended           Name                   Data            Length      Signals       Error    Remote
    ____________    ___    ________    ___________________    ___________________    ______    ____________    _____    ______

    0.031924 sec    200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.53209 sec     200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    1.0317 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    1.5323 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    2.0437 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    2.5418 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    3.0423 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    3.5422 sec      200     false      {'TransmissionMsg'}    {[0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 

各メッセージ セットのタイムスタンプを解析して、差異の平均が設定された定期的なレートにどの程度一致しているかを確認します。

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

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

canSignalTimetable を使用して、メッセージ EngineMsg からの信号データを signal timetable に再パッケージ化します。

signalTimetable = canSignalTimetable(msgRx, "EngineMsg");
head(signalTimetable)
        Time        VehicleSpeed    EngineRPM
    ____________    ____________    _________

    0.031922 sec         0             250   
    0.13752 sec          0             250   
    0.24011 sec          0             250   
    0.35028 sec          0             250   
    0.45648 sec          0             250   
    0.56215 sec          0             250   
    0.66495 sec          0             250   
    0.77479 sec          0             250   

信号 VehicleSpeed の受信値を時間の経過に沿ってプロットし、メッセージ データの 3 つの更新がどのように反映されるかを確認します。

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

定期送信用に設定されたメッセージを表示する

送信チャネルで自動送信用に設定されたメッセージを表示するには、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