今回はIO-LINK MasterとCodesys Runtimeの構築例を紹介します。よろしくおねがいします。
IOLINK?
まずIOLINKとはなんなのか簡単に説明したいと思います。よく聞かれたのはIO-LINKはProfinetやEtherCATなどと同じFieldbusではないか?と。実は違います。
IO-LINKはFieldbusではなくPoint-to-Pointの通信プロトコルです。
Sensorと通信するProtocolだということをまず頭の隅でおいておきましょう。
下図のようにIO-LINKはIO-LINK MasterとIO-Link Devicesが必要です。
IO−Link Masterは他のIO-Link DevicesとIO-LINK Protocolで通信する一方、一般的にProfinet・ModbusなどのFieldbusのSlaveと通信し必要な情報を上位Controllerとやりとりします。

IO-LINKの特徴はPoint-to-Point Communicationだけではなく一般のSensorケーブルを使用します。そして必要に応じIO-LINKとして使うか普通の入出力として使うかを選べばよいのです。その標準的な4芯ケーブルを使用することで、最大20メートルまでになります。
つまり、いまのシステムにある配線とはわかりません。増えたのはIO-LINK Masterだけです。IO-LINKデータでは4-20mAのようなアナログ値ではなくSensorの現在値を直接みます。

こちらは一般的なアナログ入力付きのFlow Meterです。このように、まずFlow Meterは流量をアナログからデジタルに変換し>さらに4-20mAにScalingします。そしてPLCのアナログ入力として使用し、プログラム内部で必要なEngineering Unitに変換する。変換は最低限でも3回はありますね。

その一方、IO-LINK ではFlow Meterは流量をアナログからデジタルに変換しそのままIO-LINK Masterに渡し、最後はField bus経由でPLCに送信しますね。PLCでもらうデータは4-20mAではなく、意味があるデジタル値です。

時代とともにSensorも進化し内部にマイクロプロセッサがあり、Firmware走っているものが多いのです。IO-LINK使用することによってやりとりできる情報量も従来の現在値から、
- デバイス状態
- エラーコード
- パラメータ
などなどになります。

こちらはよくあるIO-LINKが含まれているシステムです。一般的なFieldbus Networkとあまり変わりません。Sensorもいまのまま通りインストールだけで、延長としてSensorから多くの情報を貰えるようになります。

Sensorからもらえる情報量の話ですが、従来のシステムでは4本線がありSensorの電源2本以外に信号ケーブルもついてますね。SensorのInput/Outputは大体メーカーが決められています。例えばSignal1はError、Signal2はリセットのようなMappingです。
時代と共に進化しSensorのSignal種類が選べるようになりました。でも結局取れるSignalは2つだけです。最後は設計者によりSignalの優先度から使うSignalを決めることになります。

IO-LINKの場合は3種類のデータがもらえます。下図のようにCyclic Data/Acylic Data/Event Dataがありますね。
- Cyclic Data(周期)
周期でやりとりするデータ部。もしFlow Meterの場合だと、たとえば:- Scaled済みのFlow値
- Scaled済みの温度
- Counter
- などなど…
- Acylic Data(非周期)
Sensorの内部メモリ部。- Series Number
- Simulate Mode
- 設定値
- などなど…
- Event Data
- Sensorの付加診断情報
- 履歴
- などなど…
Configuration
こちらは今回のTutorial構成です。CodesysがインストールされてるRaspberry PI3がProfinet Controllerを立ち上げ、Molex製のTCIEP-888P-D1U Profinet IO LINK MasterとProfinet Network立ち上げ、Normal Inputの緊急停止とContrinex 社製のIO LINK RFID Sensorと連動します。

