メインコンテンツ

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

Simulink におけるイベントベースの CAN メッセージ送信動作

この例では、Simulink ® と Vehicle Network Toolbox ™ でイベントベースの CAN メッセージ送信を使用する方法を示します。この機能により、あるタイムステップから次のタイムステップへのデータの変更が検出された場合に、CAN および CAN FD メッセージの送信が可能になります。

CAN および CAN FD Transmit ブロックで利用可能な構成オプションにより、データ変更時の送信が可能になります。有効にすると、特定の CAN ID のメッセージは、その ID のデータが変更された場合にのみ送信されます。各メッセージは、ID に基づいて各タイム ステップで個別に処理されます。無効にした場合、ブロック動作および定期送信動作は正常に機能します。さらに、イベントベースの送信を定期的な送信と併用して、両方を同時に動作させることもできます。

サンプルモデルの準備

含まれているサンプル モデルには、1 つの CAN Transmit ブロックに構成された 2 つの CAN Pack ブロックが含まれています。一方のメッセージのデータは定数ですが、もう一方はタイムステップごとに変化するカウンターです。

Model1.JPG

モデル例を開きます。

open EventTransmit

CANデータベースファイルアクセスの準備

canDatabase 関数を使用して、CAN DBC ファイルの内容にアクセスできます。この関数により、ネットワーク ノード、メッセージ、信号に関する詳細情報を入手できます。この DBC ファイルはモデル内で使用され、モデルから送信された情報を復号化するために使用されます。

db = canDatabase("CANBusEvent.dbc")
db = 
  Database with properties:

             Name: 'CANBusEvent'
             Path: 'C:\Users\jpyle\Documents\MATLAB\ExampleManager\jpyle.21bExampleBlitz\vnt-ex59902587\CANBusEvent.dbc'
            Nodes: {'ECU'}
         NodeInfo: [1×1 struct]
         Messages: {2×1 cell}
      MessageInfo: [2×1 struct]
       Attributes: {}
    AttributeInfo: [0×0 struct]
         UserData: []

テスト ノードは DBC ファイルで定義されます。

node = nodeInfo(db,"ECU")
node = struct with fields:
             Name: 'ECU'
          Comment: ''
       Attributes: {}
    AttributeInfo: [0×0 struct]

ノードは 2 つの CAN メッセージを送信します。

messageInfo(db,"Constant_Msg")
ans = struct with fields:
             Name: 'Constant_Msg'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 10
         Extended: 0
            J1939: []
           Length: 4
              DLC: 4
              BRS: 0
          Signals: {'Constant'}
       SignalInfo: [1×1 struct]
          TxNodes: {'ECU'}
       Attributes: {}
    AttributeInfo: [0×0 struct]

messageInfo(db,"Counter_Msg")
ans = struct with fields:
             Name: 'Counter_Msg'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 20
         Extended: 0
            J1939: []
           Length: 4
              DLC: 4
              BRS: 0
          Signals: {'Counter'}
       SignalInfo: [1×1 struct]
          TxNodes: {'ECU'}
       Attributes: {}
    AttributeInfo: [0×0 struct]

イベントベースの送信でモデルを実行する

イベントベースの送信のみを有効にする

CAN Transmit ブロック内のイベントベースの送信をプログラムで有効にします。また、定期的な送信を無効にします。

db = canDatabase("CANBusEvent.dbc")
db = 
  Database with properties:

             Name: 'CANBusEvent'
             Path: 'C:\Users\jpyle\Documents\MATLAB\ExampleManager\jpyle.21bExampleBlitz\vnt-ex59902587\CANBusEvent.dbc'
            Nodes: {'ECU'}
         NodeInfo: [1×1 struct]
         Messages: {2×1 cell}
      MessageInfo: [2×1 struct]
       Attributes: {}
    AttributeInfo: [0×0 struct]
         UserData: []

set_param('EventTransmit/CAN Transmit', 'EnableEventTransmit', 'on');
set_param('EventTransmit/CAN Transmit', 'EnablePeriodicTransmit', 'off');

設定を適用するとブロックの表示が変わることに注意してください。

Model2.JPG

モデルとの通信用にMATLABのCANチャネルを設定する

仮想デバイス通信を使用して CAN チャネルを作成し、Simulink モデルとインターフェースします。また、CAN データベースを接続して、受信メッセージを自動的に復号化することもできます。

