LoginSignup
11
8

More than 1 year has passed since last update.

KEYENCE 上位リンク通信

Last updated at Posted at 2022-03-14

PythonでKEYENCEの上位リンク通信(Ethernet)します

この上位リンク通信はメッセージサービス用の通信コマンドでPC-PLC間で使用してPLCのメモリの値を読み書きできます
ここではpythonを使ってEtherenetで上位リンク通信するクラスを作りました
kvHostLink

環境

PLC対象機種

KV-EP21V
KV-8000(A)
KV-7500
KV-5500
KV-NC1EP

クライアント側環境

python 3.9

対応コマンド

機能 コマンド メソッド
モード変更 Mn mode
エラークリア ER errclr
エラー番号確認 ?E er
機種の問い合わせ ?K unittype
時刻設定 WRT settime
強制セット ST set
強制リセット RS reset
連続強制セット STS sts
連続強制リセット RSS rss
データ読み出し RD read
連続データ読み出し RDS reads
データ書き込み WR write
データ読み出し WRS writes

使い方

上位リンク通信のコマンドとレスポンスはすべて文字列です
レスポンスは文字列で最後にはCR+LFが付きます

オブジェクトの作成

kv = kvHostLink('192.168.0.31')

kvhostlinkクラスは通信相手のPLCのIPアドレスを指定してオブジェクトを作ります

モード変更

data = kv.mode('1')

引数には0か1を入れて動作状態を切り替えます
0: PROGRAMモード
1: RUNモード

エラークリア

data = kv.errclr()

エラー番号確認

data = kv.er()

エラー番号が返ってきます

機種の問い合わせ

data = kv.unittype()

レスポンスは以下の番号が各機種に割り当たっています
KV-8000 :57
KV-8000A :58
KV-7300 :54
KV-7500 :55
KV-3000 :51
KV-5000 :52
KV-5500 :53
KV-NC32T :128
KV-N60□□ :132
KV-N40□□ :133
KV-N24□□ :134

時刻設定

data = kv.settime()

PLCの時刻を送信元の時刻に合わせます

強制セット

data = kv.set('MR0')

引数にはデバイス種別と番号を入力します

デバイス名 種別 番号
リレー R 0-199915
リンクリレー B 0-7FFF
内部補助リレー MR 0-399915
ラッチリレー LR 0-99915
コントロールリレー CR 0-7915
タイマ T 0-3999
カウンタ C 0-3999
高速カウンタコンパレータ CTC 0-3
ワークリレー VB 0-F9FF

※ 番号は機種によってサイズが変わります

強制リセット

data = kv.reset('MR0')

引数にはデバイス種別と番号を入力します

連続強制セット

data = kv.sts('MR10', 5)

引数1はデバイス種別と番号を入力します
引数2はセットする個数を入力します

連続強制リセット

data = kv.rts('MR10', 5)

引数1はデバイス種別と番号を入力します
引数2はリセットする個数を入力します

データ読み出し

data = kv.read('MR0.U')

引数1はデバイス種別と番号とデータ形式を入力します
データ形式は以下で指定します

サフィックス データ形式
.U 10進数16ビット符号なし
.S 10進数16ビット符号あり
.D 10進数32ビット符号なし
.L 10進数16ビット符号あり
.H 16進数16ビット

デバイス種別と番号

デバイス名 種別 番号
リレー R 0-199915
リンクリレー B 0-7FFF
内部補助リレー MR 0-399915
ラッチリレー LR 0-99915
コントロールリレー CR 0-7915
ワークリレー VB 0-F9FF
データメモリ DM 0-65534
拡張データメモリ EM 0-65534
ファイルレジスタ FM 0-32767
ファイルレジスタ ZF 0-524287
リンクレジスタ W 0-7FFF
テンポラリデータメモリ TM 0-511
インデックスレジスタ Z 1-12
タイマ T 0-3999
タイマ(現在値) TC 0-3999
タイマ(設定値) TS 0-3999
カウンタ C 0-3999
カウンタ(現在値) CC 0-3999
カウンタ(設定値) CS 0-3999
デジタルトリマ AT 0-7
コントロールメモリ CM 0-5999
ワークメモリ VM 0-50999

※ 番号は機種によってサイズが変わります

連続データ読み出し

