PLCライブラリTc3_IoLinkはIoLinkデバイスとの通信するときに活用できるライブラリで、以下のProfileがSupportしています:
- Common Profile
- Smart Sensor Profile
そのライブラリの中にパラメータの読み書きが可能なファンクションブロックが用意されています。
System requirements
- WinXP, WES, Win7, WES7, WEC7 IPC or CX, (x86, x64, ARM)
- Min. TwinCAT Version:3.1.4024.25
- Min. TwinCAT Level:TC1200 TC3 PLC

Reference Link
Basic
Tc3_IOLINKを使用する前に、Beckhoff TwinCATのAoE画面からIO-LINKデバイスにデータを読み込む方法を紹介します。EL6224をクリックしてください。

AoE-Online Tabを開きます。

IO-Link ProfileのPort Drop-Down ListからPort番号を選択いただけます。
IO-Link ProfileのPort Drop-Down ListからPort番号を選択いただけます。

今回はPort4、Index16のSubIndex0にReadのコマンドを送信しました。
Read-Stringに”Contrinex AG”という文字列が戻ってきました。

今回はPort4、Index16のSubIndex0にReadのコマンドを送信しました。
Read-Stringに”Contrinex AG”という文字列が戻ってきました。

実際各社のIO-LINKデバイスManualを調べれば、Index・SubIndex・各IndexのData Type・Default値を確認できます。

How to check the AMS Net-ID?
EL6224を開いて>AoE-OnlneからNetIdという項目があります。
この数字はAMS Net-IDになります。

Add library
Tc3_IoLinkを追加します。Reference>Add Libraryします。

Tc3_IoLinkを検索しOkでLibraryを追加しましょう。

DUT
今回の記事で使用するDUTを紹介します。
E_IolPort
ポートの番号を指定します。
| Port1 | 1 |
| Port2 | 2 |
| Port3 | 3 |
| Port4 | 4 |
| Port5 | 5 |
| Port6 | 6 |
| Port7 | 7 |
| Port8 | 9 |
E_IolPortError
IO-Link 通信のエラー内容になります。
| NoError | 0 |
| WatchdogDetected | 1 |
| InternalError | 2 |
| InvalidDeviceID | 3 |
| InvalidVendorID | 4 |
| InvalidIOLinkVersion | 5 |
| InvalidFrameCapability | 6 |
| InvalidCycletime | 7 |
| InvalidPdInLength | 8 |
| InvalidPdOutLenght | 9 |
| NoDeviceDetected | 10 |
E_IolPortState
IO Link Portの通信情報になります。
| Disabled | 0 |
| stDigIn | 1 |
| stDigOut | 2 |
| CommunicationOP | 3 |
| CommunicationComstop | 4 |
Function
今回の記事で使用するFunctionを紹介します。
F_IolGetChannelStateTxt
こちらの関数はIO-LINK Portの状態をテキスト形式に変換します。

VAR_INPUT
| Variables | Type | Description |
| nIolChState | USINT | IO-LINK チャンネルの状態値 |
| nPort | E_IolPort | 状態を取得したいIO-LINK のPort番号 |
VAR_OUTPUT
| Variables | Type | Description |
| F_IolGetChannelStateTxt | String(255) | チャンネルの状態をテキスト情報に変換する。 |
F_IolGetPortError
こちらの関数はIO-Link Portのエラー状態を返します。

VAR_INPUT
| Variables | Type | Description |
| nIolChState | USINT | IO-LINK チャンネルの状態値 |
VAR_OUTPUT
| Variables | Type | Description |
| F_IolGetPortError | E_IolPortError | IO Link Portのエラー情報を示します |
F_IolGetPortState
こちらの関数はIO-Link Portの状態を返します。

VAR_INPUT
| Variables | Type | Description |
| nIolChState | USINT | IO-LINK チャンネルの状態値 |
VAR_OUPUT
| Variables | Type | Description |
| E_IoLGetPortState | E_IolPortState | Port状態を示します |
Function Block
今回の記事で使用するFunction Blockを紹介します。
FB_IolRead
こちらのFunction BlockはIO-linkデバイスのパラメータを読み取ります。

VAR_INPUT
| Variable | Type | Description |
| bExecute | BOOL | 立ち上げで実行する |
| sNetid | T-AmsNetid | IO Link MasterのAMS NET-ID |
| nlolPort | E_lolPort | アクセスしたいIO-Link Port番号 |
| nIndex | WORD | アクセスしたいIO-LinkデバイスのIndex |
| nSubindex | BYTE | アクセスしたいIO-LinkデバイスのSubIndex |
| pDSTBuf | PVOID | IoLinkデバイスから読み取ったデータの保存先のMemory Offset |
| cbBufLen | UDINT | IoLinkデバイスから読み取ったデータの保存先のTotol Size |
| tTimeout | TIME | 最大実行時間 |
VAR_OUTPUT
| Variable | Type | Description |
| bBusy | BOOL | True=実行中 |
| bDone | BOOL | True=実行成功 |
| bError | BOOL | True=エラーあり |
| hResult | HRESULT | Function Blockの戻り値 |
| nADSError | E_AdsErr | ADSエラーコード |
| nIolError | E_IolError | IO-Linkエラーコード |
FB_IolWrite
こちらのFunction BlockはIO-linkデバイスのパラメータを書き込みます。

