横河製のPLC（F3SP71）を使って、PCと通信してみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/7ceefaf7-c03c-b0db-3c27-cdb0ae534b71.png)

今回横河製のPLCを使用して、PC上で動作するソフトウェアを開発したので
記事にした。

システムの全容は莫大な情報になりすぎるため、
簡単な部分のみ掲載。

（結構組み込み系の開発は多いため今度まとめて色んなPLCの情報をアップします。
三菱電機、キーエンスを予定。オムロンの簡単な開発部分は以下のURLを参照。）
https://qiita.com/Kurogara/items/6a5a51d1d86df1e1f157

## 横河製PLCの基本情報
初期IPアドレスは「192.168.0.2」
通信ポートはA、Bの2ポートがある。
Aポートはポート番号「12289」初期値「ASCII形式」
Bポートはポート番号「12291」初期値「バイナリ形式」

ASCIIとバイナリで通信コマンドの内容は変わってくる。
今回はASCII形式で通信することにした。

## 構成図
以下の構成で構築
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/7425cdb7-0ea7-178b-273c-af2bccde517e.png)
LANケーブルで接続

## 開発環境
PLCは、「WideField3」という横河の専用ソフトでプログラム作成。
PCは、C#(.Net6)で開発した。

## 通信コマンド
__#=CPU番号1-4__
__xxxxxx=デバイス名__
__nnn=点数__　001-256
__d=書き込みデータ__　ON="1"(\\$31)  OFF="0"($30)※点数分設定する
__cc=ワード数__　01-64
__eeee=書き込みデータ__ 16進数パターンの文字列
コマンドの最後には「CRLF」をつける

<br/>
<dl>
 <dt>ビット単位の読出し</dt>
<dd><b>0#BRDxxxxxx,nnn</b></dd> 
<dd>例）CPU1のI00001から1点読み込む場合</dd>
<dd>01BRDI00001,001</dd>
<dd>レスポンス「11OK1」</dd>
<br/>
<dt>ビット単位の書込み</dt>
<dd><b>0#BWRxxxxxx,nnn,d</b></dd>
<dd>例）CPU1のI00001から1点分に1を書き込む場合</dd>
<dd>01BRDI00001,001,1</dd>
<dd>レスポンス「11OK」</dd>
<br/>

<dt>ワード単位の読出し</dt>
<dd><b>0#WRDxxxxxx,cc</b></dd>
<dd>例）CPU1のD00001から1点読み込む場合</dd>
<dd>01WRDD00001,01</dd>
<dd>レスポンス「11OK0001」（16進数の文字列）</dd>
<br/>

<dt>ワード単位の書込み</dt>
<dd><b>0#WWRxxxxxx,cc,eeee</b></dd>
<dd>例）CPU1のD00001から1点分に1を書き込む場合</dd>
<dd>01WWRD00001,01,0001</dd>
<dd>レスポンス「11OK」</dd>
<br/>
</dl>

## サンプルコード
今回はD00002の値を読み込んだ後、D00002にFFFFを書き込む処理を作成してみます。
```c#
using System.Net.Sockets;
using System.Text;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public TcpClient client;
        public NetworkStream stream;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // ソケットを作成し、接続する
            client = new TcpClient("192.168.0.2", 12289);

            // ネットワークストリームを取得
            stream = client.GetStream();

            //D00002の値を読み込む処理
            string returnData = DataSendReturn("01WRDD00002,01");

            //読み込んだ値を表示
            MessageBox.Show(returnData, "Return Data", MessageBoxButtons.OK, MessageBoxIcon.Information);

            //D00002の値にFFFFを書き込む処理
            returnData = DataSendReturn("01WWRD00002,01,FFFF");

            //読み込んだ値を表示
            MessageBox.Show(returnData, "Return Data", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        //--------------------------------------------------------------
        /// <summary>
        /// PLCにcommandのデータを送信して返ってきた値をString型で返す
        /// </summary>
        /// <param name="command">PLCに送信するデータ</param>
        /// <returns></returns>
        //--------------------------------------------------------------
        private String DataSendReturn(string command)
        {
            string responseData;
            try
            {
                command += Environment.NewLine;
                byte[] dataToSend = Encoding.ASCII.GetBytes(command);
                stream.Write(dataToSend, 0, dataToSend.Length);

                // データを受信
                byte[] dataToReceive = new byte[4096]; // 配列のサイズを指定
                int bytes = stream.Read(dataToReceive, 0, dataToReceive.Length);
                responseData = Encoding.ASCII.GetString(dataToReceive, 0, bytes);

                return responseData;
            }
            catch (Exception)
            {
                return "ER";
            }
        }
    }
}

```

## プログラム実行
まずはボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/fe7ffc38-9883-002a-4192-c08fae0a996a.png)

11OK0000が返ってきました。今の値は「0000」になっているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/2d948063-81ed-6af6-cad2-500dc46faa66.png)

つづいてOKボタンを押すと次はD00002にFFFFを書き込む処理が実行されます。
問題なく書き込みが実行された場合は、11OKが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/33db6832-48b5-ef53-1364-984904059a12.png)

もう一度button1を押すと次は11OKFFFFが返ってきます。
正常にFFFFの書き込みが行われているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b34bd9b8-40fc-b353-e6b2-34854e9b35a8.png)

PLCなどの開発も行っていますので、
組み込み系でお困りの方はお気軽にご相談くださいー