data = kv.reads('MR0.S',4)

引数1はデバイス種別と番号とデータ形式を入力します
引数2は読み出す個数を入力します

データ書き込み

data = kv.write('DM0.U', '2')

引数1はデバイス種別と番号とデータ形式を入力します
引数2は書き込む値を入力します

連続データ書き込み

data = kv.writs('DM1.S', 4, '1 2 3 4')

引数1はデバイス種別と番号とデータ形式を入力します
引数2は書き込む個数を入力します
引数3にスペースで区切って書き込む値を入力します

コード

kvhostlink.py
import time
from socket import *
import struct
import datetime

BUFSIZE = 4096

class kvHostLink:
    addr = ()
    destfins = []
    srcfins = []
    port = 8501
    

    def __init__(self, host):
        self.addr = host, self.port

    def sendrecive(self, command):
        s = socket(AF_INET, SOCK_DGRAM)
        s.bind(('', self.port))
        s.settimeout(2)

        starttime = time.time()

        s.sendto(command, self.addr)
        #print("send:%r" % (command))
        rcvdata = s.recv(BUFSIZE)

        elapsedtime = time.time() - starttime
        #print ('receive: %r\t Length=%r\telapsedtime = %sms' % (rcvdata, len(rcvdata), str(elapsedtime * 1000)))
        #print()
        return rcvdata

    def mode(self, mode):
        senddata = 'M' + mode
        rcv = self.sendrecive((senddata + '\r').encode())
        return rcv

    def unittype(self):
        rcv = self.sendrecive("?k\r".encode())
        return rcv

    def errclr(self):
        senddata = 'ER'
        rcv = self.sendrecive((senddata + '\r').encode())
        return rcv

    def er(self):
        senddata = '?E'
        rcv = self.sendrecive((senddata + '\r').encode())
        return rcv

    def settime(self):
        dt_now = datetime.datetime.now()
        senddata = 'WRT ' + str(dt_now.year)[2:]
        senddata = senddata + ' ' + str(dt_now.month)
        senddata = senddata + ' ' + str(dt_now.day)
        senddata = senddata + ' ' + str(dt_now.hour)
        senddata = senddata + ' ' + str(dt_now.minute)
        senddata = senddata + ' ' + str(dt_now.second)
        senddata = senddata + ' ' + dt_now.strftime('%w')
        rcv = self.sendrecive((senddata + '\r').encode())
        return rcv
        
    def set(self, address):
        rcv = self.sendrecive(('ST ' + address + '\r').encode())
        return rcv

    def reset(self, address):
        rcv = self.sendrecive(('RS ' + address + '\r').encode())
        return rcv

    def sts(self, address, num):
        rcv = self.sendrecive(('STS ' + address + ' ' + str(num) + '\r').encode())
        return rcv

    def rss(self, address, num):
        rcv = self.sendrecive(('RSS ' + address + ' ' + str(num) + '\r').encode())
        return rcv

    def read(self, addresssuffix):
        rcv = self.sendrecive(('RD ' + addresssuffix + '\r').encode())
        return rcv

    def reads(self, addresssuffix, num):
        rcv = self.sendrecive(('RDS ' + addresssuffix + ' ' + str(num) + '\r').encode())
        return rcv

    def write(self, addresssuffix, data):
        rcv = self.sendrecive(('WR ' + addresssuffix + ' ' + data + '\r').encode())
        return rcv

    def writs(self, addresssuffix, num, data):
        rcv = self.sendrecive(('WRS ' + addresssuffix + ' ' + str(num) + ' ' + data + '\r').encode())
        return rcv


kv = kvHostLink('192.168.0.31')
data = kv.mode('1')
print(data)
data = kv.er()
print(data)
data = kv.errclr()
print(data)
data = kv.unittype()
print(data)
data = kv.settime()
print(data)
data = kv.set('MR0')
print(data)
data = kv.reset('MR1')
print(data)
data = kv.sts('MR10', 5)
print(data)
data = kv.rss('MR10', 4)
print(data)
data = kv.read('DM0.U')
print(data)
data = kv.reads('DM0.S', 4)
print(data)
data = kv.write('DM0.U', '2')
print(data)
data = kv.writs('DM1.S', 4, '1 2 3 4')
print(data)

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8