LoginSignup
9
3

More than 1 year has passed since last update.

OMRON FINSコマンドをPythonで送信する

Last updated at Posted at 2022-02-21

OMRONの通信プロトコルのFINSコマンドをpythonで送る

FINSコマンドはメッセージサービス用の通信コマンドでPC-PLC間やPLC-デバイス間で使用されています
pythonを使ってEtherenetでPLCとメッセージ通信するクラスを作りました

環境

Windows10
python3.9
PLC OMRON CJ/NJ/NX series

ファンクション一覧

メソッド名 内容
read メモリエリアの読み出し
write メモリエリアへ書き込み
fill メモリエリアの一括書き込み
run 動作モード切り替え
stop プログラムモードに切り替え
ReadUnitData CPUユニット情報の読出し
ReadUnitStatus CPUユニットステータスの読出し
ReadCycletime サイクルタイム読出し
Clock 時間情報の読出し
SetClock 時間情報の書込み
ErrorClear 異常解除
ErrorLogRead 異常履歴の読出し
ErrorLogClear 異常履歴のクリア
SendCommand その他のFINSコマンドを送信

使い方

インスタンスの作成 fins(IPAddress, 相手FinsAddress, 自分FinsAddress)

finsudp = fins('192.168.250.1', '0.1.0', '0.10.0')

finsクラスは通信相手のIPアドレス, 相手のFINSアドレス, 自分のFINSアドレスを指定してオブジェクトを作ります
FINSアドレスを省略すると相手のIPアドレスの下1桁の数値をノードとして相手先FINSアドレスとします

finsクラスは通信相手のIPアドレスと相手と自分のFINSアドレスを指定してインスタンスを作ります
FINSアドレスとは 「FINSネットワークアドレス . ノードアドレス . 号機アドレス」の3つの数字を . (ドット)でつなぎます
ネットワークアドレスは直接接続することを想定して 0 (自ネットワーク)にしています
ノードアドレスはIPアドレスの一番下の数値と合わせて受信側(PLC)は 1 を、送信元(PC)はIPアドレスは192.168.250.10としているので 10 としています
号機アドレスは 0 (CPU宛て)とします

read(address, num)

# E0_30000から10CH読出し
data = finsudp.read('E0_30000', 10)

上で作ったオブジェクトのreadメソッドでアドレスとCH数を指定して値を読み出します
アドレスはCIOは000、DMはD0、EMはE0_0、WRはW0のように指定します
読み出したデータはバイト列(bytes)で受け取ります

write(address, data)

# E0_0からdataを書込み
rcv = finsudp.write('E0_0', data)

writeメソッドでアドレスと書き込みデータを渡して書き込みます
書き込みデータdataはバイト列(bytes)で渡します

fill(address, num, data)

# D110から10CH分(D110-119)に55を書込み
rcv = finsudp.fill('D110', 10, 55)

連続したメモリエリアに同一のデータを書き込みます

run(mode)

# 動作モード切り替え (0x02=Monitor 0x04=Run)
rcv = finsudp.run(0x02)

stop()

# プログラムモードに切り替え
rcv = finsudp.stop()

ReadUnitData()

# CPUユニット情報の読出し
rcv = finsudp.ReadUnitData()

レスポンス内容

byte数 4 20 20 40 12
内容 05 01 00 00 CPUユニットの形式 システムバージョン システム情報 エリア情報

ReadUnitStatus()

# CPUユニットステータスの読出し
rcv = finsudp.ReadUnitStatus()

レスポンス内容

byte数 4 1 1 2 2 2 2 16
内容 06 01 00 00 運転状態 動作モード 運転停止異常情報 運転継続異常情報 メッセージ有無 故障コード 異常メッセージ

ReadCycletime()

# サイクルタイム読出し
rcv = finsudp.ReadCycletime()

レスポンス内容

byte数 4 4 4 4
内容 06 20 00 00 平均 最大 最小

Clock()

# 時間情報の読出し
rcv = finsudp.Clock()

レスポンス内容

byte数 4 1 1 1 1 1 1 1
内容 07 01 00 00 曜日

SetClock(datetime)

# 時間情報の書込み(PCの時間を書込み)
rcv = finsudp.SetClock(datetime.now())

ErrorClear()

# 異常解除
rcv = finsudp.ErrorClear()

発生中の異常を解除

ErrorLogRead()

# 異常履歴の読出し 最新10件
rcv = finsudp.ErrorLogRead()

レスポンス内容

byte数 4 2 2 2 10 ... 10
内容 21 02 00 00 レコード最大数 格納数 読出しレコード数 異常履歴データ ... 異常履歴データ

ErrorLogClear()

# 異常履歴のクリア
rcv = finsudp.ErrorLogClear()

SendCommand()

cmd = bytearray([0x05,0x01])
rcv = finsudp.SendCommand(cmd)

FINSコマンドを直接送信するメソッドです

データ変換

print (finsudp.toInt16(data))

受け取ったデータのバイト列(bytes)を変換するためのメソッド
バイト列のデータがどのようなデータかによってメソッドが変わります

メソッド名 変換するデータの長さ
toInt16 16bit数値
toUInt16 16bit符号なし
toInt32 32bit数値
toUInt32 32bit符号なし
toInt64 64bit数値
toUInt64 64bit符号なし
toFloat 浮動小数点
toDouble 倍精度
toString 文字列

サンプル

# D100から10CH分のデータを読出し
data = finsudp.read('D100', 10)
print (finsudp.toInt16(data))

出力
> [1, 2, 500, 1000, 30000, 32767, -1, 0, 0, 0]
9
3
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
9
3