canCh = canChannel("Mathworks","Virtual 1",2)
canCh = 
  Channel with properties:

   Device Information
            DeviceVendor: 'MathWorks'
                  Device: 'Virtual 1'
      DeviceChannelIndex: 2
      DeviceSerialNumber: 0
            ProtocolMode: 'CAN'

   Status Information
                 Running: 0
       MessagesAvailable: 0
        MessagesReceived: 0
     MessagesTransmitted: 0
    InitializationAccess: 1
        InitialTimestamp: [0×0 datetime]
           FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

   Channel Information
               BusStatus: 'N/A'
              SilentMode: 0
         TransceiverName: 'N/A'
        TransceiverState: 'N/A'
       ReceiveErrorCount: 0
      TransmitErrorCount: 0
                BusSpeed: 500000
                     SJW: []
                   TSEG1: []
                   TSEG2: []
            NumOfSamples: []

   Other Information
                Database: []
                UserData: []

canCh.Database = db;

CAN チャネルを開始してオンラインにします。

start(canCh);

モデルの実行

シミュレーション実行時間を割り当ててモデルを開始します。

t = "10";
set_param("EventTransmit","StopTime",t)
set_param("EventTransmit","SimulationCommand","start");

シミュレーションが開始するまで待ちます。

while strcmp(get_param("EventTransmit","SimulationStatus"),"stopped")
end

シミュレーションが終了するまでお待ちください。

pause(2)

MATLAB でメッセージを受信する

モデルによって生成されたバスからのすべてのメッセージを受信します。

msg = receive(canCh,inf,"OutputFormat","timetable")
msg=12×8 timetable
       Time       ID    Extended          Name              Data        Length      Signals       Error    Remote
    __________    __    ________    ________________    ____________    ______    ____________    _____    ______

    5.204 sec     10     false      {'Constant_Msg'}    {[ 5 0 0 0]}      4       {1×1 struct}    false    false 
    5.204 sec     20     false      {'Counter_Msg' }    {[ 0 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 1 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 2 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 3 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 4 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 5 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 6 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 7 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 8 0 0 0]}      4       {1×1 struct}    false    false 
    5.206 sec     20     false      {'Counter_Msg' }    {[ 9 0 0 0]}      4       {1×1 struct}    false    false 
    5.2061 sec    20     false      {'Counter_Msg' }    {[10 0 0 0]}      4       {1×1 struct}    false    false 

MATLAB ® の CAN チャネルを停止します。

stop(canCh);

受信したメッセージと信号データを調べる

CAN ID が受信された回数が以下にプロットされています。メッセージ「Constant_Msg」(CAN ID 10) は、初期設定後にデータが変更されないため、1 回だけ受信されます。モデルの実行中にデータが継続的に変更されたため、すべてのタイム ステップからメッセージ「Counter_Msg」(CAN ID 20) が受信されます。

% Define X and Y axis.
x = 1:length(msg.ID);
y = msg.ID;

% Plot the graph for both the CAN IDs received.
stem(x,y,'filled')
hold on;
yMax = max(msg.ID)+5;
ylim([0 yMax])

% Label the graph.
xlabel("Number of CAN messages");
ylabel("CAN ID");
legend("CAN ID","Location","northeast");
legend("boxoff");
hold off;

次に、同じシミュレーション実行中に各メッセージで受信した信号をプロットします。

% Create a structure with signal details.
signalTimeTable = canSignalTimetable(msg);

% Plot the signal values of "Constant_Msg".
x1 = 1:height(signalTimeTable.Constant_Msg);
y1 = signalTimeTable.Constant_Msg.Constant;
plot(x1, y1,"Marker","o");
hold on

% Plot the signal values of "Counter_Msg".
x2 = 1:height(signalTimeTable.Counter_Msg);
y2 = signalTimeTable.Counter_Msg.Counter;
plot(x2, y2,"Marker","o");

% Determine the maximum value for y-axis for scaling of graph.
y1Max = max(signalTimeTable.Constant_Msg.Constant);
y2Max = max(signalTimeTable.Counter_Msg.Counter);
yMax = max(y1Max,y2Max)+5;
ylim([0 yMax]);

% Label the graph.
xlabel("Number of Times Signals Received");
ylabel("CAN Signal Value");
legend("Constant","Counter","Location","northeastoutside");
legend("boxoff");
hold off

信号「Constant」(メッセージ「Constant_Msg」内) は 1 回だけプロットされますが、信号「Counter」(メッセージ「Counter_Msg」内) はすべてのタイム ステップでプロットされます。これは、CAN Transmit ブロックでイベントベースの送信が有効になっているためです。イベントベースの送信では、以前受信したメッセージと比較してその CAN ID のデータが変更された場合にのみ CAN メッセージが送信されます。

メッセージ「Counter_Msg」内の信号は、時間ステップごとに 1 ずつ増加するカウンターであるため、線形曲線が見られます。

各データ ポイントは、イベント ベースの送信が有効になっている送信を表します。したがって、信号「カウンター」はすべてのタイム ステップで受信されますが、信号「定数」は 1 回だけ受信されます。

イベントベースおよび定期的な送信でモデルを実行する

両方の送信モードを有効にする

