アドベントカレンダー
夏休みの宿題を直前にやるタイプとバレてしまいました。。
送信と受信について
過去の記事でも書きましたが、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)
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 D00 0050 D00 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などに
コピー情報を並べておき、一括で読み出すことでオーバーヘッドの少ない通信になると考えます。
重要なのは現状の処理を邪魔しないことなので、
テスト環境で負荷試験を行うことをおすすめします。