LoginSignup
27
31

More than 1 year has passed since last update.

MCプロトコルのチートシート

Last updated at Posted at 2018-12-01

アドベントカレンダー

夏休みの宿題を直前にやるタイプとバレてしまいました。。

送信と受信について

過去の記事でも書きましたが、TCPを使ったソケット通信です。
設定その他は、こちらの記事を参照下さい。

ここでは、送信・受信したいコマンド例文を上げていきます。
また、フォーマットは3Eフレームとします。

メモリ-レジスタの種類

メモリやレジスタ(変数)の事をPLCではデバイスと言っています
PLCをプログラムするときのデバイスを一通り説明します。

以下()カッコ内はデバイスの説明
[]カッコ内はコマンドのコード値です。

  • Xレジスタ (PLCへの入力端子) [X*]
  • Yレジスタ (PLCからの出力端子) [Y*]
  • 内部リレー (PLCでビット値として使用できる) [M*]
  • ラッチリレー (停電時にも状態保持されるビット) [L*]
  • アナンシェータ (警報用特殊リレー) [F*]
  • エッジリレー (入力の立ち上がり時のみON、その後自動OFF) [V*]
  • リンクリレー (GOTなどの外部デバイスと相互同期している) [B*]
  • データレジスタ (16bit分のデータ保存レジスタ) [D*]
  • リンクレジスタ (リレーと同じく外部デバイス同期 16bit) [W*]
  • タイマー (左から順に入力-出力-現在値) [TS][TC][TN]
  • 積算タイマー (左から順に入力-出力-現在値) [SS][SC][SN]
  • カウンタ (左から順に入力-出力-現在値) [CS][CC][CN]
  • インデックスレジスタ (数値オフセット用の特殊レジスタ) [Z*]
  • ファイルレジスタ (データ保存用の記憶領域) [ZR*][R*]

PLCをいじっている人なら、わかるかもしれませんが、
特殊レジスタ以外は変更・取得することが出来ます。
この為、制御中のPLCにも介入して実行できる為、
セキュリティには十分気をつける必要があります。

PLCのデータ変更タイミング

良く知られた話ですが、PLCは計算の都度レジスタ値を変更しません。
プログラマの慣習としては首をかしげますが、
1行毎に計算結果を保留とし、最後に一斉に反映・変更が行われます。
以下イメージ。(左:一般的なプログラム 右:PLC)
scan2.png

PLCとの通信タイミング

1スキャンが完了し、データ更新が完了した後のタイミングで行われます。

※コマンドについてはすべてスペースなしです。
 ここでは見やすくスペースを入れることとします。

ヘッダフレームの指定

4Eフレームの場合

5400 1234 0000
5400 : 4Eフレーム送信であることを定義
1234 : 任意シリアル番号 PLC返答分に盛り込まれて、どのPLCかわかります。
0000 : 空き 0固定

3Eフレームの場合

5000
5000 : 3Eフレームを定義

アクセス範囲指定

4Eと3Eフレームの場合

00 FF 03FF 00
00 : ネットワーク番号
FF : PC番号
03FF : 要求先 I/O番号
00 : 要求先ユニット番号

PLCにEtherポートが1つの場合、上記にてOK
複数ポートにて他のPLCと繋がっている場合、
PLCの設定と同じく指定する。

送信データ長

このコマンド以降のデータ長さ(文字数)を16進で伝える

5000 00FF 03FF 00 0018 0020 1401 0000 D*00 0000 0001
上記なら
0020 0401 0000 D*00 0000 0001
24文字 = 0018

監視タイマー

命令文実行完了までのウォッチドッグ。
250msec =0.25sec単位で指定
16進数

0020 = 0.25 x 32 = 8sec

コマンド

ここの数値で書き込みか、読み込みか、連続か個別かを指定します。
前半が読み書きコマンド、
後半がサブコマンド

0401 0000 : ワード単位 16bit 一括読み出し(連続範囲指定)
0401 0001 : ビット単位 一括読み出し(連続範囲指定)

1401 0000 : ワード単位 16bit 一括書き込み(連続範囲指定)
1401 0001 : ビット単位 一括書き込み(連続範囲指定)

0403 0000 : ワード単位 読み出し ランダムアドレス指定
0403 0002 : ダブルワード単位 読み出し ランダムアドレス指定

0406 0000 : ブロック単位の読み出し ランダムアドレス指定
1406 0000 : ブロック単位の書き込み ランダムアドレス指定

ここからはコマンドに応じたコードになる。
例えば、
0401 0000 D*00 0001 0001 = D001から1ワード分を読み出し
1401 0000 ZR00 0001 0001 00c3 = ZR01に1ワード"00c3"を書き込み

0403 0000 0002 0000 D*00 0050 D*00 0076 = ランダムワード読み出し D050とD076 ダブルワードなし

受信データ

一例

D000 00 FF 03FF 00 000C 0000 1234 5678

D000 : 固定文
00 : ネットワーク番号
FF : PC番号
03FF : 要求先ユニットI/O番号
00 : 要求先ユニット 局番
000c : 以降のデータ長 "0000 1234 5678" = 12
0000 : 終了コード エラーの場合は C051となる
1234 5678 : 2ワード分のデータ
 ※1ワードかもしれないし、1ダブルワードかもしれない
  要求した本人だけがわかる。

最後に

ざっくりとした説明になってしまったが、
個人的には少量なら関数を作成し、
1ワードずつ読み書きしたほうがややこしくならないと感じます。

読み出し数が多い場合、PLC側で使用していない領域 D3000~D7000などに
コピー情報を並べておき、一括で読み出すことでオーバーヘッドの少ない通信になると考えます。

重要なのは現状の処理を邪魔しないことなので、
テスト環境で負荷試験を行うことをおすすめします。

27
31
1

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
27
31