今回はまたIOLINKの記事になります。前回はProfinetのIO-LINK Masterと繋がりましたが、次はEthernet/IP IO-LINK Masterを試してみます。理論が同じでも、違うのでEthernet/IPとProfinetの仕様問題だけです。注目するのはProfinetであろうかEthernet/IPであろうかIO-LINKデバイスにとって変わりません。IO-LINK Deviceのプログラムをそのまま流用できます。
Configuration
こちらが今回の構成になります。TwinCAT3でTF6281を使用し、Ethernet/IP Scannerを立ち上げ、Molex製のEthernet/IP IO-Link Master TCIEI-888P-DYU と繋がります。一方、TwinCAT3もTF6281のEthernet/IP APIを使ってExplict MessageをAdapterに送信します。
Module-TCIEI-888P-DYU
こちらは今回使用するEthernet/IP IO-Link Masterです。Molex製のTCIEI-888P-DYUです。
Signal Map
モジュールは主に電源部分・信号部分・NETWORK部分の3つに分かれています。
Overview
Wiring
Ui/Uo
こちらは電源の配線図です。
LED
Basic Information
こちらは各LEDの意味です。おおまけに言いますと緑・赤・青い色に分かれています。
赤はアラームの意味で、緑はNormal、そして青い色はIO-LINKの状態を表しています。
I/O Port
こちらは各Portの配線です。
IP setting
RotaryスイッチからIPの設定ができます。Defaultは192.168.1.xですが、そのxはRotaryスイッチの設定により決めます。例えばx100は1、x10は5、x1は3になると、そのデイバスのIpは192.168.1.153になります。
IO Connections
こちらはこのモジュールの最大IO Connection数です。
Exclusive Ownerx1で、Listen OnlyやInput Onlyは最大で7までになります。
Data map
モジュールのデバイスMapです。アプリケーションにより、I/OとStatusだけか、I/O・Status・IO-LINKデータを取得するかを設定できます。
Assmbly #113
こちらは今回の記事で使用するAssmebly#113です。
DIOデータと各Portの32Byte IO-LINK DeviceデータのAssemblyです。
Download EDS
Ethernet/IP通信するにはEDS FileはMustではないが、ImportできるEngineering ToolsならImportしてください。こっちのほうが間違いにくいです。
下記のLINKからHarshIO 600 EtherNet/IP IO-Link Master EDS FileをDownloadします。
TwinCAT
次はTwinCAT3側です。TwinCAT3はFunction TF6281 を使用しEthernet/IP Scannerを立ち上げて、Molex製のTCIEI-888P-DYU Ethernet/IP IO-LINK Masterと接続しリアルタイム通信します。
Reference Link
Point1- Scanner IP Setting
よく忘れる設定ですが、TwinCAT3ではEthernet/IP Scannerもう1つのVirtual IPが必要です。Defaultは0.0.0.0で設定しないと繋がりません。TC3 EIP Scanner>Settings>F800.0>F800.21とF800.22を設定してください。
Point2-Adapter IP Setting
Adapter側のIPも実機に合わせてください。Box 1>右クリック>Change IP Addressで変更できます。
Point3-Network Adapter Setting
実機とTwinCAT3を繋がってるNetworkカードInterfaceもよく設定が抜けます。TC3 EIP Scanner>Adapter>Searchします。
正しいInterfaceを設定しましょう。
Point4-Import EDS File
知ってると思いますが、TC3 EIP Scanner>右クリック>Import EDS FileでDownloadしたEDS Fileを入れ込むことできます。
Point5-Select the Right Device
当たり前の話ですが、間違ってDeviceを選んだら通信できませんので、気をつけましょう。
Point6-Scanner AmsNetID
Append IO Connection
IO Connectionを追加します。Box 1>右クリック>Append IO Connection>LO_PD_32bytesをクリックします。
それはAssembly#113です。
Configuration
次はモジュールの設定を行います。IO-LINK Masterは各Portを普通のIOとして使うか、IO-Link デバイスとして使うかを設定できますね。その設定を紹介します。
先程追加したConnectionをDouble Clickします。
Config InstanceのTabを開くとPortの設定とかはできます。
Example1-Configure port0 as DI
では最初にPort0をDigital Inputとして設定します。
C0 Mode>Valueを選択しSIを選択します。
IN ChannelInput変数をクリックします。
いまはESTOPがリリースしてる状態なので、1になります。
そして緊急停止を押すと、Valueが0になります。
Example2-Configurare Other port as Input
次は別のPortでInputを設定してみてIN ChannelInputの変換をみてみます。
C2 Modeを見つけて、先と同じくSIに設定します。
In ChannelInput変数をクリックします。
Port2がOnになると、Valueが4になります。
つまり、そのValueは1つのChannelの状態をすべてまとめて、Bit0はPort0、Bit1はPort1のようなイメージです。
Example3-Configure port0 as DO
次はPort0をDigital出力として説明します。CO Mode>SOに設定します。
Box1>Connection1>Outputs>OUT DATA CHANNELを開きます。
1を書き込みますとPort1が出力します。
Example4-Configure port0 as IO-LINK
最後のExampleはPort0をIO-LINK Modeに設定します。
Port0のIO-LINKデータはC0 IO-Link PDIN…に確認できます。
このようにRFIDから読み取ったデータが格納されます。
そしてMolexデバイスのIPにChromeなどのBrowserを入力します。
このように各Portやデバイスの状態を確認できます。
C0をクリックしPort0が繋がってるIO-LINK Device情報が取れますね。
Program
Reference Link
こちらのProfinet IO-LINK Masterとほぼ同じプログラムです。注目するのはProfinetであろうかEthernet/IPであろうかIO-LINKデバイスにとって変わりません。
Bouns: Explict Messages
もちろんEthernet/IP IO-Link Masterと通信するだけではつまらないので、BounsとしてはBeckhoff TwinCAT3からExplict messagesをTargetに送信する方法を紹介します。
FB_GET_ATTRIBUTE_SINGLE
こちらのFunction Blockを使用し、TargetにGET_Attribute_Single Servicesを送信します。
VAR_INPUT
Name | Type | Description |
sNetId | T_AmsNetID | TwinCAT EtherNet/Ip ScannerのAMSNetId |
sIPv4Addr | T_IPv4Addr | Target デバイスのIP |
bExecute | BOOL | 立ち上げで実行 |
nClass | WORD | CIP Class番号 |
nInstance | WORD | CIP Service Instance 番号 |
nAttribute | WORD | CIP Service Attribute 番号 |
pDst | POINTER TO BYTE | Copyされる変数のPointerADR関数で取得可能 |
nMaxLen | WORD | pDst 変数の最大SizeSizeOf関数で取得可能 |
nSessionTimeoutMSec | DWORD | Session Timeout、Default=30s |
nCmdTimeoutMSec | DWORD | Command Timeout,Default=7.5s |
bRackComm | BOOL | PLCがCompactLogixならTrue |
nPort | BYTE | CPUのPort番号(TF6281はPort1だけSupport) |
nSlot | BYTE | Slot番号 |
VAR_OUTPUT
bBusy | BOOL | True=実行中、TargeからFeedbackが来たらFalseになります。 |
bError | BOOL | True=Errorあり |
nErrId | UDINT | Error情報 |
nDataLen | WORD | Targetからの返答データサイズ(Bytes) |
FB_CUSTOM_SERVICE
こちらのFunction Blockを使用し、Targetに Servicesを送信します。
VAR_INPUT
Name | Type | Description |
sNetId | T_AmsNetID | TwinCAT EtherNet/Ip ScannerのAMSNetId |
sIPv4Addr | T_IPv4Addr | Target デバイスのIP |
bExecute | BOOL | 立ち上げで実行 |
nServiceCode | BYTE | CIP Service Code |
nClass | WORD | CIP Class番号 |
nInstance | WORD | CIP Service Instance 番号 |
nAttribute | WORD | CIP Service Attribute 番号 |
pDst | POINTER TO BYTE | Copyされる変数のPointerADR関数で取得可能 |
nMaxLen | WORD | pDst 変数の最大SizeSizeOf関数で取得可能 |
nSessionTimeoutMSec | DWORD | Session Timeout、Default=30s |
nCmdTimeoutMSec | DWORD | Command Timeout,Default=7.5s |
bRackComm | BOOL | PLCがCompactLogixならTrue |
nPort | BYTE | CPUのPort番号(TF6281はPort1だけSupport) |
nSlot | BYTE | Slot番号 |
VAR_OUTPUT
bBusy | BOOL | True=実行中、TargeからFeedbackが来たらFalseになります。 |
bError | BOOL | True=Errorあり |
nErrId | UDINT | Error情報 |
nDataLen | WORD | Targetからの返答データサイズ(Bytes) |
Implemention
DUT
DUT_EIP_Object01
こちらはCIP Object 01の構造に沿って定義します。
TYPE DUT_EIP_Object01 : STRUCT VendorID :UINT; DeviceType :UINT; ProductCode :UINT; Revision_Major :USINT; Revision_Minor :USINT; Status :UINT; SerialNumber :UINT; ProductName :STRING(31); State :UINT; ConfigurationConsistencyValue :UINT; HeatbeatInterval:UINT; END_STRUCT END_TYPE |
DUT_EIP_Adapter_State
こちらはTwinCAT のAdapter Statusにそって定義します。
TYPE DUT_EIP_Adapter_State : STRUCT RemoteNodeNoConnection :BOOL; RemoteNodeNotReachable :BOOL; TCPClientInitFailed :BOOL; UDPClientInitFailed :BOOL; ConnectionDisconnected :ARRAY[1..8]OF BOOL; END_STRUCT END_TYPE |
DUT_EIP_DevState
こちらはTwinCAT のEthernet/IP Statusにそって定義します。
TYPE DUT_EIP_DevState : STRUCT LinkError :BOOL; IOResetRequired :BOOL; WatchdogTriggered :BOOL; MasterNoValidIP :BOOL; TCPServerUnable :BOOL; UDPServerUnable :BOOL; Normal :BOOL; Error :BOOL; END_STRUCT END_TYPE |
DUT_Contrinex_RLS_1181_320
こちらは今回使用するIO-LINK Devicesです。Contrinex社製のRFID Readerです。(Reference LinkのCodesys Profinet IO-Link Masterと同じものを使っていますので、Contrinex社製のRFID Readerの説明はあちらのLinkで参考にしてください。)
TYPE DUT_Contrinex_RLS_1181_320 : STRUCT Status :DUT_Contrinex_RLS_1181_320_Byte0Status; UID_LSB :DINT; UID_MSB :DINT; _ :ARRAY[0..6]OF BYTE; END_STRUCT END_TYPE |
DUT_Contrinex_RLS_1181_320_Byte0Status
同じく、Reference LinkのCodesys Profinet IO-Link Masterと同じものを使っていますので、Contrinex社製のRFID Readerの説明はあちらのLinkで参考にしてください。
TYPE DUT_Contrinex_RLS_1181_320_Byte0Status : STRUCT b00NBTag :BIT; //Number of Tags in front of RWM b01NBTag :BIT; //Number of Tags in front of RWM b02NBTag :BIT; //Number of Tags in front of RWM b03NBTag :BIT; //Number of Tags in front of RWM b04ANT :BIT; //0=RF Field OFF b05TAG :BIT; //0=No tag present in front of RWM b06,b07 :BIT; END_STRUCT END_TYPE |
uDUT_Contrinex_RLS_1181_320
同じく、Reference LinkのCodesys Profinet IO-Link Masterと同じものを使っていますので、Contrinex社製のRFID Readerの説明はあちらのLinkで参考にしてください。
TYPE uDUT_Contrinex_RLS_1181_320 : UNION raw:ARRAY[0..31]OF BYTE; Data:DUT_Contrinex_RLS_1181_320; END_UNION END_TYPE |
Function Block
FB_Contrinex_RLS_1181_320
同じく、Reference LinkのCodesys Profinet IO-Link Masterと同じものを使っていますので、Contrinex社製のRFID Readerの説明はあちらのLinkで参考にしてください。
VAR
FUNCTION_BLOCK FB_Contrinex_RLS_1181_320 VAR_INPUT END_VAR VAR_OUTPUT UIDLSB :DINT; UIDMSB :DINT; UID :LINT; TagsInfrontOFRWM :BYTE; TagOnRWM :BOOL; RFFieldON :BOOL; END_VAR VAR Device AT%I* :uDUT_Contrinex_RLS_1181_320; END_VAR |
PROGRAM
UIDLSB:=Device.Data.UID_LSB; UIDMSB:=Device.Data.UID_MSB; UID:=SHL(DINT_TO_LINT(Device.Data.UID_MSB),32); UID:=UID+Device.Data.UID_LSB; TagsInfrontOFRWM.0:=Device.Data.Status.b00NBTag; TagsInfrontOFRWM.1:=Device.Data.Status.b01NBTag; TagsInfrontOFRWM.2:=Device.Data.Status.b02NBTag; TagsInfrontOFRWM.3:=Device.Data.Status.b03NBTag; TagOnRWM:=Device.Data.Status.b05TAG; RFFieldON:=Device.Data.Status.b04ANT; |
Function
FC_Get_Adapter_State
こちらはEthernet IP Scannerの現在状態を取得し返答します。
VAR
FUNCTION FC_Get_Adapter_State : DUT_EIP_Adapter_State VAR_INPUT in:UINT; END_VAR |
PROGRAM
FC_Get_Adapter_State.RemoteNodeNoConnection[1]:=in.1; FC_Get_Adapter_State.RemoteNodeNoConnection[2]:=in.2; FC_Get_Adapter_State.RemoteNodeNoConnection[3]:=in.3; FC_Get_Adapter_State.UDPClientInitFailed:=in.12; FC_Get_Adapter_State.TCPClientInitFailed:=in.13; FC_Get_Adapter_State.RemoteNodeNotReachable:=in.14; FC_Get_Adapter_State.RemoteNodeNoConnection:=in.15; |
FC_Get_DevState
こちらは各Adapterの現在状態を取得し返答します。
VAR
FUNCTION FC_Get_DevState : DUT_EIP_DevState VAR_INPUT in :UINT; END_VAR |
PROGRAM
FC_Get_DevState.Normal:=in =0; FC_Get_DevState.Error:=in<>0; FC_Get_DevState.LinkError:=in.0; FC_Get_DevState.IOResetRequired:=in.4; FC_Get_DevState.WatchdogTriggered:=in.5; FC_Get_DevState.UDPServerUnable:=in.12; FC_Get_DevState.TCPServerUnable:=in.13; FC_Get_DevState.MasterNoValidIP:=in.14; |
MAIN
プログラムは難しいところなく、RWM()はCodesysの参考例とほぼ一緒にで、そしてBeckhoff TwinCAT3のEthernet/IP APIを使用しGet_Attribute_SingleとGet_Attribute_All Service MessageをAdapterに送信します。
VAR
PROGRAM MAIN VAR //IO-Link Devices RWM1 :FB_Contrinex_RLS_1181_320; //Get Attribute Signle Get_Attribute_Single:FB_GET_ATTRIBUTE_SINGLE; bExecute_Get_Attribute_Single :BOOL; RawData_GetAttribute_Signle:ARRAY[0..255]OF BYTE; ProductName :STRING(31); R_TRIG_Get_Attribute_Single:R_TRIG; //Get Attribute All RawData_GetAttribute_All :ARRAY[0..255]OF BYTE; R_TRIG_Get_Attribute_All :R_TRIG; bExecute_Get_Attribute_All :BOOL; Custom_Service:FB_CUSTOM_SERVICE; SourceOffset :UINT; NumberOfBytes :UINT; Object01 :DUT_EIP_Object01; //Configuration sIPv4Addr :T_IPv4Addr; sNetId :T_AmsNetID; END_VAR |
PROGRAM
//IO Link Devices RWM1(); //Explict Message sIPv4Addr:=’192.168.1.11′; sNetId:=’192.168.1.18.2.1′; //Example1, Get Attribute Single R_TRIG_Get_Attribute_Single( CLK:=bExecute_Get_Attribute_Single ); IF R_TRIG_Get_Attribute_Single.Q THEN MEMSET( ADR(RawData_GetAttribute_Signle) ,16#0 ,SIZEOF(RawData_GetAttribute_Signle) ); END_IF Get_Attribute_Single( sIPv4Addr:=sIPv4Addr ,sNetId:=’192.168.1.18.2.1′ ,bExecute:=bExecute_Get_Attribute_Single ,nClass:=1 ,nInstance:=1 ,nAttribute:=7 ,pDst:=ADR(RawData_GetAttribute_Signle) ,nMaxLen:=SIZEOF(RawData_GetAttribute_Signle) ); IF NOT Get_Attribute_Single.bBusy AND bExecute_Get_Attribute_Single THEN MEMMOVE( destAddr:=ADR(ProductName) ,srcAddr:=ADR(RawData_GetAttribute_Signle) ,n:=Get_Attribute_Single.nDataLen ); bExecute_Get_Attribute_Single:=FALSE; END_IF //Example2, Get Attribute All R_TRIG_Get_Attribute_All( CLK:=bExecute_Get_Attribute_Single ); IF R_TRIG_Get_Attribute_All.Q THEN MEMSET( ADR(RawData_GetAttribute_All) ,16#0 ,SIZEOF(RawData_GetAttribute_All) ); END_IF Custom_Service( sNetId:=sNetId ,sIPv4Addr:=sIPv4Addr ,nClass:=1 ,nInstance:=1 ,nAttribute:=1 //can not be zero ,nServiceCode:=16#1 ,pSrc:=0 ,nMaxLen:=SIZEOF(RawData_GetAttribute_All) ,bExecute:=bExecute_Get_Attribute_All ,pDst:=ADR(RawData_GetAttribute_All) ); IF NOT Custom_Service.bBusy AND bExecute_Get_Attribute_All THEN //The first 14 Bytes MEMMOVE( ADR(Object01) ,ADR(RawData_GetAttribute_All) ,TO_UINT(14) ); MemMove( ADR(Object01.ProductName) ,ADR(RawData_GetAttribute_All[15]) ,TO_UINT(RawData_GetAttribute_All[14]) ); //13=Frame Bytes size before Product Name //+1 is mean the Data[14] is the data leneght of Product Name, but not include this byte SourceOffset:=13+RawData_GetAttribute_All[14]+1; NumberOfBytes:=Custom_Service.nDataLen-SourceOffset; MemMove( ADR(Object01.State) ,ADR(RawData_GetAttribute_All[SourceOffset]) ,TO_UINT(NumberOfBytes) ); bExecute_Get_Attribute_All:=FALSE; END_IF; |
ASSIGN
もちろん、IO割付けは忘れずに!右クリック>Change Linkします。
選択した変数のByte数と同じ変数があれば、直接割付けできます。
それがTwinCATの便利なところです…!
RESULT
こちらはExplict Messageを使用しObject0x01 Product NameのAttribute を取得します。
こちらはExpを使用し、Get_Attribute_All MessageをAdapterに送信します。