CAN Transmit ブロック内のイベント送信をプログラムで有効にします。また、定期送信を有効にし、メッセージ周期を設定します。

set_param('EventTransmit/CAN Transmit', 'EnableEventTransmit', 'on');
set_param('EventTransmit/CAN Transmit', 'EnablePeriodicTransmit', 'on');
set_param('EventTransmit/CAN Transmit', 'MessagePeriod', '0.1');

設定を適用するとブロックの表示が変わることに注意してください。

Model3.JPG

モデルとの通信用にMATLABのCANチャネルを設定する

仮想デバイス通信を使用して CAN チャネルを作成し、Simulink モデルとインターフェースします。また、CAN データベースを接続して、受信メッセージを自動的に復号化することもできます。

canCh = canChannel("Mathworks","Virtual 1",2)
canCh = 
  Channel with properties:

   Device Information
            DeviceVendor: 'MathWorks'
                  Device: 'Virtual 1'
      DeviceChannelIndex: 2
      DeviceSerialNumber: 0
            ProtocolMode: 'CAN'

   Status Information
                 Running: 0
       MessagesAvailable: 0
        MessagesReceived: 0
     MessagesTransmitted: 0
    InitializationAccess: 1
        InitialTimestamp: [0×0 datetime]
           FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

   Channel Information
               BusStatus: 'N/A'
              SilentMode: 0
         TransceiverName: 'N/A'
        TransceiverState: 'N/A'
       ReceiveErrorCount: 0
      TransmitErrorCount: 0
                BusSpeed: 500000
                     SJW: []
                   TSEG1: []
                   TSEG2: []
            NumOfSamples: []

   Other Information
                Database: []
                UserData: []

canCh.Database = db;

CAN チャネルを開始してオンラインにします。

start(canCh);

モデルの実行

シミュレーション実行時間を割り当ててモデルを開始します。

t = "20";
set_param("EventTransmit","StopTime",t)
set_param("EventTransmit","SimulationCommand","start");

シミュレーションが開始するまで待ちます。

while strcmp(get_param("EventTransmit","SimulationStatus"),"stopped")
end

シミュレーションが終了するまでお待ちください。

pause(5);

MATLAB でメッセージを受信する

モデルによって生成されたバスからのすべてのメッセージを受信します。

msg = receive(canCh,Inf,"OutputFormat","timetable")
msg=22×8 timetable
       Time       ID    Extended          Name              Data        Length      Signals       Error    Remote
    __________    __    ________    ________________    ____________    ______    ____________    _____    ______

    4.598 sec     10     false      {'Constant_Msg'}    {[ 5 0 0 0]}      4       {1×1 struct}    false    false 
    4.598 sec     20     false      {'Counter_Msg' }    {[ 0 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 1 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 2 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 3 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 4 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 5 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 6 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 7 0 0 0]}      4       {1×1 struct}    false    false 
    4.5987 sec    20     false      {'Counter_Msg' }    {[ 8 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[ 9 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[10 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[11 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[12 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[13 0 0 0]}      4       {1×1 struct}    false    false 
    4.5988 sec    20     false      {'Counter_Msg' }    {[14 0 0 0]}      4       {1×1 struct}    false    false 
      ⋮

MATLAB の CAN チャネルを停止します。

stop(canCh);

受信したデータを調べる

同じ期間に各メッセージで受信したデータをプロットします。

% Create a structure with signal details.
signalTimeTable = canSignalTimetable(msg);

% Plot the signal values of "Constant_Msg".
x3 = 1:height(signalTimeTable.Constant_Msg);
y3 = signalTimeTable.Constant_Msg.Constant;
plot(x3, y3,"Marker","o");
hold on

% Plot the signal values of "Counter_Msg".
x4 = 1:height(signalTimeTable.Counter_Msg);
y4 = signalTimeTable.Counter_Msg.Counter;
plot(x4, y4,"Marker","o");

% Determine the maximum value for y-axis for scaling of graph.
y3Max = max(signalTimeTable.Constant_Msg.Constant);
y4Max = max(signalTimeTable.Counter_Msg.Counter);
yMax = max(y3Max,y4Max)+5;
ylim([0 yMax]);

% Label the graph.
xlabel("Number of Times Signals Received");
ylabel("CAN Signal Value");
legend("Constant","Counter","Location","northeastoutside");
legend("boxoff");
hold off

プロットは、メッセージ「Constant_Msg」内の信号「Constant」が、イベントベースの送信により開始時に 1 回、その後は送信の周期的な性質により、数回しか受信されないことを示しています。これは、信号への入力値が一定に保たれるためです。

信号「Counter」の値はメッセージ「Counter_Msg」内の各タイムステップで変化しますが、イベントベースの送信により継続的に受信され、その後、定期送信が有効になっているため、さらに数回の送信が行われます。