こちらは新しい記事のシリーズで、三菱電機のMXF-EtherCATバージョンのCPUで様々な検証を行います。第4話ではMXF-EtherCATからSDOメッセージを使用しWAGOの新しいEtherCATカプラー7553-8000にパラメータを読み書きします。
さ、FAを楽しもう!
Reference Link
https://soup01.com/ja/category/mitsubishi-jp/mxr/
SDO Communications (Communications using Service Data Objects)
SDO(Service Data Object:サービスデータオブジェクト)は、EtherCATマスタから必要に応じて、指定したスレーブのデータを読み書きするための通信方式で、登録されたデータへのアクセスや、デバイスパラメータの送受信に使用されます。
主な用途として、スレーブの設定情報の読み取りや、各種動作パラメータの書き込みなどが挙げられます。
SDOによるデータ通信は非周期的に実行されます。例えば、デバイスの起動時に一度だけ設定パラメータを送信するような用途に使用されます。
このように、SDOは周期的なプロセスデータ交換とは異なり、必要なタイミングで実行される通信であるため、通信の優先度は比較的低く設定されています。
MX_ECのモジュールラベル一覧
こちらは今回記事でSDOメッセージ経由でCOE読み書きのために使用するMX_ECラベルです。
モジュールラベル (MX_EC.以下)
| バッファメモリ
| データ型
| 説明
|
|---|
uSet_SDOControlCommand_D
|
U40\G90112
|
WORD
|
SDO通信実行コマンド
|
|---|
uSet_SDOTransmitNodeAddress_D
|
U40\G90113
|
WORD
|
送信先Slaveのノードアドレス
|
|---|
uSet_SDOTransmitIndexNumber_D
|
U40\G90114
|
WORD
|
アクセス先CoE Index
|
|---|
uSet_SDOTransmitSubIndexNumber_D
|
U40\G90115
|
WORD
|
アクセス先SubIndex
|
|---|
udSet_SDOTransmitDataSize_D
|
U40\G90116~90117
|
DWORD
|
書込みデータ長。単位Byte
|
|---|
unSet_SDOTransmitData_D
|
U40\G90118~90517
|
WORD配列
|
SDO書込みデータ
|
|---|
uSts_SDOExecutedControlCommand_D
|
U40\G90518
|
WORD
|
SDO実行完了状態
|
|---|
udSts_SDOReceiveDataSize_D
|
U40\G90522~90523
|
DWORD
|
受信データ長。単位Byte
|
|---|
unSts_SDOReceiveData_D
|
U40\G90524~90923
|
WORD配列
|
SDO読出し結果
|
|---|
uSts_SDOErrorCode_D
|
U40\G90924
|
WORD
|
SDO通信エラーコード
|
|---|
udSts_SDODetailErrorCode_D
|
U40\G90926~90927
|
DWORD
|
SDO通信詳細エラー
|
|---|
SDO制御コマンド
完了判定は、要求コマンドと実行済みコマンドが一致することです。実行完了後でも、エラーコードを確認する必要があります。
SDO要求を0へ戻すと、MX-Fの受信データやエラー情報がクリアされるため、プログラムでは結果をローカル変数へ保存してから要求を解除します。
指令値
| 説明
| 動作
|
|---|
0
|
No Command
|
待機・要求解除
|
|---|
1
|
SDO Communication UPLOAD
|
CoE Objectの読出し
|
|---|
2
|
SDO Communication DOWNLOAD
|
CoE Objectの書込み
|
|---|
WAGO側のCoE Object Dictionary
こちらは今回記事でアクセスするCoEです。
Index
| SubIndex
| Object
| Access
| 今回の用途
|
|---|
0x1000
|
0x00
|
Device Type
|
RO
|
デバイス種別を確認
|
|---|
0x10F3
|
0x05
|
Diagnosis History – Flags
|
RW
|
診断記録とEMCY通知を設定
|
|---|
0x1000:00 — Device Type
-
データ型:UNSIGNED32(4 Byte)
-
アクセス:Read Only
-
仕様書記載値:0x00001389
-
今回の実機では、SDO Readにより下位16bitとしてH1389を取得しました。上位16bitも0であれば、32bit値は0x00001389です。
0x10F3:05 — Diagnosis History Flags
これは、WAGOの診断情報の記録やEtherCAT Emergency Message(EMCY)の送信を制御するオブジェクトです。
Bit
| マスク
| WAGO資料の説明
| 1の場合
|
|---|
0
|
0x0001
|
Enable EMCY sending
|
EMCY送信を有効
|
|---|
1
|
0x0002
|
Ignore infos
|
情報メッセージの記録を無視
|
|---|
2
|
0x0004
|
Ignore warnings
|
警告メッセージの記録を無視
|
|---|
3
|
0x0008
|
Ignore errors
|
エラーメッセージの記録を無視
|
|---|
4
|
0x0010
|
Acknowledge mode
|
承認モードの状態
|
|---|
5
|
0x0020
|
Message buffer full
|
診断バッファ満杯の状態
|
|---|
7557-0441 Status bytes
ステータスバイトは、すべてのチャネルで同一の方法で実装されています。
ステータスバイト構成
BIT
| 名称
| 値:0の状態
| 値:1の状態
|
|---|
Bit 7
|
Reserved(予約)
|
—
|
—
|
|---|
Bit 6
|
General Error(総合エラー)
|
エラーなし。Bit 0、1、4、5のエラーフラグが設定されていない状態です。
|
エラーあり。Bit 0、1、4、5のいずれかのエラーフラグが設定されている状態です。
|
|---|
Bit 5
|
Wire Break(断線)
|
センサケーブルに断線が発生していない状態です。
|
センサケーブルに断線が発生している状態です。
|
|---|
Bit 4
|
Overload(過負荷)
|
過負荷が発生していない状態です。
|
センサケーブルに過負荷が発生している状態です。
|
|---|
Bit 3
|
User Overrange(ユーザー設定上限超過)
|
フィールド側の入力電圧または入力電流が、ユーザー設定の上限値を下回っている状態です。
|
フィールド側の入力電圧または入力電流が、ユーザー設定の上限値を超えている状態です。
|
|---|
Bit 2
|
User Underrange(ユーザー設定下限未満)
|
フィールド側の入力電圧または入力電流が、ユーザー設定の下限値を上回っている状態です。
|
フィールド側の入力電圧または入力電流が、ユーザー設定の下限値を下回っている状態です。
|
|---|
Bit 1
|
Overrange(測定範囲上限超過)
|
フィールド側の入力電圧または入力電流が、測定範囲の上限値を下回っている状態です。
|
フィールド側の入力電圧または入力電流が、測定範囲の上限値を超えている状態です。
|
|---|
Bit 0
|
Underrange(測定範囲下限未満)
|
フィールド側の入力電圧または入力電流が、測定範囲の下限値を上回っている状態です。
|
フィールド側の入力電圧または入力電流が、測定範囲の下限値を下回っている状態です。
|
|---|
プロセスイメージ(Standard)
バイト位置
| 入力プロセスデータ
|
|---|
Byte 0
|
プロセス値 CH1_D0
|
|---|
Byte 1
|
プロセス値 CH1_D1
|
|---|
Byte 2
|
プロセス値 CH2_D0
|
|---|
Byte 3
|
プロセス値 CH2_D1
|
|---|
Byte 4
|
プロセス値 CH3_D0
|
|---|
Byte 5
|
プロセス値 CH3_D1
|
|---|
Byte 6
|
プロセス値 CH4_D0
|
|---|
Byte 7
|
プロセス値 CH4_D1
|
|---|
プロセスイメージ(Advanced)
バイト位置
| 入力プロセスデータ
|
|---|
Byte 0
|
プロセス値 CH1_D0
|
|---|
Byte 1
|
プロセス値 CH1_D1
|
|---|
Byte 2
|
プロセス値 CH2_D0
|
|---|
Byte 3
|
プロセス値 CH2_D1
|
|---|
Byte 4
|
プロセス値 CH3_D0
|
|---|
Byte 5
|
プロセス値 CH3_D1
|
|---|
Byte 6
|
プロセス値 CH4_D0
|
|---|
Byte 7
|
プロセス値 CH4_D1
|
|---|
Byte 8
|
ステータスバイト CH1_S0
|
|---|
Byte 9
|
ステータスバイト CH2_S1
|
|---|
Byte 10
|
ステータスバイト CH3_S2
|
|---|
Byte 11
|
ステータスバイト CH4_S3
|
|---|
7557-0461 Status bytes
ステータスバイトは、すべてのチャネルで同一の方法で実装されています。
ステータスバイト構成
BIT
| 名称
| 値:0の状態
| 値:1の状態
|
|---|
Bit 7
|
Reserved(予約)
|
予約ビット
|
—
|
|---|
Bit 6
|
General Error(総合エラー)
|
エラーなし。Bit 3(短絡)およびBit 4(断線)のエラーフラグが設定されていない状態です。
|
総合エラーあり。Bit 3(短絡)またはBit 4(断線)のエラーフラグが設定されている状態です。
|
|---|
Bit 5
|
Reserved(予約)
|
予約ビット(0固定)
|
—
|
|---|
Bit 4
|
Wire Break(断線)
|
断線が発生していない状態です。
|
アナログ出力端子(+AO1、−AO1)が開放状態または異常に高いインピーダンス状態にある、もしくは出力端子に外部電圧が印加されている状態です。
|
|---|
Bit 3
|
Short Circuit(短絡)
|
短絡が発生していない状態です。
|
アナログ出力端子(+AO1、−AO1)間で短絡が発生している状態です。
|
|---|
Bit 2
|
Reserved(予約)
|
予約ビット(0固定)
|
—
|
|---|
Bit 1
|
Reserved(予約)
|
予約ビット(0固定)
|
—
|
|---|
Bit 0
|
Reserved(予約)
|
予約ビット(0固定)
|
—
|
|---|
プロセスイメージ
出力バイト位置
| 出力プロセスデータ
| 入力バイト位置
| 入力プロセスデータ
|
|---|
Byte 0
|
プロセス値 CH1_D0
|
Byte 0
|
ステータスバイト CH1_S0
|
|---|
Byte 1
|
プロセス値 CH1_D1
|
Byte 1
|
ステータスバイト CH2_S1
|
|---|
Byte 2
|
プロセス値 CH2_D0
|
Byte 2
|
ステータスバイト CH3_S2
|
|---|
Byte 3
|
プロセス値 CH2_D1
|
Byte 3
|
ステータスバイト CH4_S3
|
|---|
Byte 4
|
プロセス値 CH3_D0
|
―
|
―
|
|---|
Byte 5
|
プロセス値 CH3_D1
|
―
|
―
|
|---|
Byte 6
|
プロセス値 CH4_D0
|
―
|
―
|
|---|
Byte 7
|
プロセス値 CH4_D1
|
―
|
―
|
|---|
Implementation
WAGO 7553-8000側
最初はWAGO 7553-8000側から設定します。
DIP スイッチ
今回の記事ではWAGO EtherCATカプラーをID=7️に設定しますので、本体にあるDIPスイッチのスイッチ1,2,3をON側にしてください。
MXF-EtherCAT側
次はMXF-EtherCAT側を構築します。
EtherCATネットワーク構築
EtherCATネットワークを構築するにはModule Parameters→Module Extended Parametersをクリックします。
モジュール設定
前回PART3で追加した7557-0441 Standardと7557-0461 Standardをモジュール構成から消します。
下図にある”X”ボタンをクリックします。
YESで進みます。
次は右側から7557-0441 Advancedと7557-0461 Advancedをモジュール構成に追加します。
Done!
7557-0441のPDO MappingにはStatus Wordが追加されました。
7557-0461のPDO MappingにはStatus Wordが追加されました。
設定保存
Close with Reflecting the Settingをクリックしネットワーク設定を保存します。
Yesをクリックします。
ラベル生成
今度はラベルを生成します。Labeling Targetを選択し→Label Nameを入力→Create Labelで構造体ラベルを生成しましょう。
Yesで進みます。
Done!
プログラム
構造体
最初は構造体を作成します。
dut_wago7553_8000_DiagStatusWord
WAGO 7553-8000 EtherCATカプラーのStatus Wordを分解するための構造体を作成します。
dut_wago7557_0461_StatusWord
WAGO 7553-0461 アナログ出力のStatus Wordを分解するための構造体を作成します。
dut_wago7557_0441_StatusWord
WAGO 7553-0441 アナログ入力のStatus Wordを分解するための構造体を作成します。
FUN
Functionを追加するために、FB/FUN→右クリック→Add New Dataし新しいFCを追加します。
fc_wago7553_8000_DiagStatusWord
fc_wago7553_8000_DiagStatusWord関数はWAGO 7553-8000 EtherCATカプラーにインストールされた診断ワードからカプラーの状態を判断します。
fc_wago7553_8000_DiagStatusWord.CHNUM.0:=iwData.0;
fc_wago7553_8000_DiagStatusWord.CHNUM.1:=iwData.1;
fc_wago7553_8000_DiagStatusWord.CHNUM.2:=iwData.2;
fc_wago7553_8000_DiagStatusWord.CHNUM.3:=iwData.3;
fc_wago7553_8000_DiagStatusWord.CHNUM.4:=iwData.4;
fc_wago7553_8000_DiagStatusWord.CHNUM.5:=iwData.5;
fc_wago7553_8000_DiagStatusWord.CHNUM.6:=iwData.6;
fc_wago7553_8000_DiagStatusWord.CHNUM.7:=iwData.7;
fc_wago7553_8000_DiagStatusWord.CHNUM.0:=iwData.8;
fc_wago7553_8000_DiagStatusWord.CHNUM.1:=iwData.9;
fc_wago7553_8000_DiagStatusWord.CHNUM.2:=iwData.A;
fc_wago7553_8000_DiagStatusWord.EVTCODE.0:=iwData.B;
fc_wago7553_8000_DiagStatusWord.EVTCODE.1:=iwData.C;
fc_wago7553_8000_DiagStatusWord.EVTCODE.2:=iwData.D;
fc_wago7553_8000_DiagStatusWord.CLRACK.0:=iwData.E;
fc_wago7553_8000_DiagStatusWord.EVENT.0:=iwData.F;
;
|
|---|
fc_wago7557_0461_StatusWord
fc_wago7557_0461_StatusWord関数はWAGO 7557_0461 アナログ出力にインストールされた診断ワードからモジュールの状態を判断します。
fc_wago7557_0461_StatusWord.Generalerror:=iwData.3;
fc_wago7557_0461_StatusWord.Generalerror:=iwData.4;
fc_wago7557_0461_StatusWord.Generalerror:=iwData.6;
;
|
|---|
fc_wago7557_0441_StatusWord
fc_wago7557_0441_StatusWord関数はWAGO 7557_0441 アナログ入力にインストールされた診断ワードからモジュールの状態を判断します。
fc_wago7557_0441_StatusWord.Underrange:=iwData.0;
fc_wago7557_0441_StatusWord.Overrange:=iwData.1;
fc_wago7557_0441_StatusWord.UserUnderrange:=iwData.2;
fc_wago7557_0441_StatusWord.UserOverrange:=iwData.3;
fc_wago7557_0441_StatusWord.WireBreak:=iwData.5;
fc_wago7557_0441_StatusWord.GeneralError:=iwData.6;
;
|
|---|
MAIN
次はメインプログラムです。
こちらは検証プログラムです。ST言語のR_TRIGとSHLを使用し、16ビットのデジタル出力を順番にONさせるプログラムを作成しました。
-
R_TRIGで100msクロック信号の立ち上がり、かつWAGOの入力モジュールに配線したボタンを押したことを検出し、SHLによって出力データを1ビットずつ左にシフトします。
-
NX-ECC202・NX-ECC203出力データが0の場合は初期値として1を設定し、最上位ビット(Bit 15)に到達すると出力データをクリアして、再びBit 0から処理を繰り返します。
-
WAGO 7557-0123出力モジュールはChannel1からChannel16までON・OFFを繰り返します。
-
7557-0461アナログ出力チャンネル1の出力値は7557-0441アナログ入力値1そのままLoop Backします。
-
先程作成した関数からWAGO 7553-8000 EtherCATカプラーとモジュールの状態を確認します。
//EtherCAT Ready
M10:=MX_EC.bIn_EtherCATFunction_Ready;
//Sub Devices
D100:=MX_EC.unSts_SubDeviceESMState_D[0];
D101:=MX_EC.unSts_SubDeviceESMState_D[1];
D102:=MX_EC.unSts_SubDeviceESMState_D[2];
D103:=MX_EC.unSts_SubDeviceESMState_D[3];
//
IF iCounter <0 THEN
iCounter:=0;
END_IF;
//fbR_TRIG(CLK:= MX_SQ.stSM.b10msClock);
fbR_TRIG(CLK:= MX_SQ.stSM.b100msClock AND stID07.Module17557_010516DI_3msNPNInputs_Channel1Data1 =1);
IF SubDevice_1001NX_ECC203_Module1NX_OD5256OutputDataSet1_OutputBit16bits = 0 THEN
SubDevice_1001NX_ECC203_Module1NX_OD5256OutputDataSet1_OutputBit16bits:=1;
END_IF;
IF fbR_TRIG.Q THEN
SubDevice_1001NX_ECC203_Module1NX_OD5256OutputDataSet1_OutputBit16bits:=
SHL(
SubDevice_1001NX_ECC203_Module1NX_OD5256OutputDataSet1_OutputBit16bits
,1
);
END_IF;
IF stID40.Module2NX_OD5256OutputDataSet1_OutputBit16bits =0 THEN
stID40.Module2NX_OD5256OutputDataSet1_OutputBit16bits:=1;
END_IF;
IF fbR_TRIG.Q THEN
stID40.Module2NX_OD5256OutputDataSet1_OutputBit16bits:=
SHL(
stID40.Module2NX_OD5256OutputDataSet1_OutputBit16bits
,1
);
IF iCounter = 0 THEN
stID07.Module27557_012316DO_05ANPNOutputs_Channel1Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel2Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel3Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel4Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel5Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel6Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel7Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel8Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel9Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel10Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel11Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel12Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel13Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel14Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel15Data1:=0;
stID07.Module27557_012316DO_05ANPNOutputs_Channel16Data1:=0;
iCounter:=iCounter+1;
ELSE
stID07.Module27557_012316DO_05ANPNOutputs_Channel1Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel2Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel3Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel4Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel5Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel6Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel7Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel8Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel9Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel10Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel11Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel12Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel13Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel14Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel15Data1:=1;
stID07.Module27557_012316DO_05ANPNOutputs_Channel16Data1:=1;
iCounter:=0;
END_IF;
END_IF;
stID07.Module47557_04614AO_UIStandardOutputs_Channel1Word1:=stID07.Module37557_04414AI_UIStandardInputs_Channel1Word1;
//
dutWago7553_8000_DiagsatatusWord:=fc_wago7553_8000_DiagStatusWord(
EN:=TRUE
,iwData:=stID07.Input_DiagnosticsStatusWord
);
//
dut_wago7557_0461_StatusWord[1]:=fc_wago7557_0461_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel1Status
);
dut_wago7557_0461_StatusWord[2]:=fc_wago7557_0461_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel2Status
);
dut_wago7557_0461_StatusWord[3]:=fc_wago7557_0461_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel3Status
);
dut_wago7557_0461_StatusWord[4]:=fc_wago7557_0461_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel4Status
);
//
dut_wago7557_0441_StatusWord[1]:=fc_wago7557_0441_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel1Status
);
dut_wago7557_0441_StatusWord[2]:=fc_wago7557_0441_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel2Status
);
dut_wago7557_0441_StatusWord[3]:=fc_wago7557_0441_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel3Status
);
dut_wago7557_0441_StatusWord[4]:=fc_wago7557_0441_StatusWord(
EN:=TRUE
,iwData:=stID07.Module47557_04614AO_UIAdvancedInputs_Channel4Status
);
|
|---|
pSDO
pSDOは、MX-F100-ECをEtherCAT MainDevice、WAGO 7553-8000をSubDeviceとして使用し、CoE(CANopen over EtherCAT)のSDO通信によって、WAGOの内部パラメータを読み書きするサンプルプログラムである。
EtherCATのPDO通信は、一定周期で入出力データを交換するために使用する。一方、SDO通信は、機器内部のObject Dictionaryにアクセスし、パラメータや診断情報を個別に読み書きするために使用する非周期通信である。
今回のプログラムでは、WAGOのDevice Typeを読み出す機能と、Diagnosis HistoryのFlagsを変更する機能を実装した。
指令・操作フラグ
Local Label
| 型
| 説明
|
|---|
bReadReq
|
BOOL
|
SDO Read実行要求。FALSE→TRUEで起動
|
|---|
bWriteReq
|
BOOL
|
SDO Write実行要求。FALSE→TRUEで起動
|
|---|
bWritePermit
|
BOOL
|
書込み許可。今回の解説付きコードで追加
|
|---|
bReadPrev
|
BOOL
|
Read要求の前回状態。立上り検出用
|
|---|
bWritePrev
|
BOOL
|
Write要求の前回状態。立上り検出用
|
|---|
bIgnoreInfo
|
BOOL
|
WAGO Bit 1をON/OFF
|
|---|
bIgnoreWarning
|
BOOL
|
WAGO Bit 2をON/OFF
|
|---|
bIgnoreError
|
BOOL
|
WAGO Bit 3をONにする要求
|
|---|
bPermitBit3Change
|
BOOL
|
Bit 3のON操作を個別に許可
|
|---|
完了・異常フラグ
Local Label
| 型
| TRUEになる条件
|
|---|
bReadDone
|
BOOL
|
Device TypeのSDO Read成功
|
|---|
bDownloadAck
|
BOOL
|
SDO Downloadの正常応答を受信
|
|---|
bWriteVerified
|
BOOL
|
再読出しのBit 0~3が書込み要求と一致
|
|---|
bWriteDone
|
BOOL
|
Write検証まで完了
|
|---|
bValueChanged
|
BOOL
|
書込み前後のBit 1~3に変化があった
|
|---|
bSdoError
|
BOOL
|
SDO通信・サイズ判定・検証で異常
|
|---|
bConfigError
|
BOOL
|
書込み許可不足などの操作条件エラー
|
|---|
こちらはFlowです。
今回のプログラムでは、単純にSDOでデータを書き込むだけではなく、書込み前の値を取得し、必要なビットのみ変更して書き込み、最後に再読出しして検証する方式を採用している。
これにより、既存の診断設定をできる限り維持しながら、必要な設定だけを変更できる。また、SDO Downloadの成功と、書込み後に値が一致したことを個別のフラグで確認できるため、異常発生時の切り分けも容易になる。
最終的な目的は、SDO通信が成立することだけではなく、「何を書き込もうとしたか」「正常応答があったか」「書込み後に何が読み出されたか」を記録し、設定変更を検証できるようにすることである。
(*
MX-F EtherCAT SDO Read / Write / Verify
Target: WAGO
Node Address: 7
READ:
0x1000:00 Device Type
READ-MODIFY-WRITE-VERIFY:
0x10F3:05 Diagnosis History Flags
Bit 0: Preserve original value
Bit 1: bIgnoreInfo
Bit 2: bIgnoreWarning
Bit 3: bIgnoreError (permission required)
Bit 4-15: Preserve original value
SDO Read size: 1 or 2 bytes
SDO Write size: Same as Read size
bWriteDone = TRUE only after read-back match
*)
dwTransmitNodeAddress := 7;
CASE uiStep OF
// ============================================
// IDLE
// ============================================
0:
IF bReadReq AND NOT bReadPrev THEN
bReadDone := FALSE;
bSdoError := FALSE;
bConfigError := FALSE;
uiErrorStep := 0;
uiStep := 10;
ELSIF bWriteReq AND NOT bWritePrev THEN
bWriteDone := FALSE;
bWriteVerified := FALSE;
bValueChanged := FALSE;
bDownloadAck := FALSE;
bSdoError := FALSE;
bConfigError := FALSE;
uiErrorStep := 0;
wSdoError := 0;
dwSdoDetail := 0;
dwFlagsReadSize := 0;
dwVerifySize := 0;
uiStep := 20;
END_IF;
// ============================================
// READ Device Type 0x1000:00
// ============================================
10:
IF (MX_EC.uSet_SDOControlCommand_D = 0)
AND
(MX_EC.uSts_SDOExecutedControlCommand_D = 0)
THEN
MX_EC.uSet_SDOTransmitNodeAddress_D :=
dwTransmitNodeAddress;
MX_EC.uSet_SDOTransmitIndexNumber_D :=
16#1000;
MX_EC.uSet_SDOTransmitSubIndexNumber_D := 0;
MX_EC.uSet_SDOControlCommand_D := 1;
uiStep := 11;
END_IF;
11:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 1 THEN
wSdoError :=
MX_EC.uSts_SDOErrorCode_D;
dwSdoDetail :=
MX_EC.udSts_SDODetailErrorCode_D;
IF (wSdoError = 0)
AND
(MX_EC.udSts_SDOReceiveDataSize_D = 4)
THEN
wDeviceTypeLo :=
MX_EC.unSts_SDOReceiveData_D[0];
wDeviceTypeHi :=
MX_EC.unSts_SDOReceiveData_D[1];
bReadDone := TRUE;
uiStep := 12;
ELSE
bSdoError := TRUE;
uiErrorStep := 11;
uiStep := 90;
END_IF;
MX_EC.uSet_SDOControlCommand_D := 0;
END_IF;
12:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 0 THEN
uiStep := 0;
END_IF;
// ============================================
// STEP 20: Read Flags Before Write
// ============================================
20:
IF (MX_EC.uSet_SDOControlCommand_D = 0)
AND
(MX_EC.uSts_SDOExecutedControlCommand_D = 0)
THEN
MX_EC.uSet_SDOTransmitNodeAddress_D :=
dwTransmitNodeAddress;
MX_EC.uSet_SDOTransmitIndexNumber_D :=
16#10F3;
MX_EC.uSet_SDOTransmitSubIndexNumber_D := 5;
MX_EC.uSet_SDOControlCommand_D := 1;
uiStep := 21;
END_IF;
// ============================================
// STEP 21: Create Write Data
// ============================================
21:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 1 THEN
wSdoError :=
MX_EC.uSts_SDOErrorCode_D;
dwSdoDetail :=
MX_EC.udSts_SDODetailErrorCode_D;
dwFlagsReadSize :=
MX_EC.udSts_SDOReceiveDataSize_D;
IF (wSdoError = 0)
AND
((dwFlagsReadSize = 1)
OR (dwFlagsReadSize = 2))
THEN
wFlagsBefore :=
MX_EC.unSts_SDOReceiveData_D[0];
// Clear Bit 1, 2, 3 only
// Preserve all other bits
wFlagsWrite :=
wFlagsBefore AND 16#FFF1;
// Bit 1 – Ignore Information
IF bIgnoreInfo THEN
wFlagsWrite :=
wFlagsWrite OR 16#0002;
END_IF;
// Bit 2 – Ignore Warning
IF bIgnoreWarning THEN
wFlagsWrite :=
wFlagsWrite OR 16#0004;
END_IF;
// Bit 3 – Ignore Error
IF bIgnoreError THEN
wFlagsWrite :=
wFlagsWrite OR 16#0008;
END_IF;
// For 1-byte SDO, limit to 8 bits
IF dwFlagsReadSize = 1 THEN
wFlagsWrite :=
wFlagsWrite AND 16#00FF;
END_IF;
// Bit 3 change protection
IF (((wFlagsBefore XOR wFlagsWrite)
AND 16#0008) <> 0)
AND NOT bPermitBit3Change
THEN
bConfigError := TRUE;
uiErrorStep := 25;
uiStep := 90;
ELSE
uiStep := 22;
END_IF;
ELSE
bSdoError := TRUE;
uiErrorStep := 21;
uiStep := 90;
END_IF;
MX_EC.uSet_SDOControlCommand_D := 0;
END_IF;
// ============================================
// STEP 22: Wait Read Reset
// ============================================
22:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 0 THEN
uiStep := 30;
END_IF;
// ============================================
// STEP 30: SDO Download
// ============================================
30:
IF (MX_EC.uSet_SDOControlCommand_D = 0)
AND
(MX_EC.uSts_SDOExecutedControlCommand_D = 0)
THEN
MX_EC.uSet_SDOTransmitNodeAddress_D :=
dwTransmitNodeAddress;
MX_EC.uSet_SDOTransmitIndexNumber_D :=
16#10F3;
MX_EC.uSet_SDOTransmitSubIndexNumber_D := 5;
// Match actual received object size
MX_EC.udSet_SDOTransmitDataSize_D :=
dwFlagsReadSize;
MX_EC.unSet_SDOTransmitData_D[0] :=
wFlagsWrite;
// SDO Download
MX_EC.uSet_SDOControlCommand_D := 2;
uiStep := 31;
END_IF;
// ============================================
// STEP 31: Check Download ACK
// ============================================
31:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 2 THEN
wSdoError :=
MX_EC.uSts_SDOErrorCode_D;
dwSdoDetail :=
MX_EC.udSts_SDODetailErrorCode_D;
IF wSdoError = 0 THEN
bDownloadAck := TRUE;
uiStep := 32;
ELSE
bSdoError := TRUE;
uiErrorStep := 31;
uiStep := 90;
END_IF;
MX_EC.uSet_SDOControlCommand_D := 0;
END_IF;
// ============================================
// STEP 32: Wait Download Reset
// ============================================
32:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 0 THEN
uiStep := 40;
END_IF;
// ============================================
// STEP 40: Read Back 0x10F3:05
// ============================================
40:
IF (MX_EC.uSet_SDOControlCommand_D = 0)
AND
(MX_EC.uSts_SDOExecutedControlCommand_D = 0)
THEN
MX_EC.uSet_SDOTransmitNodeAddress_D :=
dwTransmitNodeAddress;
MX_EC.uSet_SDOTransmitIndexNumber_D :=
16#10F3;
MX_EC.uSet_SDOTransmitSubIndexNumber_D := 5;
MX_EC.uSet_SDOControlCommand_D := 1;
uiStep := 41;
END_IF;
// ============================================
// STEP 41: Verify Read Back
// ============================================
41:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 1 THEN
wSdoError :=
MX_EC.uSts_SDOErrorCode_D;
dwSdoDetail :=
MX_EC.udSts_SDODetailErrorCode_D;
dwVerifySize :=
MX_EC.udSts_SDOReceiveDataSize_D;
IF (wSdoError = 0)
AND
(dwVerifySize = dwFlagsReadSize)
THEN
wFlagsAfter :=
MX_EC.unSts_SDOReceiveData_D[0];
// Verify Bit 0 to 3
// Bit 4 and 5 may be read-only/status
IF ((wFlagsAfter XOR wFlagsWrite)
AND 16#000F) = 0
THEN
bWriteVerified := TRUE;
bWriteDone := TRUE;
// Detect actual change of Bit 1 to 3
bValueChanged :=
((wFlagsBefore XOR wFlagsAfter)
AND 16#000E) <> 0;
ELSE
bSdoError := TRUE;
uiErrorStep := 41;
END_IF;
ELSE
bSdoError := TRUE;
uiErrorStep := 41;
END_IF;
MX_EC.uSet_SDOControlCommand_D := 0;
uiStep := 42;
END_IF;
// ============================================
// STEP 42: Wait Verify Reset
// ============================================
42:
IF MX_EC.uSts_SDOExecutedControlCommand_D = 0 THEN
uiStep := 0;
END_IF;
// ============================================
// STEP 90: Error Recovery
// ============================================
90:
MX_EC.uSet_SDOControlCommand_D := 0;
IF MX_EC.uSts_SDOExecutedControlCommand_D = 0 THEN
uiStep := 0;
END_IF;
END_CASE;
// ============================================
// Rising Edge Detection
// ============================================
bReadPrev := bReadReq;
bWritePrev := bWriteReq;
|
|---|
CPUと接続する
最後はPCとMXF-EtherCATをUSB-Cで接続します。
ダウンロード
プロジェクトをCPUにダウンロードし、電源を入れ直します。
結果
WAGO 7553-8000 EtherCAT Coupler本体にあるRUNとI/O LED両方も緑点灯になっています。
オムロンのECC203はエラーなく、RUN・TS両方とも緑点灯になっています。
4つのEtherCAT Slaveもステータス=8、つまりOP状態になっています。
次はbReadReqをTRUEにし、SDOメッセージを送信します。
Done!WAGO 7553-8000 EtherCATカプラーからデバイスIDが取得しました。
最後はbWriteReqをTRUEにし、SDOメッセージを送信し、IgnoreInfo FlagをTrueにします。