Python
RaspberryPi
IoT
PLC
シーケンサー

PLCとRaspberry Piはとっても相性がいい。(通信の行い方)

だいたい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です。

命令文の例

Command_Ex.txt
送信文::500000FF03FF000018002004010000D*0002110001
受信文::D00000FF03FF00000800000001

例・Pythonでの、最も簡素な通信方法

PLC.py
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つだけならFFh

  • 03FF :要求先ユニットI/O番号
    マルチドロップ・マルチCPU・二重化システムの場合は指定、
    1台なら"03FF"

  • 00 :要求先ユニット局番号
    上記と同じ、マルチドロップ・マルチCPU・二重化システムの場合は指定、
    1台なら"03FF"

ここからコマンド

  • 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やポートなどをこうして設定します。

GX-Woks2で説明。
PCパラメータを選択
2018-09-13_15h57_10.png

いろいろ設定!
2018-09-13_15h58_59.png

空いている欄、ここでは3段目に[TCP]
プルダウンから[MCプロトコル]
自局ポート番号には好きなポート番号を。
2018-09-13_16h04_36.png

これで、PLCに書き込むとソケット通信(MCプロトコル)にて通信ができます。

改めて、プログラム側でIP,ポートを確認しましょう。

で、これからなにをする?

こっからはネット+PCソフトの本領発揮ですよ。
0.5秒単位でデータ収集して、社内DBに記録や、
生産実績の記録、振動センサや温度・圧力を監視して
IoTの事例お得意の "壊れる前に、治しに来ました" が出来るかもしれません。

また、許されるならAWS,GCPに投げて遠隔監視や操作まで可能です。
(私の現場では、Firebaseでデータの監視装置で使用してます。)
(メンテ時には、ログも取得したり。)

まだまだ、一部分の紹介ですが、
三菱FAのサイトにて、SH-080003 を検索すると
「Q対応シリアルコミュニケーションユニットユーザーズマニュアル」があるので
無料で落として、PDFの63ページ(書物内では61ページ)にコマンド一覧が載っています。
その他もここより詳しく書いてあるので、一回は見てみて下さい。

ここまでわかると、その他のPLCはどうなっているのか、気になりますね。
では。

三菱電機FA
http://www.mitsubishielectric.co.jp/