Install GSD
Molex社のTCIEP-888P-D1UはProfinet仕様なのでCodesysにそのデバイスのGSDMLをインストールします。
Tools>Device Repository..をクリックします。
Installボタンをクリックします。
GSDML Fileを選択しOpenします。
TCIEP-888P-D1UをCodesys IDEにインストールしました。
Network Configuration
次はネットワーク構成を設定します。Ethernet Adapter>PN Controller追加>PN Devices追加>設定の流れになります。
Add Ethernet Adapter
Deviceのところを右クリック>Add Deviceします。
Ethernet Adapter>Ethernetを選択>Add Deviceで追加。
Add PN Controller
次はProfinet IO>Profinet IO Master>PN-Controllerを追加します。
Add PN Devices
さらにProfinet IO Device>I/O>HarshIO 600 IOLでモジュールを追加します。
それでネットワーク構成が完成しました。
Set Ethernet Adapter IP
Ethernet AdapterのNetwork Interface設定します。
Gernal>Browseします。
適切のNetwork Interfaceを選び>OKします。
Set PN Controller IP
PN ControllerのIPを設定します。
General>Station name設定します。
Default Slave IP Parameterはネットワーク内で収めるように変更してください。
192.168.1.xのネットワークになります。
Set PN Devices IP/Device Name
ProfinetではDevice Nameはすごく大事です。PN ControllerはDevice Nameに沿ってIPを振ります。
General Tabを開きます。
Station name、IP Parameterを設定し、Watchdogは場合により調整してください。
Assgin Device Name
Codesys IDEからPN DeviceのDevice Nameを設定します。
まずいまのProjectを一回Downloadし、CodesysのProfinet StackをRaspberry Codesys RuntimeにDownloadします。
PN Controllerを右クリック>Scan for Devicesします。
Scan Devicesをクリックします。
いまネットワーク内つながっている機器が一覧できます。
TCIEP-888P-D1UのPN DeviceでStation NameのInput FieldからCodesys Projectで設定したDevice Nameを入れます。
Set name and IPをクリックします。
もう一回Scan Deviceすると、TCIEP-888P-D1UはIP AddressもPN Controllerから振られたことがわかります。
Codesys RuntimeをRunかけると緑のICONがあり、Profinet通信してることがわかります。
Plug A Normal Input
では最初TCIEP-888P-D1UにNormal入力を繋がります。これはIOLINKのその1つ特徴ですね。IO-Link デバイスと普通の入力でも同じIO LINK Masterでも使用できます。
Add Slot
そのInputをTCIEP-888P-D1UのPort1と接続します。
1つ目の<Empty>を右クリック>Plug Deviceします。
Normal InputなのでDigital Input(SIO)>Plug Deviceします。
それでPort1にNormal Inputだと設定しました。
Project をDownloadし、緑ICONを表示すれば問題ありません。
How to view
ではそのNormal Input状態のMonitor方法を表示します。
Digital_Input_Output_DIOをクリックします。
Channel Inputで各Portの状態が反映します。
Result
TCIEP-888P-D1UののPort1がいま緑色ですね。これはPort1がNormal Inputとして使われるときの表示です。
実際の動作は以下になります。
https://youtube.com/shorts/S3koWvoSMto
Normal InputがTrueになるとChannel Inputは256になります。
つまり8Bit目ですね。
Plug A IO Link Devices
Normal Inputが接続に成功したところで次はCONTRINEX 社のHF RFID SYSTEM
READ/WRITE MODULES (RWM) RLS-1181-320と接続します。
IOLink Sensorは各社によりProcess Dataのサイズ、Device MapはManual確認してください。
Characters
Manualによりますと、Process data inは9 Bytes、そしてOutは10Bytesですね。
Process Data Input
そして9BytesのInputデータで、最初の0Byte目はStatusで、1-4Byte目はUIDのLSB、5-8Byte目はUIDのMSBです。
Add Slot
そのIOLink Sensorの仕様もわかりましたので、Port4に接続します。
なので4番目のSlot、いまの<Empty> SlotでPlug Device。
IO-Link In/Out 16/16>Plug Devicesします。ManualによりますとProcess data inは9 Bytes Out 10Bytesでとりあえず SlotのData SizeはProcess dataより大きいであればOKです。
これでOKです。
Rename
Port4をわかりやすい名前に変更しましょう。
とりあえずRLS_1881_320がわかるような名前になります。
If not connect..
もしIO-LINK Sensorが接続してない場合、ICONは赤い三角になります。
if connect
逆にIO-LINK Sensorと接続してるならICONが緑になります。
Result
Molex製のTCIEP-888P-D1UがIO-LINK Sensorと接続成功するとLEDが青い色になります。
https://youtube.com/shorts/YPqHhiZXsV4
Try it!
では実際そのRFID ReaderをRFIDを読んでみましょう。
Codesys IDEからみると配列が数字が格納されていますね。
https://youtube.com/shorts/5y94qavdYIg
Implementation
動作確認OKでしたら次はプログラムを作成しましょう。
DUT_Contrinex_RLS_1181_320_Byte0Status
こちらのDUTはByte0の各Bitを定義します。
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 |
DUT_Contrinex_RLS_1181_320
そしてByte1-8のUIDと一緒に定義ます。
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 |
uDUT_Contrinex_RLS_1181_320
最後はUNION 構造体を定義します。Byte配列はProcess Inputに割り付けます。
TYPE uDUT_Contrinex_RLS_1181_320 : UNION raw:ARRAY[0..15]OF BYTE; Data:DUT_Contrinex_RLS_1181_320; END_UNION END_TYPE |
FB_Contrinex_RLS_1181_320
DUTは定義終わりで、次はFunction Blockを作成します。
VAR
変数DeviceはuDUT_Contrinex_RLS_1181_320として定義します。そのやり方はRFID Readerの数を増やしてもFunction Block のInstance にあるDeviceを直接割り付ければよいのです。他にDeviceのデータをStatus/UIDを Encodeし出力します。
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 :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; |
Assign
もちろん割付けも忘れずに。
Test
テスト1はRFID Tagを読みます。
Test2
テスト1は別のRFID Tagを読みます。
Test3
最後は3枚のRFID Tagを重ねて読むとTagsInfrontOfRWMは3になりますね。
Sample Code
https://github.com/soup01Threes/Codesys/blob/main/Codesys_IOLINK_Pi3.projectarchive