三菱MELSEC MCプロトコルをpythonで送信
Pythonで三菱MELSECのMCプロトコル(Ethernet)を送信します
MCプロトコルは三菱のシーケンサのデバイスを値を読み書きすることができます
ここではpythonを使ってEthernet(UDP)でMCプロトコルで通信するクラスを作りました
MCP.py
環境
伝文
3Eフレームでバイナリコードを使用します
3EフレームはMELSEC-QnAシリーズのEthernetインタフェースで使用する伝文構成です
クライアント側環境
python 3.9
使い方
オブジェクトの作成
mcp = MCProtcol3E('192.168.0.41', 4999)
mcp = MCProtcol3E('192.168.0.41', 4999)
MCProtocol3Eクラスは通信相手のIPアドレスとポート番号を指定してオブジェクトを作ります
ワード単位でデバイスの読出し (最大640点)
data = mcp.read('D0', 10)
readメソッドでアドレスと点数を指定して実行すると戻り値には読み出したデータがバイト配列(bytes)で取得できます
ビット単位で読み出し (最大7168点)
data = mcp.read('SM0', 8, True)
第3引数をTrueにするとビット単位での読出しになります
対象のデバイスは以下のデバイスです
X: 入力
Y: 出力
M: 内部リレー
L: ラッチ
F アナンシエータ
V: エッジリレー
B: リンクリレー
D: データレジスタ
W: リンクレジスタ
TS: タイマ(接点)
TC: タイマ(コイル)
TN: タイマ(現在値)
SS: 積算タイマ(接点)
SC: 積算タイマ(コイル)
SN: 積算タイマ(現在値)
CS: カウンタ(接点)
CC: カウンタ(コイル)
CN: カウンタ(現在値)
SB: リンク特殊リレー
SW: リンク特殊レジスタ
S: ステップリレー
DX:ダイレクト入力
DY: ダイレクト出力
SM: 特殊リレー
SD: 特殊レジスタ
ワード単位で書込み
# 数値の場合の例
data = struct.pack('hhh', 123, 456, 789)
rcv = mcp.write('D20', data)
# 実数の場合の例
data = struct.pack('f', 1.23)
rcv = mcp.write('D10', data)
writeメソッドでアドレスと書込みデータを渡して実行すると戻り値に終了コードが返ってきます
書込みデータはバイト配列で渡します
ちなみに数値をバイト列にするstruct.packでよく使いそうなフォーマットを書いておきます
フォーマット | 型 | バイト数 |
---|---|---|
h | Int16 | 2 |
H | UInt16 | 2 |
i | Int32 | 4 |
I | UInt32 | 4 |
q | Int64 | 8 |
Q | UInt64 | 8 |
f | Float | 4 |
d | Double | 8 |
ビット単位で書込み
# ビットの場合の例
data = [0x11, 0x11, 0x10]
rcv = mcp.write('M10', data, 5)
第3引数に書き込むビット数を入れるとビット単位での書込みになります
データ変換
メソッド名 | 変換するデータの長さ | 例 |
---|---|---|
toBin | バイナリ | data = mcp.read('SM0', 8) print(mcp.toBin(data)) > 0b11000100 |
toInt16 | 16bit数値 | data = mcp.read('D0', 5) print(mcp.toInt16(data)) > [-1, 1, 2, 3, 4] |
toUInt16 | 16bit符号なし | data = mcp.read('D0', 5) print(mcp.toUInt16(data)) > [65535, 1, 2, 3, 4] |
toInt32 | 32bit数値 | data = mcp.read('D0', 6) print(mcp.toInt32(data)) > [-1, 196610, 327684] |
toUInt32 | 32bit符号なし | data = mcp.read('D0', 6) print(mcp.toUInt32(data)) > [131071, 196610, 327684] |
toInt64 | 64bit数値 | data = mcp.read('D0', 8) print(mcp.toInt64(data)) > [-1, 1970350607106052] |
toUInt64 | 64bit符号なし | data = mcp.read('D0', 8) print(mcp.toUInt64(data)) > [844433520197631, 1970350607106052] |
toFloat | 浮動小数点 | data = mcp.read('D0', 4) print(mcp.toFloat(data)) > [-2.2, 0.0] |
toDouble | 倍精度 | data = mcp.read('D0', 8) print(mcp.toDouble(data)) > [-2.2, 0.0] |
toString | 文字列 | data = mcp.read('D0', 2) print(mcp.toString(data)) > ABCD |
参考
伝文フォーマット
一括読出し
D100から10ワード読出しコマンド
サブヘッダ | ネットワーク番号 | PC番号 | 要求先ユニットI/O番号 | 要求先ユニット局番号 |
---|---|---|---|---|
50 00 | 00 | FF | FF 03 | 00 |
要求データ長 *1 | 監視タイマ | コマンド | サブコマンド *2 | 先頭番号 | デバイスコード | 点数 |
---|---|---|---|---|---|---|
0C 00 | 10 00 | 01 04 | 00 00 | 64 00 00 | A8 | 0A 00 |
*1 要求データ長から後ろのバイト数
*2 ビット読出しのときはサブコマンドを01 00にする
正常時の応答伝文
サブヘッダ | ネットワーク番号 | PC番号 | 要求先ユニットI/O番号 | 要求先ユニット局番号 |
---|---|---|---|---|
D0 00 | 00 | FF | FF 03 | 00 |
応答データ長 *1 | 終了コード | 読出しデータ |
---|---|---|
16 00 | 00 00 | ... |
*1 応答データ長から後ろのバイト数
一括書込み
D100から10ワード書込みコマンド
サブヘッダ | ネットワーク番号 | PC番号 | 要求先ユニットI/O番号 | 要求先ユニット局番号 |
---|---|---|---|---|
50 00 | 00 | FF | FF 03 | 00 |
要求データ長 *1 | 監視タイマ | コマンド | サブコマンド *2 | 先頭番号 | デバイスコード |
---|---|---|---|---|---|
20 00 | 10 00 | 01 14 | 00 00 | 64 00 00 | A8 |
点数 | 書込みデータ |
---|---|
0A 00 | 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 |
*1 要求データ長から後ろのバイト数
*2 ビット読出しのときはサブコマンドを01 00にする
正常時の応答伝文
サブヘッダ | ネットワーク番号 | PC番号 | 要求先ユニットI/O番号 | 要求先ユニット局番号 |
---|---|---|---|---|
D0 00 | 00 | FF | FF 03 | 00 |
応答データ長 *1 | 終了コード |
---|---|
02 00 | 00 00 |
*1 応答データ長から後ろのバイト数
Author And Source
この問題について(三菱MELSEC MCプロトコルをpythonで送信), 我々は、より多くの情報をここで見つけました https://qiita.com/OkitaSystemDesign/items/97b7d27c0d53668baafc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .