PLC無しで通信チェックが可能なツールを作ってみた

今回も作ったツールを公開してみます。
今回のツールはPLCと通信してどうこうではなく、逆にPLCの代わりに通信応答を返すツールです。
なんちゃってPLC、ダミー通信ツール、と表現するのが妥当と思います。少しかっこつけて言えば「PLC通信エミュレータ」でしょうか。

とりあえずココからダウンロードできます。
ソースコードが気になる方はこちらを参照ください。

2026/6/13 追加
.NET 6.0がサポート切れなので.NET 10.0に対応
ツールはココからダウンロードできます。

目次

開発環境

以前に作成したデバイスモニタチャートモニタと同様にVisual Studio2022のC#、ターゲットフレームワークは.NET6.0です。
※ランタイムはココからダウンロードできます。必要なものは「.NET デスクトップ ランタイム 6.*.* 」のランタイムです。

対応しているプロトコルはEthernet通信のみで、
・三菱(MCプロトコル/SLMP)
・OMRON(FINS)
・KEYENCE(上位リンク/MCプロトコル)
・横河(パソコンリンク)
で使える、、予定です。

2026/6/13 追加
開発環境はVisual Studio 2026、C#、ターゲットフレームワークは.NET 10.0
(VS2022では.NET 10.0は正規対応していない)

注意事項

多分動くと思いますが、、サクッとデバッグのみでたいしたテストをしていないため予期せぬ不具合が発生する可能性が多分にあります。また本ツールを使用したことによる如何なる損害についても一切責任を負いません。ご使用については全て自己責任でお願いします。

心の声

もはやテンプレという名の言い訳。。。
まあ今回のツールはPLCに対してアクセスするものではないので、何かあってもモノを壊すことは無くパソコン上で何か発生するだけ。

主な機能

  • 最大4台のPLC通信を模擬
  • デバイスのRead/Writeにのみ対応(ラベル・変数には未対応)
    ⇒対応コマンドの詳細は下記参照
  • 対象デバイスの値は共有メモリを使用してツール側で保持
    ⇒Writeした値の保持およびツール側でデバイス値の任意操作も可能
    (当然ながら同じデバイスに対しての書込は後操作が優先)
  • デバイス値はファイルにて保存&復元
  • 通信ログの表示および保存

MCプロトコルの対応コマンド (三菱 or KEYENCE)

種別コマンドサブコマンド
ワード単位の一括読出し04010000
ビット単位の一括読出し04010001
ワード単位の一括書込み14010000
ビット単位の一括書込み14010001
ワード単位のランダム読出し04030000
ワード単位のランダム書込み14020000
ビット単位のランダム書込み14020001

※複数ブロックの一括読み書き(0406/1406)やモニタ・モニタ登録(0801/0802)には未対応
※サブコマンドの0002/0003には未対応(SLMP側で対応)
※内部デバイスのみに対応(バッファメモリ(U*\G****)やリンクダイレクトデバイス(J*\B****など)には未対応)
※KEYENCEでのMCプロトコルも対応コマンドは同じ

SLMPの対応コマンド (三菱)

種別コマンドサブコマンド
ワード単位の一括読出し04010002
ビット単位の一括読出し04010003
ワード単位の一括書込み14010002
ビット単位の一括書込み14010003
ワード単位のランダム読出し04030002
ワード単位のランダム書込み14020002
ビット単位のランダム書込み14020003

※複数ブロックの一括読み書き(0406/1406)やモニタ・モニタ登録(0801/0802)には未対応
※サブコマンドの0000/0001には未対応(MCプロトコル側で対応)
※通常内部デバイスのみに対応(バッファメモリ(U*\G****)やリンクダイレクトデバイス(J*\B****など)には未対応)

FINSの対応コマンド (OMRON)

種別コマンドコード
I/Oメモリエリアの読出01 01
I/Oメモリエリアの書込01 02
I/Oメモリエリアの複合読出01 04

※I/Oメモリエリアの一括書込(01 03)やI/Oメモリエリアの転送(01 05)には未対応
※タスクフラグ(TK)やインデックスレジスタ(IR/DR)、クロックやコンディションフラグには未対応

上位リンクの対応コマンド (KEYENCE)

種別コマンド
データ読み出しRD
連続データ読み出しRDS or RDE
データ書き込みWR
連続データ書き込みWRS or WRE

※強制セット/リセット(ST/RS)やモニタ登録/読み出し(MBS/MWS/MBR/MWR)には未対応

パソコンリンクの対応コマンド (横河)

種別コマンド(Ascii)コマンド(Binary)
ビット単位の読出しBRD01
ビット単位の書込みBWR02
ビット単位のランダム読出しBRR04
ビット単位のランダム書込みBRW05
ワード単位の読出しWRD11
ワード単位の書込みWWR12
ワード単位のランダム読出しWRR14
ワード単位のランダム書込みWRW15

