だいたいPLCってなによ
Qiitaはプログラム、主にサーバ・PC・スマホに対するソフトウェアの技術サイトなので
馴染みがない人が多いと思いますが、電気回路に近く、
ノイズ耐性や安定性・メーカー部品保守部品の入手性に特化している演算器で
す。
すごくざっくり言えば、Arduinoの容量とスピード、I/O関連を強化させたものと考えれば十分です。
シーケンサなどとも呼ばれ(三菱FAの商標) 工場の装置制御に使用されています。
ラダー図とか聞いたことがあればそれです。
※ここでも三菱のPLCをベースに記事を書いております。
なぜラズパイを使う?
PLCは元々工作機械であったり、工場のラインをベースにスタンドアロンを前提に使用していたため、
昨今のネットワーク関連にすこぶる弱いです。
最近はLANの端子で通信ができるようになりましたが、
専用のソフトを基準に通信しています。
(しかもそこそこのお値段。)
でもこれからの時代、IoTも含めてネットに繋がらないと不便でしかないので、
ラズパイに橋渡ししてもらおうって算段です。
相性のいい理由
- 電源が近くにある
- 通信もLANケーブル1本でOK
- 装置の中に設置する為のケースもある
- 簡単なI/Oも付いているから、簡単なON/OFFも検知できる
- PLCが不得手な計算処理が得意
- PCと比較して消費電力は格段に少ない。
なにより、安いじゃないですか、コミコミで1万あれば、マシンのIoT化出来るんですよ?
ウン十万のソフト買って、サーバ役のPCを設置するより
ラズパイ上でお得意の言語を使ったほうが保守しやすいです。
何が出来るの?
端的にいうと、PLC内部のデータを読み書きできます。
つまりやろうと思えば、乗っ取り出来ます。
- 外部からの緊急停止
- 現状のセンサー読み取り
- メンテナンスフラグを立てたり消したり
どうやるの?
この記事、お待ちかねの方法ですね。
三菱のPLCに備わっているMCプロトコルを使用します。
三菱が無料で技術書を配布しており、
具体的にはソケット通信により、リクエストを送信、応答分によりデータを取得できます。
つまり、ソケット通信ができればどんな言語でもOKです。
命令文の例
送信文::500000FF03FF000018002004010000D*0002110001
受信文::D00000FF03FF00000800000001
例・Pythonでの、最も簡素な通信方法
import socket
host = "192.168.1.1" # <- PLCに割り振り or 設定したIP
port = 5015 # <- 同じくPLCに設定したポート(後述)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
client.send("500000FF03FF000018002004010000D*0002110001") # 送信文
response = client.recv(1024) # バッファはこんなにいらないけど、一応。
# ↑これが"D00000FF03FF00000800000001"となる。
これだけ。
PLCへの書き込みの場合は、返答文が正常終了かエラーメッセのどちらかになる。
命令文の解説
送信している内容は、PLCの接続構成によるが、
ここでは装置1台に付き、1台のPLCとして話をします。
※複数台の場合はここをヒントに三菱のリファレンスを見て下さい
送信文
5000 00 FF 03FF 00 0018 0020 0401 0000 D*000211 0001
先頭から順に。
5000 :サブヘッダ
PLCの機種によってフレームが決まっている?
5000とすることによって、"3Eフレーム"での通信を指定する。
5400は"4Eフレーム"
ちなみに4Eフレームは、データ文そのものにシリアルを追加することが出来て、
応答分が誰のモノかわかる。00 :ネットワーク番号
ネットワーク間にPLCを中継機として使用している場合は、01h-EFhまでを指定できる。
同じネットワーク上なら、"00"FF :PC番号
同じネットワーク内にPLCが複数ある場合、01h-EFhを指定。
1つだけならFFh03FF :要求先ユニットI/O番号
マルチドロップ・マルチCPU・二重化システムの場合は指定、
1台なら"03FF"00 :要求先ユニット局番号
上記と同じ、マルチドロップ・マルチCPU・二重化システムの場合は指定、
1台なら"00"
ここからコマンド
0018 :送信データ長
ここから続くバイト数を、16進で記入
次の0020から最後の0001まで24文字 => 0018hとなる。0020 :レスポンス待ち時間
処理時間のタイムアウト指定、16進指定で 1単位 250ミリ秒
ここでは32単位、0.8秒まで待つ。0401 :ワード単位(一括)読み出し
おまたせしました。やっと読み書き命令の登場です。
ここの場合、ワード単位で、アドレスを範囲、一括で読み出します。
1点読み出しも出来るので、使い勝手良し。
1点なら0403でも可能、というか正道。0000 :上記読み出しコマンドの、サブコマンド
ほぼ使用しないが、「ビットをセットしたい」or「ビットをリセットしたい」などの場合、
ここが0001になったりする。D*000211 :データアドレス指定
PLCはワード単位でD211など、番号ごとのデバイス(データレジスタ)があり、
これを指定、その他にも "M,X,Y,B,W"など、PLC開発者にはおなじみのデバイスが指定できる
ここではD211を指定、この中身を見たい。
注:ZRデバイスだけは*を省略、ZR000001のようにする。0001 :連続データ数指定
このコマンドは一括読み出しなので、データ数(デバイス数=ワード数)を
指定している、ここでは1個
ここを0003にすると、D211,D212,D213のデータが返ってくる。
000Aなら、D211~D220まで。
つまり、送信データ長の数字と、0401以降のコマンドをいじると、
欲しいデータが降ってくることになる。
受信文
D000 00 FF 03FF 00 0008 0000 0001
正常な返答だとこの様になる。
- D000 00 FF 03FF 00 0008:各種情報
D000:返答固定文
00:ネットワーク番号
FF:PC番号
03FF:要求先ユニットI/O
00:要求先ユニット局番号
0008:以降の文字バイト数
あまり使わないデータですね。
バイト数は使うかもしれませんが、
返ってくる量がわかっていればベリファイ程度に使用します。
0000 :終了コード
0000が正常な終了コードなので、ここだけはチェック0001 :データ(16進)
これが本題のデータ、煮るなり焼くなり、でもまずは10進数変換かな?
PLCの設定
IPやポートなどをこうして設定します。
空いている欄、ここでは3段目に[TCP]
プルダウンから[MCプロトコル]
自局ポート番号には好きなポート番号を。
これで、PLCに書き込むとソケット通信(MCプロトコル)にて通信ができます。
改めて、プログラム側でIP,ポートを確認しましょう。
で、これからなにをする?
こっからはネット+PCソフトの本領発揮ですよ。
0.5秒単位でデータ収集して、社内DBに記録や、
生産実績の記録、振動センサや温度・圧力を監視して
IoTの事例お得意の "壊れる前に、治しに来ました" が出来るかもしれません。
また、許されるならAWS,GCPに投げて遠隔監視や操作まで可能です。
(私の現場では、Firebaseでデータの監視装置で使用してます。)
(メンテ時には、ログも取得したり。)
まだまだ、一部分の紹介ですが、
三菱FAのサイトにて、SH-080003 を検索すると
「Q対応シリアルコミュニケーションユニットユーザーズマニュアル」があるので
無料で落として、PDFの63ページ(書物内では61ページ)にコマンド一覧が載っています。
その他もここより詳しく書いてあるので、一回は見てみて下さい。
ここまでわかると、その他のPLCはどうなっているのか、気になりますね。
では。