今回はBeckhoffのEL6751を使用し続け、Schneider社のATV320から基本的な制御はもちろん、入力端子台やSTO状態も取り込めるように説明します。
記事の中にATV320の設定も書いていますが、注目するのは Open-Closed Principle (OCP) のコンセプト説明です。(前回のTwinCATをライブラリ化して今回流用する形になります)
さ、始めましょう。
Reference Link
Implementation
ATV320 Side
Configuration
rNA3
rNA3Menuを開き、Defaultは空きですが、今回は3BDA(STOS、STO状態)に設定します。STOSはINT (Signed16)で、0=正常(IDLE)、1=STOトリガー中(STO)、2=Fault(FLT)になります。
rNA4
rNA4Menuを開き、Defaultは空きですが、今回は1452(IL1R)に設定します。IL1RはINT (Signed16)でATV320内蔵してる入力点状態になります。
nCA3
nCA3Menuを開き、Defaultは空きですが、今回は145C(OL1R)に設定します。OL1RはINT (Signed16)でATV320内蔵してる出力点を制御できます。
TwinCAT Side
Download the Library
Githubから前回記事がライブラリ化されたものをDownloadしてください。
https://github.com/soup01Threes/TwinCAT3/blob/main/ATV320_EL6751.library
Import Library
前回の記事で作ったFunction BlockをLibraryしましたので、下記のLinkからDownloadしてください。
次はTwinCAT>PLC>PLC プロジェクト>Referenceをクリックします。
TwinCAT ライブラリ使用についてもっと知りたい方:
Add libraryをクリックします。
Advanced..ボタンクリックします。
Library Repository…をクリックします。
Install..で外部ライブラリをインストールします。
先程Downloadした.library fileを選び>Openします。
Done!いまは0.0.0.2になっていて、Closeで進みます。
最後はATV320のライブラリを選択してOKすればライブラリの導入が完成です。
ATV320,0.0.0.2(threesSoup01)が出てきました。
Program
次はLibraryのFunction BlockをExtendして、今回の記事にATV320の追加信号を取り込めるように改造します。それはプログラムの”Open-closed Principle (OCP) ”という手法に関連しています。
Open-closed Principle (OCP)?
Open-Closed Principle (OCP) を簡単に言いますと、モジュールは自分のアプリケーションに応じて拡張するのは問題なく(Open)、モジュール自体を修正するのはやめてね(Closed)のことです。
モジュールの機能が拡張OK、つまりそのモジュールはOpenしてるんですね。そのOpen状態、将来機能追加や仕様変更によって違う動作をする必要があるかもしれません。
モジュール開発者が将来どのように拡張されるかは予想できません、予想する必要もありません。なので、モジュールの柔軟性のため”Open”することが求められます。
逆に、モジュールのソースコードを修正することが許されないこと”Close”と言います。
ソースコードが頻繁に修正されると、モジュールに依存しているほかのモジュールはその度に更新や動作の再確認が求められます。なので、ソフトウェアが安定するためには、修正に対して閉じていることが必要になります。
Function BlockもそのOpen/Close原則に基づき、拡張のためにOPENであるべきだが、変更のためにはCLOSEであるべきである。
拡張機能の実装は、既存のコードを変更するのではなく、コードを追加することによってのみ達成されるべきです。例えば今回の記事では新しいファンクションブロックは、既存のファンクションブロックから継承され、ATV320のSTO状態や入力端子状態を取り込めるようになります。なので、既存のファンクションブロックを変更することなく、新しい機能を追加することができます。
DUT
DUT_ATV320_HMI_NW3_4_PL
こちらのDUTはHMIからATV320入力端子とSTOの状態を表示する変数です。
TYPE DUT_ATV320_HMI_NW3_4_PL: STRUCT DIs :ARRAY[1..6]OF BOOL; STO :BOOL; END_STRUCT END_TYPE |
Function Block
次はFunction Blockです。
FB_ATV320_NW3_4
先程話していたOpen-closed 原則から新しいFunction BlockをFB_ATV320_Basic_withHMIから拡張していきます。
FUNCTION_BLOCK FB_ATV320_NW3_4 EXTENDS FB_ATV320_Basic_withHMI VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR NW3,NW4 AT %I*:UINT; NC3 AT %Q*:UINT; _HMI_NW3_4 :DUT_ATV320_HMI_NW3_4_PL; STO_Triggered :BOOL; END_VAR METH_GetInputStatus METHOD PUBLIC METH_GetInputStatus : BOOL VAR_INPUT iNumbers :UINT; END_VAR |
METH_GetInputStatus
リクエストされたiNumbersの値によって入力端子台の状態を返します。
METH_GetInputStatus:=FALSE; CASE iNumbers OF 1: METH_GetInputStatus:=NW4.0; 2: METH_GetInputStatus:=NW4.1; 3: METH_GetInputStatus:=NW4.2; 4: METH_GetInputStatus:=NW4.3; 5: METH_GetInputStatus:=NW4.4; 6: METH_GetInputStatus:=NW4.5; END_CASE |
METH_GetSTO
STOの状態を取得します。
METHOD PUBLIC METH_GetSTO : BOOL METH_GetSTO:=NW3 = 1; |
METH_HMIUpdate
最後は親Function BlockのMETH_HMIUpdate()をOverwriteします。(入力端子台とSTO状態という新しい表示項目が増えたので)
METHOD PUBLIC METH_HMIUpdate : BOOL _HMI_NW3_4.DIs[1]:=METH_GetInputStatus(1); _HMI_NW3_4.DIs[2]:=METH_GetInputStatus(2); _HMI_NW3_4.DIs[3]:=METH_GetInputStatus(3); _HMI_NW3_4.DIs[4]:=METH_GetInputStatus(4); _HMI_NW3_4.DIs[5]:=METH_GetInputStatus(5); _HMI_NW3_4.DIs[6]:=METH_GetInputStatus(6); _HMI_NW3_4.STO:=METH_GetSTO(); METH_CmdFaultReset(iTrigger:=_HMI.PB.bReset); METH_SwitchOn(iTrigger:=_HMI.PB.bSwitchON AND NOT METH_GetSTO()); METH_DriveRun( iTrigger:=Prop_OperationState = e_ATV320_OperationState.OperationEnabled ,iSetPoint:=_HMI.PB.iSetPoint ); METH_CmdDisableOperation(iTrigger:=_HMI.PB.bDisableOperation); METH_CmdDisableVoltage(iTrigger:=_HMI.PB.bDisableVoltage); METH_CmdQuickStop(iTrigger:=_HMI.PB.bQuickStop); METH_CmdShutDown(iTrigger:=_HMI.PB.bShutdown); _HMI.PL.rCurrentHz:=METH_RPM2Hz(iData:=NW2); _HMI.PL.rCurrentRPM:=NW2; _HMI.PL.State:=Prop_OperationState; |
MAIN
最後は先ほど実装したMethodを呼び出すだけです。
PROGRAM MAIN VAR ATV320_1:FB_ATV320_NW3_4; ins :ARRAY[1..6]OF BOOL; sto :BOOL; END_VAR ATV320_1.Prop_MaxRPM:=1500; ATV320_1.Prop_MaxHz:=50; ATV320_1.METH_HMIUpdate(); ins[1]:=ATV320_1.METH_GetInputStatus(1); ins[2]:=ATV320_1.METH_GetInputStatus(2); ins[3]:=ATV320_1.METH_GetInputStatus(3); ins[4]:=ATV320_1.METH_GetInputStatus(4); ins[5]:=ATV320_1.METH_GetInputStatus(5); ins[6]:=ATV320_1.METH_GetInputStatus(6); sto:=ATV320_1.METH_GetSTO(); |
Visualization
実はTwinCATのLibarayではプログラムだけではなく画面も一緒にライブラリ化することが可能です。
新しい画面を作成し、ライブラリの画面を使用しながら必要なITEMを追加します。
VAR_IN_OUT _hmis_Basic:DUT_ATV320_Basic_HMI; _hmis_NW3_NW4 :DUT_ATV320_HMI_NW3_4_PL; END_VAR |
簡単な画面になりますが、端子台とSTOの状態が追加されました。
Link
もちろん、変数をNM3・NM4に紐づけするのは忘れずに!
Result
DI3・DI4はSTOの設定として使用されていますので、いま両方ともTRUEが入っていて、ATV320も出力してますね。
STOと接続している緊急停止ボタンを押すとSTOがTrue、DI3・DI4がFalseになります。
Download
こちらのLinkからプロジェクトをDownloadしてください。
https://github.com/soup01Threes/TwinCAT3/blob/main/Project_EL6751_ATV320_CANOPEN_Part2.tnzip