キーエンスSafety ControllerのTutorial第5話です。今回はみなさんがよく使われているSafetyリレーと配線し、Modbus/TCP Serverを立ち上げ、Beckhoff TwinCAT3のTF6250から様々なレジスタにアクセスします。
さ、はじめよう!
Reference Video
こちらは記事の動画Versionになります。
Beckhoff.TF6250でKeyence GC1000とModbus TCP/IP接続チュートリアル
Reference Link
http://soup01.com/ja/category/keyence%e3%82%ad%e3%83%bc%e3%82%a8%e3%83%b3%e3%82%b9/gc-1000/
Implementation
Wiring
プロジェクトを構築する前に、まず配線を簡単に説明します。
Input
こちらはGC1000の入力側配線になります。GC1000から以下の入力信号を取り込んでいます:
- 非常停止
- 安全リレーのNO接点
- 安全リレーのNC接点
- リセットボタン
Output
こちらはGC1000の出力側配線になります。GC1000から以下の入力信号を取り込んでいます:
- 安全リレーのコイル出力
- 安全リレーOFFときのランプ出力
- 安全リレーONときのランプ出力
Keyence Side
今回の記事ではキーエンスGC1000 Safety ControllerのModbus TCP Server機能を使用します。
Specification
こちらはGC1000のModbus TCP Server仕様で、固定のPort502を使って、最大4つのConnectionになります。
Function Code
こちらはキーエンスGC1000 Safety Controllerが対応してるModbus Function Codeです。
Input Register
こちらは今回記事で使用したGC1000 のInput Registerです。
レジスタ100Hから103HまではGC1000のCommunication Inputになります。
Holding Register
こちらは今回記事で使用したGC1000 のHoldingRegisterです。
レジスタ214Hから215HまではGC1000の状態やエラー発生数になります。
レジスタ252Hから255HまではGC1000のCommunication Outputになります。
レジスタ700Hから73FHまでは現在GC1000が実行してるプロジェクト名になります。
Input Configuration
こちらはGC1000の入力構成になります。
- EMS00:非常停止ボタン
- SNO2005_NC_INPUT:安全リレーSNO2005のB接点
- SNO2005_NO_INPUT:安全リレーSNO2005のA接点
- RST000:リセットボタン
Output Configuration
こちらはGC1000の出力構成になります。
- SNO2005_MAIN_COIL:安全リレーSN2005のコイル
- AUX‐SNO2005_OFF:現在安全リレーSNO2005のコイルがOFFしてる状態を示すランプ出力
- AUX-SNO2005_READY:現在安全リレーSNO2005のコイルがONしてる状態を示すランプ出力
- SNO2005_V31:安全リレーSN2005のKMあたりオンコイル
Register Configuration
今回の記事もGC1000の内部レジスタを使用します。
プロジェクトに4つのRegisterがあり、非常停止の状態・安全リレーの状態とModbus のLife bitになります。
Program
プログラムは2ページに分かれております。
Page1
Page1はメインの制御や内部レジスタにデータ出力のプログラムになります。
Page2
Page2はGC1000の状態を通信出力に渡すためのプログラムです。
ModbusTCP/IP Configuration
次はGC1000のModbus TCP/IP設定を行います。
GC ConfiguratorからModbusTCPをEthernet Fieldに追加しましょう。
Done!Modbus TCP/IP Driverが追加されました。
Ethernet Setting
次はEthernetの設定を行うため、Basic Settingをクリックしてください。
EthernetのBasic Setting画面が表示されます。
Transfer communication settingsのCheckboxを入れ、Static IPを選択します。
次はIPアドレスを設定してください。プロジェクトのIP設定をGC1000に転送することになります。
Done!
Beckhoff Side
次はBeckhoff TwinCAT側の実装を説明します。今回はTF6250にあるFB_MBREADREGSとFB_MBWriteRegsのFBを使用しGC1000のレジスタにアクセスします。
Install TF6250
下記のLinkからTF6250のSetup FileをDownloadし、インストールしてください。
Add library
Program
FC_ClearArray
こちらの関数では配列値を0にクリアします。
FUNCTION FC_ClearArray VAR_IN_OUT io:ARRAY[*]OF WORD; END_VAR VAR i:DINT; END_VAR FOR i:=LOWER_BOUND(io,1) TO UPPER_BOUND(io,1) DO io[i]:=16#0; END_FOR |
MAIN
こちらはMAINプログラムです。
PROGRAM MAIN VAR //Function Block _MBRead:FB_MBReadInputRegs; _MBWrite:FB_MBWriteRegs; //Buffer ReadBuffer:ARRAY[0..99]OF WORD; WriteBuffer:ARRAY[0..99]OF WORD; //Data From GC1000 ProjectName :WSTRING; GC1000_Running,GC1000_Normal:BOOL; GC1000_NumberOfError:WORD; EStopTriggered,SNO2005_CoilOFF,SNO2005_CoilON:BOOL; //Command to GC1000 bReset:BOOL; //Program Flow Control iStep:INT; TON1,TON2,TON3:TON; END_VAR aInit();aReadDataFromGC1000();aWriteData2GC1000();aBusyTimeOut(); |
ACTION:aBusyTimeOut
こちらのActionはInput Registerに受信するときのタイムアウト設定になります。
//Busy Timeout TON3(in:=_MBRead.bBusy ); IF TON3.Q THEN iStep:=0; END_IF |
ACTION:aInit
こちらのActionはタイマーの設定値などを初期化します。
TON1.PT:=T#1S; TON2.PT:=T#1S; TON3.PT:=T#5S; TON1(IN:=NOT TON2.Q); TON2(in:=TON1.Q); |
ACTION:aReadDataFromGC1000
こちらのActionはCASE分を使ってGC1000に各Input Registerを読み取ります。
//Read Process CASE iStep OF 0: _MBRead.sIPAddr:=’192.168.5.21′; _MBRead.nTCPPort:=502; _MBRead.nUnitID:=1; _MBRead.cbLength:=SIZEOF(ReadBuffer); _MBRead.pDestAddr:=ADR(ReadBuffer); _MBWrite.sIPAddr:=’192.168.5.21′; _MBWrite.nTCPPort:=502; _MBWrite.nUnitID:=1; _MBWrite.cbLength:=SIZEOF(WriteBuffer); _MBWrite.pSrcAddr:=ADR(WriteBuffer); _MBRead(bExecute:=FALSE); EStopTriggered:=FALSE; SNO2005_CoilOFF:=FALSE; SNO2005_CoilON:=FALSE; ProjectName:=” “; iStep:=10; 10: _MBRead.nMBAddr:=16#252; _MBRead.nQuantity:=4; _MBRead(bExecute:=TRUE); IF _MBRead.cbRead <> 0 OR _MBRead.bError THEN _MBRead(bExecute:=FALSE); IF _MBRead.cbLength <> 0 THEN EStopTriggered:=ReadBuffer[0].0; SNO2005_CoilOFF:=ReadBuffer[0].1; SNO2005_CoilON:=ReadBuffer[0].2; iStep:=20; END_IF; IF _MBRead.bError THEN iStep:=900; END_IF END_IF 20: IF NOT _MBRead.bBusy THEN FC_ClearArray(io:=ReadBuffer); iStep:=30; END_IF 30: _MBRead.nMBAddr:=16#700; _MBRead.nQuantity:=64; _MBRead(bExecute:=TRUE); IF _MBRead.cbRead <> 0 OR _MBRead.bError THEN _MBRead(bExecute:=FALSE); IF _MBRead.cbLength <> 0 THEN MEMMOVE( destAddr:=ADR(ProjectName) ,srcAddr:=ADR(ReadBuffer) ,n:=64*2 ); iStep:=40; END_IF; IF _MBRead.bError THEN iStep:=901; END_IF END_IF 40: IF NOT _MBRead.bBusy THEN FC_ClearArray(io:=ReadBuffer); iStep:=10; END_IF 50: _MBRead.nMBAddr:=16#214; _MBRead.nQuantity:=2; _MBRead(bExecute:=TRUE); IF _MBRead.cbRead <> 0 OR _MBRead.bError THEN _MBRead(bExecute:=FALSE); IF _MBRead.cbLength <> 0 THEN GC1000_Running:=ReadBuffer[0].0; GC1000_Normal:=NOT ReadBuffer[0].1; GC1000_NumberOfError:=ReadBuffer[1]; iStep:=60; END_IF; IF _MBRead.bError THEN iStep:=902; END_IF END_IF 60: IF NOT _MBRead.bBusy THEN FC_ClearArray(io:=ReadBuffer); iStep:=10; END_IF 900,901,902: iStep:=0; END_CASE |
ACTION:aWriteData2GC1000
こちらのActionはリセット信号とハートビートをGC1000のHolding Registerに書き込みます。
WriteBuffer[0].0:=bReset; WriteBuffer[0].1:=TON1.Q; //Write Process //100=Communication Input _MBWrite( nMBAddr:=16#100 ,nQuantity:=4 ,bExecute:=NOT _MBWrite.bBusy ); |
Result
こちらの動画はBeckhoff TwinCAT3がTF6250経由でキーエンスGC1000のレジスタを書き込む操作です。
Keyence.Write GC1000 Register via TwinCAT TF6250 ModbusTCP
こちらの動画はBeckhoff TwinCAT3がTF6250経由でキーエンスGC1000のレジスタを読み込む操作です。