VAR_INPUT
| Variable | Type | Description |
| bExecute | BOOL | 立ち上げで実行する |
| sNetid | T-AmsNetid | IO Link MasterのAMS NET-ID |
| nlolPort | E_lolPort | アクセスしたいIO-Link Port番号 |
| nIndex | WORD | アクセスしたいIO-LinkデバイスのIndex |
| nSubindex | BYTE | アクセスしたいIO-LinkデバイスのSubIndex |
| pSRCBuf | PVOID | IoLinkデバイスに書き込むデータの保存先のMemory Offset |
| cbBufLen | UDINT | IoLinkデバイスに書き込むデータの保存先のTotol Size |
| tTimeout | TIME | 最大実行時間 |
VAR_OUTPUT
| Variable | Type | Description |
| bBusy | BOOL | True=実行中 |
| bDone | BOOL | True=実行成功 |
| bError | BOOL | True=エラーあり |
| hResult | HRESULT | Function Blockの戻り値 |
| nADSError | E_AdsErr | ADSエラーコード |
| nIolError | E_IolError | IO-Linkエラーコード |
Implementation1-F_IolGetChannelStateTxt
F_IolGetChannelStateTxt Functionを使用し、現在Portの状態を取ってみます。
Program
StateCh4 変数は実際EL6224のState変数とLinkさせてください。
| VAR StateCh4 AT %I*:USINT; nPort :E_IolPort:=E_IolPort.Port4; sChannelStateTxt :STRING; END_VAR //F_IolGetChannelStateTxt sChannelStateTxt:=F_IolGetChannelStateTxt( nIolChState:=StateCh4 ,nPort:=nPort ); |
Result
IOLINK デバイスが正常に通信してるとき”Port4 is state CommunicationOP’のテキストが戻ってきます。

ですが、IOLINKデバイスと繋いてるケーブルを抜いたら”Port 4 is state Disabled and has error NoDevice Deteced’というテキストに変わります。

Implementation2-F_IolGetPortError
F_IolGetPortError Functionを使用し、現在Portのエラー状態を取ってみます。
Program
StateCh4 変数は実際EL6224のState変数とLinkさせてください。
| VAR StateCh4 AT %I*:USINT; sPortError :E_IolPortError END_VAR //F_IolGetPortError sPortError:=F_IolGetPortError( nIolChState:=StateCh4 ); |
Result
IOLINK デバイスが正常に通信してるとき”NoErrorOP’が戻ってきます。

ですが、IOLINKデバイスと繋いてるケーブルを抜いたら”NoDevice”に変わります。

Implementation3-F_IolGetPortState
F_IolGetPortState Functionを使用し、現在Portの状態を取ってみます。
Program
StateCh4 変数は実際EL6224のState変数とLinkさせてください。
| VAR StateCh4 AT %I*:USINT; sPortState :STRING; END_VAR //F_IolGetPortState sPortState:=F_IolGetPortState( nIolChState:=StateCh4 ); |
Result
IOLINK デバイスが正常に通信してるとき”CommunicationOPが戻ってきます。

ですが、IOLINKデバイスと繋いてるケーブルを抜いたら”Disabled”に変わります。

Implementation4-FB_IolRead
FB_IolRead Function Blockを使用し、現在Portと繋がってるIOLINKデバイスのIndex16#10、SubIndex 16#0の状態を読んでみます。
Program
| VAR FB_IolRead :FB_IolRead; DSBuffer :STRING(255); nPort :E_IolPort:=E_IolPort.Port4; FB_IolRead_Execute :BOOL; END_VAR //FB_IolRead FB_IolRead.bExecute:=FB_IolRead_Execute; FB_IolRead.sNetId:=’169.254.141.157.2.6′; FB_IolRead.nIolPort:=nPort; FB_IolRead.pDSTBuf:=ADR(DSBuffer); FB_IolRead.cbBufLen:=SIZEOF(DSBuffer); FB_IolRead.nIndex:=16#10; FB_IolRead.nSubindex:=0; FB_IolRead(); |
Result
Done!Contrinexが返ってきました。

Implementation5-FB_IolWrite
FB_IolWrite Function Blockを使用し、現在Portと繋がってるIOLINKデバイスのIndex16#40、SubIndex 16#3の現在値を変更します。
Program
| VAR FB_IolWrite:FB_IolWrite; FB_IolWrite_Execute:BOOL; SensorMode :USINT; nPort :E_IolPort:=E_IolPort.Port4 END_VAR SensorMode:=16#18; SrcBuff:=’Beckhoff’; FB_IolWrite.bExecute:=FB_IolWrite_Execute; FB_IolWrite.sNetId:=’169.254.141.157.2.6′; FB_IolWrite.nIolPort:=nPort; FB_IolWrite.pSRCBuf:=ADR(SensorMode); FB_IolWrite.cbBufLen:=sizeof(SensorMode); FB_IolWrite.nIndex:=16#40; FB_IolWrite.nSubindex:=3; FB_IolWrite(); |
Result
Done!Function Blockはエラーなしで実行に成功しました。

EL6224を開いて、AoE-Online画面から確認してみましょう。

Done!先程書き込んでいた18が確認できました。