※同一データの書込み(BFL/WFL/03/13)やモニタ指定/モニタリング(BRS/BRM/WRS/WRM/06/07/16/17)には未対応
※特殊モジュールアクセスコマンド(アナログユニットや高速カウンタユニット等へのアクセス)には未対応

使い方

通信設定

設定は
①通信プロトコル選択
②TCP or UDP選択
③ポート番号入力(1024~65535)
④Binary or Ascii選択
⑤通信ログ保存 *常時変更可
⑥エラー応答 *常時変更可
⑦共有メモリIndex入力(0~3)
です。(それぞれ回線No.0~3の4台分)

共有メモリIndexはこのツール内でのデバイス値を共有メモリで保持(0~3の4台分)しており、この共有メモリ≒デバイス値のアクセス先を指定するものになります。基本的にはPLC4台分を別々に想定していますが実際には場合によって複数の通信回線を使用して1台のPLCにアクセスすることもあり得るため、このような経路にも対応できるようにしています。

設定後は開始・停止ボタンで通信処理の開始・停止が可能となります。
一番下側にある”デバイス値のリセット”のボタンはデバイス値≒共有メモリの値をすべて0にクリアします。

PLCとの通信アプリケーション(デバイスモニタチャートモニタなど)から本ツールへアクセスするには別のPCを用意してIPアドレスを適切に設定することで使えるワケですが、、
わざわざ複数のPCを準備するのは面倒なので同一のPC内で確認するのがオススメです。というよりPLC無しでサクッと通信をチェックするためのツールなので同じPC内で使うことがほとんどだと思います。
方法は特に難しいことはなく、PLCにアクセスする側の設定でIPアドレスを“127.0.0.1”(いわゆるループバックlocalhostと呼ばれるもの)に設定すればOKです。

当然ですが
①サーバ側=本ツール側の通信を開始
②クライアント側(デバイスモニタなど)の通信を開始
の順に操作しないとエラーが発生するのでご注意ください。。

終了する場合は逆に
①クライアント側の通信を停止
②サーバ側=本ツール側の通信を停止
とするのがベターです。(どちらから停止しても問題はないハズですが)

通信ログ

通信を開始するとログを表示します。画面上部のラジオボタンで表示回線を切り替えます。
(読出か書込かがすぐに分かる程度のログですが。。)
※ログをファイルに保存するとこのテキストがそのまま出力されます。

デバイス値

デバイス値≒共有メモリの値を確認・操作出来ます。
デバイスと点数を指定すると右側のグリッド表示が変わり、左側で表示するデータ型を選択できます。ビット表示(● or 〇)部分をダブルクリックすると反転、ワード値表示部分はクリックすると入力ダイアログが表示されるので値を入力すると操作可能です。
このあたりはデバイスモニタと同様です。

クライアント側(デバイスモニタなど)から書込要求があれば共有メモリの値が書き換わります。

注意事項 その2

TCPで通信する場合ですが、、
動作自体は確認できましたが切断に問題アリです。。。
クライアント側で回線切断(ソケットを閉じる)をするとサーバ側で切断を検出できるかと思っていたのですが予想どおりには動作せず。。。同一PCだからなのかどうかは不明です。(複数PCで試していないので)
極稀に回線切断を検出できることもあったのですが基本ダメです。TCPで使用する場合はクライアント側の回線切断に合わせて、本ツール側で通信停止→開始としないと次の通信が出来ませんのであしからず。。(私の力不足orz)

UDPの場合はTCPと違ってConnectという概念がないので上記のような切断の問題は発生しません。

感想?

今回のツールは、、、かなり使う人を選ぶツールと思います。
大半の人には「ふ~ん、あーそう」的なものですが極々限られた人にはそれなりに有用なもの、、と思いたい。
(PLCとの通信ツールを”作る側の人”にはちょっと需要あるかも)

