ツールの作り方 – 通信編/上位リンク(KEYENCE)

今回はKEYENCEの上位リンクを説明します。
※Ethernet通信のみ(上位リンクはAsciiのみ)
※EthernetまたはEthernet/IPユニットのマニュアルに詳細が記載されています

目次

フォーマットの確認

送信データ(PC→PLC)

No項目備考
1イーサネットヘッダ****※1
2IPヘッダ****※1
3TCP/UDPヘッダ****※1
4コマンド“RD”
“WR” など
Ascii文字
付加情報としてデバイスや点数等が必要
5デリミタCR
(0x0D)
CR+LFでも可
PLC側でLFは無視される

※1
マニュアルにヘッダと称して記載されているがユーザ側では無視してOK

受信データ(PLC→PC)

No項目備考
1イーサネットヘッダ****※1
2IPヘッダ****※1
3TCP/UDPヘッダ****※1
4レスポンス****Ascii文字
【正常時】
読出データ または
“OK”
【異常時】
エラーコード
(16進文字列2文字)
5デリミタCR+LF
(0x0D+0x0A)

KYENCEの上位リンクはMCプロトコルやFINSコマンドと異なり他局アクセス不可のためシンプルにコマンドとレスポンスだけの構成となります。

コマンドについて

コマンド

※デバイスの読み書きを抜粋
※MCプロトコルのランダム読出のような機能は無し

機能コマンド備考
データ読出RD1点のみ読出
連続データ読出RDS“RDE”でも可能
データ書込WR1点のみ書込
連続データ書込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文字)
.H16進数(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まで使えます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA

目次