今回はKEYENCEの上位リンクを説明します。
※Ethernet通信のみ(上位リンクはAsciiのみ)
※EthernetまたはEthernet/IPユニットのマニュアルに詳細が記載されています
フォーマットの確認
送信データ(PC→PLC)
No | 項目 | 値 | 備考 |
1 | イーサネットヘッダ | **** | ※1 |
2 | IPヘッダ | **** | ※1 |
3 | TCP/UDPヘッダ | **** | ※1 |
4 | コマンド | “RD” “WR” など | Ascii文字 付加情報としてデバイスや点数等が必要 |
5 | デリミタ | CR (0x0D) | CR+LFでも可 PLC側でLFは無視される |
※1
マニュアルにヘッダと称して記載されているがユーザ側では無視してOK
受信データ(PLC→PC)
No | 項目 | 値 | 備考 |
1 | イーサネットヘッダ | **** | ※1 |
2 | IPヘッダ | **** | ※1 |
3 | TCP/UDPヘッダ | **** | ※1 |
4 | レスポンス | **** | Ascii文字 【正常時】 読出データ または “OK” 【異常時】 エラーコード (16進文字列2文字) |
5 | デリミタ | CR+LF (0x0D+0x0A) |
KYENCEの上位リンクはMCプロトコルやFINSコマンドと異なり他局アクセス不可のためシンプルにコマンドとレスポンスだけの構成となります。
コマンドについて
コマンド
※デバイスの読み書きを抜粋
※MCプロトコルのランダム読出のような機能は無し
機能 | コマンド | 備考 |
データ読出 | RD | 1点のみ読出 |
連続データ読出 | RDS | “RDE”でも可能 |
データ書込 | WR | 1点のみ書込 |
連続データ書込 | WRS |
連続読出/書込についてはデバイス種別毎に1回の交信(送信&受信)における最大点数が異なるので注意が必要です。
デバイス指定
上位リンクはAsciiによる通信なので基本的にはラダーの記述と同様にそのままAscii文字列で指定します。(“R1000″、”B1234″、”DM1000″など)
ただしタイマやカウンタは接点・現在値・設定値の3種類があるので使い分けが必要です。
No | デバイス | 種別 | 備考 |
1 | リレー | R | |
2 | リンクリレー | B | デバイス番号は16進数 |
3 | 内部補助リレー | MR | |
4 | ラッチリレー | LR | |
5 | コントロールリレー | CR | |
6 | ワークリレー | VB | ※2 |
7 | データメモリ | DM | |
8 | 拡張データメモリ | EM | ※3 |
9 | ファイルレジスタ(バンク) | FM | |
10 | ファイルレジスタ(連番) | ZF | |
11 | リンクレジスタ | W | デバイス番号は16進数 |
12 | テンポラリデータメモリ | TM | ※2 |
13 | インデックスレジスタ | Z | ※2 |
14 | タイマ | T | ※4 |
15 | タイマ(現在値) | TC | |
16 | タイマ(設定値) | TS | |
17 | カウンタ | C | ※4 |
18 | カウンタ(現在値) | CC | |
19 | カウンタ(設定値) | CS | |
20 | デジタルトリマ | AT | ※2 |
21 | コントロールメモリ | CM | |
22 | ワークメモリ | VM | ※2 |
※2
MCプロトコルではアクセス不可のデバイス
※3
MCプロトコルでアクセス可だがデバイス番号にオフセットが必要
※4
読出の場合、接点、現在値、設定値の3つが対象
書込の場合は対象が現在値となり接点への書込は不可
データ形式指定
ビットデバイスが対象の場合は形式指定を省略しますが、ワードデバイスの場合はデータ形式を指定する必要があります。
形式指定文字 | データ形式 | サイズ |
.U | 符号無し10進数(16ビット=1ワード) | 5バイト(=5文字) |
.S | 符号付き10進数(16ビット=1ワード) | 6バイト(6文字) |
.D | 符号無し10進数(32ビット=2ワード) | 10バイト(10文字) |
.L | 符号付き10進数(32ビット=2ワード) | 11バイト(11文字) |
.H | 16進数(16ビット=1ワード) | 4バイト(4文字) |
特にこだわりが無ければ.H(16進数)を指定するのがオススメです。
サイズが小さいので通信速度的に(多少なりとも)有利になります。
デバイス読出
例としてDM1000から100点読み出す場合のコードです。
Option Explicit On
Imports System.Net.Sockets
Public Sub ReadSample()
Dim tx() As Byte ' 送信バッファ
Dim cmd As String ' コマンド文字列
Dim idx As Integer ' 送信バッファ アクセスIndex
Dim sentLen As Integer ' 送信Byte数
Dim readLen As Short ' 読出点数
' 送信データ
ReDim tx(8191) ' バッファサイズは適当に。
' コマンドデータ
readLen = 100
cmd = "RDS DM1000.H " & readLen.ToString() & vbCr ' DM1000から16進で100点読出
' Ascii→Byteに変換
For idx = 0 To cmd.Length - 1
tx(idx) = CType(Asc(cmd.Substring(idx, 1)), Byte)
Next
''tx = System.Text.Encoding.ASCII.GetBytes(cmd) ' ←変換はこっちの書き方がスマートかも?
' 送信
' _sockはSocketクラスで既にConnectされているものとする
sentLen = _sock.Send(tx, idx, SocketFlags.None)
Dim rx() As Byte ' 受信バッファ
Dim recvLen As Integer ' 受信Byte数
Dim resLen As Integer ' レスポンスデータ長
Dim errCode As Short ' エラーコード
Dim readData() As Short ' 読出データ(デバイス値)
Dim i As Integer
' 受信
ReDim rx(8191) ' バッファサイズは適当に。
recvLen = _sock.Receive(rx)
' チェック
If recvLen = 4 Then
' エラーコード2文字 + CR + LF
' ChrでByte→Asciiに変換
errCode = Short.Parse(Chr(rx(0)) & Chr(rx(1)), Globalization.NumberStyles.HexNumber)
Return
End If
' デリミタはCR+LFの2文字だが1文字分を引いてデータ数をチェック
' →データはスペース区切りのため1要素で4文字+スペースの5文字と考える
' (最後の要素はスペースの代わりにCRで5文字)
resLen = recvLen - 1
If resLen <> readLen * 5 Then Return ' レスポンスデータ(Byte数)は読出点数×5と一致しないとNG
ReDim readData(readLen - 1)
For i = 0 To readLen - 1 Step 5
' ChrでByte→Asciiに変換
readData(i) = Short.Parse(Chr(rx(i + 0)) & Chr(rx(i + 1)) & Chr(rx(i + 2)) & Chr(rx(i + 3)), Globalization.NumberStyles.HexNumber)
Next
End Sub
注意点は前回(MCプロトコル)とほぼ同じです。
デバイス書込
例としてMR12000をSET(1)する場合のコードです。
Option Explicit On
Imports System.Net.Sockets
Public Sub WriteSample()
Dim tx() As Byte ' 送信バッファ
Dim cmd As String ' コマンド文字列
Dim idx As Integer ' 送信バッファ アクセスIndex
Dim sentLen As Integer ' 送信Byte数
' 送信データ
ReDim tx(8191) ' バッファサイズは適当に。
' コマンドデータ
cmd = "WR MR12000 1" & vbCr ' SET="1", RST="0"
' Ascii→Byteに変換
For idx = 0 To cmd.Length - 1
tx(idx) = CType(Asc(cmd.Substring(idx, 1)), Byte)
Next
''tx = System.Text.Encoding.ASCII.GetBytes(cmd) ' ←変換はこっちの書き方がスマートかも?
' 送信
' _sockはSocketクラスで既にConnectされているものとする
sentLen = _sock.Send(tx, idx, SocketFlags.None)
Dim rx() As Byte ' 受信バッファ
Dim recvLen As Integer ' 受信Byte数
Dim errCode As Short ' エラーコード
' 受信
ReDim rx(8191) ' バッファサイズは適当に。
recvLen = _sock.Receive(rx)
' チェック
If recvLen <> 4 Then Return ' 4Byte以外の受信はそもそもNG。
If Chr(rx(0)) = "O"c AndAlso Chr(rx(1)) = "K"c Then
' 正常終了
Return
Else
' 異常終了
' ChrでByte→Asciiに変換
errCode = Short.Parse(Chr(rx(0)) & Chr(rx(1)), Globalization.NumberStyles.HexNumber)
Return
End If
End Sub
注意点は読出とほぼ同様です。
とりあえずMCプロトコル、FINSコマンド、上位リンク、についてサラッと説明してきましたがPLC用のツールとして通信処理は避けて通れないものなので使用するPLCに合わせたものを作るといろいろ便利になります。
気が向いたらそこそこ使えそうな通信ライブラリを作って公開する、、かもしれません。
PLC側の通信設定
KEYENCEの場合はCPU内蔵Ethernetと単体のEthernetユニットで設定はほぼ同じです。
- 基本 – IPアドレス
任意値を設定します。192.168.***.***あたりを使うパターンが一般的に多いです。 - 基本 – サブネットマスク
通常は255.255.255.0を使います。 - ポート番号 – ポート番号(上位リンク)
初期値(8501)のままでOKです。変更も可能です。 - ポート番号 – MCプロトコルポート番号(TCP)
TCPでMCプロトコルを使う場合に設定します。
初期値(5000)のままでOKです。変更も可能です。 - ポート番号 – MCプロトコルポート番号(UDP)
UDPでMCプロトコルを使う場合に設定します。
初期値(5000)のままでOKです。変更も可能です。 - その他
上位リンクやMCプロトコルを使う上では上記以外の設定は無関係です。
三菱と比較した場合、必要な設定はIPアドレスとポートのみなので簡単です。
通信回線は上位リンクとMCプロトコルを合わせて15まで使えます。
コメント