ちなみに今回作成したツールの原型といいますか、簡易版のツールは以前から使っていたのですがイマイチ使えなかったのでリニューアルした感じです。(たぶん1カ月くらいかかった)
ちなみに以前公開したデバイスモニタチャートモニタの作成時は実機PLCとの接続テストはゼロです。。が、何のテストも無しでいきなり公開する勇気はないので、最低限の通信テストはダミーの通信ツールを使っていたワケです。
(実際にPLCと接続してもいないのに多分使える、、として公開したのはこういうカラクリがあります。いくら個人のサイトとはいえ、何の根拠もなくホイホイと無責任に公開はムリ。バグはあるけどw)
今後また何かツールを作る場合はデバッグ・動作確認が楽になる、、ハズ。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (28件)

  • 普段よりPLCと通信するアプリを作成しているものです。
    日本でどれくらいの人にこのツールの便利さが伝わるのか不明ですが、私にはわかります笑
    これでビットの立ち上がりをトリガに開始する処理のデバッグなどする際、いちいち評価用PLCを引っ張り出さずに済みます。
    自己責任で使わせていただきます。ありがとうございます。

    • 評価していただきありがとうございます!
      最初から「めちゃめちゃ人を限定するツール」と分かってはいましたが、、伝わる人には伝わるのですね。妙にうれしくなりました。
      何かしら役に立っていれば幸いです。

  • 使わせて頂きました。大変便利でいいですね。
    [ランダム読出し,書込み]のダブルワードでの動作が、うまくいかない様です。

    • お試し&連絡ありがとうございます。
      このツール、、おそらく他にも何か潜んでいると思います。orz
      最近はなかなかソースコードを見ている時間がないのですがそのうちなんとか。。

  • 最近PLC(MCプロトコル)から計測値を読み出すアプリを作成しております。
    こちらのシュミレータのおかげで実機が無くとも動作検証ができるようになり大変助かっております!
    実機を揃えることも中々難しいですし、アプリケーション連携の運用例も徐々に更新頻度が無くなりつつある昨今で「お手軽にPLCのシミュレーションができるなんて!」と、とても感動しました。
    自己責任でこれからも使わせて頂きます。本当にありがとうございます。

  • はじめまして。SCADAや通信ライブラリを使用した場合は、GX Simulatorと接続してテストできたのですが、直接通信する際にGX Simulatorと接続できず、困っていました。
    本ツールを使用すれば、簡単なテストは実機がなくてもできるので、かなり便利になりました。
    (感動しました)
    今後も使用したいと思います。
    (ちなみにGX Simulatorと接続できるライブラリの開発予定はないでしょうか?)

    • それなり(?)に役に立ったようでなによりです。
      ちなみにGX Simulatorと接続できるものとなると、、メーカ側が公開しているプロトコルは無いので開発するのはほぼ無理です。
      ただメーカからはMX Componentという通信ライブラリが販売されていますので、これを使えばGX Simulatorにアクセスしてデバイスの読み書きが可能になります。
      (本業の仕事だとMX Componentも使っているので便利は便利ですが、GX Simulatorを使うと動作が重くなるので。。)

  • >メーカ側が公開しているプロトコルは無いので開発するのはほぼ無理です。

    無理といふことはないです。 GX Sim 2, GX Sim 3 に access する VC++, .NET のを作ってみました。
    SimpleGXC

    GX Sim3 への access がやや面倒でした。

    • たしかに絶対的に無理、ということはありませんが、かなりハードルが高い気がします。。
      シリアル通信ならラインモニタ、Ethernetならパケットキャプチャツール、、
      何かしら通信データをのぞき見る手段があるにはあるのでこれらを駆使して公開されているプロトコルを参考に推測&解析、でしょうか。
      昔から手段がありそうなのは知識として知っていますがやったことがないので何とも。。
      (GX Simulatorに使える手段かどうかも不明ですが)

  • テスト用のPLCが少なく、通信を模擬で行えるのはとてもありがたいです。
    一点質問なのですが、このソフトは4Eフレーム対応していますでしょうか?

    • 4Eフレームにも対応しているハズ、、と思って試したらダメでしたorz
      (ソースコードでは対応した形跡があるのですが。。)

  • こんにちわ
    MCプロトコルからこのアプリに接続を試しているんですがつながりません
    この記事に書いてある電文と同じのものを送っているのにいつもC05Bってエラーコードが出ます
    皆さんどうやってつないでいるんですか
    特別な設定とかありますか?

  • 全然専門外の仕事をしている者ですが、PLCのプログラミングに興味があってググったらここに辿り着きました。
    TCP通信に関しては、仮にPingでの応答がタイムアウトした場合、再接続を試みてダメだったら切断とする。
    というルールを自分で決めて実装するしかないと思います。
    相手から「切断しました」とか返ってくるわけありませんからw

  • めっちゃ役に立つツールありがとうございます。
    いちいちそこら辺に転がっているPLCを電源つないで、MCプロトコル接続できるようにGX Worksで設定して、LANケーブルつないで、PC側のLANの
    IPアドレスを一時的に変えて…ってやっていた検証作業が一瞬でできた!
    エミュレーター側のデバイスがモニターできるのが素晴らしい。
    れっきとしたエミュレーターです。堂々と名乗っていいです。

    • コメントありがとうございます。励みになります。
      PLCの電源、CPU(三菱ならベースも)、準備するのも手間なときありますね。。
      しかも設定するは簡単だけど地味に手間w
      役に立ったようで作ったかいがありました。

      • 本文中にある
        > 動作自体は確認できましたが切断に問題アリです。。。
        は、たしかに当方でも再現しています。
        クライアント側でTCPをクローズしているのに、
        次に再度接続しようとすると接続できず、
        DummyPLC を停止→開始とすることで再度接続できるようになります。
        特に不便を感じるほどでもないのですが、解決できるといいですね。

      • > 同一PCだからなのかどうかは不明です。(複数PCで試していないので)

        外部機器から試してみました。
        PC: Dummy PLC
        外部機器:ロボットコントローラー(OSはたぶんLinux系)
        上記テストで通信は問題なくできるのですが、外部機器がsocketを
        closeすると、Dummy PLC には再接続できなくなり、
        停止 → 起動と操作する必要があります。

  • 通信のテストのために有り難く使わせていただいております。
    MCプロトコルを使うと書き込めるのですが、
    13:33:59.520 TCP Client: 192.168.100.20
    13:34:01.184 TCP Recv: 50 00 00 FF FF 03 00 34 00 00 00 01 14 00 00 15 00 00 A8 14 00 01 00 00 00 00 00 00 00 63 00 01 00 26 00 05 00 29 00 11 00 27 00 36 00 6F 6B 61 6D 6F 74 6F 00 00 00 00 00 00 00 00 00 (61bytes)
    >>> ブロック書込: D21, 20点(ワード単位)
    13:34:01.189 TCP Send: D0 00 00 FF FF 03 00 02 00 00 00 (11bytes)

    SLMPでワード単位の一括書込み 1401 0002コマンドを使っても書き込むことが出来ません。
    13:34:21.332 TCP Client: 192.168.100.20
    13:34:22.414 TCP Recv: 50 00 00 FF FF 03 00 34 00 00 00 01 14 02 00 15 00 00 A8 14 00 01 00 00 00 00 00 00 00 63 00 01 00 26 00 05 00 29 00 11 00 27 00 36 00 6F 6B 61 6D 6F 74 6F 00 00 00 00 00 00 00 00 00 (61bytes)
    13:34:22.418 TCP Send: D0 00 00 FF FF 03 00 0B 00 5B C0 00 FF FF 03 00 01 14 02 00 (20bytes)
    何か問題ありますでしょうか?

    • MCプロトコルとSLMPはサブコマンドが違うだけでなくデバイス指定も異なります。
      バイナリ通信の場合MCプロトコルでは3byteのデバイス番号+1byteのデバイスコード(D21→0x15 0x00 0x00 0xA8)ですが
      SLMPは4byteのデバイス番号+2byteのデバイスコード(D21→0x15 0x00 0x00 0x00 0xA8 0x00)となります。
      DummyPLC側での受信ログのデバイス指定がどちらも同じデータなので、MCプロトコルはOKでSLMPがNGとなっているのだと思います。

  • 非常に有用なツール、有難うございます。
    活用させて頂いております。
    1点、ご質問させて頂きたいのですが、
    KEYENCE MCプロトコルに設定し、ランダム書き込みを行った際、
    エラー応答のチェックを外すと、デバイス値が更新され、
    レスポンスの応答が無くなります。
    レスポンスの応答が欲しい場合は、エラー応答のチェックを入れると認識します。
    しかし、エラー応答のチェックを入れると、デバイス値が更新されない様な・・・
    私の使い方に問題があるのでしょうか?

    • エラー応答のチェックを入れるとデータが正しくてもエラーコードを返してデバイス値が更新されないのは予定どおりですが、
      エラー応答のチェックを外して応答が無いのはDummyPLCの不具合。。orz

      • 返信、有難うございます。
        状況がわかりました。
        KEYENCEの仕様書には、応答が無い様な事が記載されていたと思っていました。

      • 追加で、ご質問させて頂きます。
        設定するポート番号は、送受信のポート番号が同一となるのでしょうか?

        送受信ポート番号が同一であるならば、使い方に
        > わざわざ複数のPCを準備するのは面倒なので同一のPC内で確認するのがオススメです。
        とありましたので、同一PCにて、自作プログラムとDummyPLCをTCP通信接続して使用しました。
        その際、ランダム読み出しコマンドを送信した後、DummyPLCからの応答情報は、自作プログラムとDummyPLCのどちらに応答を返信するのか、ちょっと疑問に思いまして・・・
        私の勘違いならば、申し訳ありません。

        • ポートを合わせる→サーバ側(PLCやDummyPLC等)とクライアント側(デバイス値を読み書きする側)でTCP or UDPとポート番号を合わせないとそもそも通信ができないのはソレとして、、
          サーバ側として同じポートを待ち受けるのは先に実行したほうが優先?(後から実行するほうが失敗?)される気がしますがキッチリ試したことがないので何とも。。
          (特にTCPは接続確立しないと何もできない、逆に言えば通信確立してしまえば互いに相手が確定されているので急に通信相手が変わることは無いです)

コメントする

CAPTCHA

目次