【PLC】PCとリンクしてリアルタイムデータを読み書きして連携する

plc_pc
plc_pc
C#.NET

ad2

【PLC】PCとリンクしてリアルタイムデータを読み書きして連携する

Keyence製KVシリーズで上位リンク通信

上位リンク通信の仕組みを詳しく

通信フロー図

linkimage

コマンド一覧

クライアントからさバーに送るコマンドの一覧は下記の通りです。

機能 コマンド
モード変更 Mn
エラークリア ER
エラー番号確認 ?E
機種の問い合わせ ?K
動作モード確認 ?M
時刻設定 WRT
強制セット/強制リセット ST/RS
連続強制セット/連続強制リセット STS/RSS
データ読み出し RD
連続データ読み出し RDS
連続データ読み出し RDE
データ書き込み WR
連続データ書き込み WRS
連続データ書き込み WRE
設定値書き込み WS
連続設定値書き込み WSS
モニタ登録 MBS/MWS
モニタ読み出し MBR/MWR
コメント読み出し RDC
バンク切り替え BE
拡張ユニットバッファメモリ読み出し URD
拡張ユニットバッファメモリ書き込み UWR

今回は、このコマンドの中からデータ読み出し、データ書き込みについて詳しく使い方を書いてみようと思います。

データ読み出し「RD」連続データ読み出し「RDS」

PLCの特定のデバイス値の値を読み出すコマンドです。

RD:指定したデバイスのデータを1つ読み出し

RD

備考「␣」:スペース(空欄)

RDS:指定した個数のデバイスのデータを連続で読み出し

RDS

レスポンス:返り値

common_response

 

例えば、DM1000のデバイス値の値を知りたいとき、

コマンド:[RD␣DM 1000]

をクライアントからサーバーに送ると「DM1000」のデバイス値が返ってくる仕組みです。

具体例を載せておきます。

DM200~DM202の3デバイス分の値をデータ形式[.S]で読み出すコマンド

sample_RDS
string strRDSCOm = "RDS DM200.S 3\r"

※末尾は「\r」

レスポンス返り値は、スペース区切りで返ってくる。

sample_RDS_response
string res = "+15025 -25400 +00000\r\n";

エラーレスポンス

エラーが起きた場合のレスポンスもあるので、きちんと作るならエラー処理も作れます。

E0:デバイス番号異常

error1

E1:コマンド異常

error2

データ書き込み「WR」連続データ書き込み「WRS」

PLCの特定のデバイス番号に値を書き込むコマンドです。

WR:指定したデバイスにデータを1つ書き込む

WR

備考「␣」:スペース(空欄)

WRS:指定した個数のデバイスにデータを連続で書き込み

WRS

WR,WRSコマンドは、書き込みコマンドになっています。

PCからPLCに値を書き込み出来ます。

サンプル例:DM200~DM202にデータ形式「.S」で書き込む場合

wrs_sample
string strWRSCom = "WRS DM200.S 3 +15025 -05400 200\r";

※末尾は「\r」

レスポンス

書き込みコマンドを送って完了したら、「OK」のレスポンスが返ってきます。

response_ok

エラーレスポンス

[E0]と[E1]は読み出しの時と同じエラーレスポンスになります。

E0:デバイス番号異常

E1:コマンド異常

書き込みの場合のエラーとして[E4]のレスポンスが返ってきます。

E4:書き込み禁止

error4

データ形式※

データ形式 設定値1~n
サイズ 範囲
.U 10進数16ビット符号なし 5byte 00000~65535
.S 10進数16ビット符号あり 6byte -32768~+32767(0の場合+00000)
.D(省略可) 10進数32ビット符号なし 10byte 0000000000~4294967295
.L 10進数16ビット符号あり 11byte -2147483648~+2147483647(0nの場合+0000000000)
.H 16進数16ビット 4byte 0000~FFFF

PLC側は細かい設定不要

まず、サーバーであるPLC側はいっさいクライアントであるPCとの通信を気にしなくて大丈夫。

PLC側はフロー図に示した通り、自動でクライアントとの通信を確立してくれます。

制御屋は難しい事は考えなくて済むので、PC側のシステム屋が大変なだけです。

なので、実際の現場の方が見ているなら、システム屋には十分な工数を与えてくれると幸いです。

PC側でのシステム実装

さてここからが本題です。クライアント側のPCでは、今回はC#.Netで実装していく方向で説明します。

Socket通信でTcpClientを使います。

余談ですが、仕事でPLCと通信するシステムを作ることになったのですが、

PLCとの通信はしたことなかったので、最初はどうやるのか全くわからない状態でした。

TcpClientでPLCと通信確立

では早速、TcpClientでconnectするソースコードは以下の通りです。

public int portNo = 8501;  //上位リンク通信用ポート番号(初期設定)
public IPAddress iPAddress = IPAddress.Parse("135.15.79.20");   //PLCのIPアドレス(適宜設定) 

private void PLCconnect()
{
    //PLCコネクション接続
    TcpClient client = new TcpClient();

    try
    {
        //接続
        client.Connect(iPAddress, portNo);
    }
    catch
    {
        //接続エラー
        MessageBox.Show("PLCとの接続エラー");
    }
    
    ////
    //ここに処理するコードを書いていく。
    ////
}

PLC側の上位リンク通信用ポートが初期設定値:8501なのでそれを定義する。

PLC側のIPアドレスを定義する。(PLCで設定しているIPアドレスを当ててあげればいい)

そして、TcpClientのインスタンス作成。

Connectで引数にIPアドレス、ポート番号を設定してあげる。

これだけで、PLCとPCとの通信が確立します。

意外と簡単にPLCと接続できたんだと驚きました。

RDコマンド処理

//NetworkStreamを取得
NetworkStream ns = client2.GetStream();

//読み出しコマンド
string strRDCom = "RD DM500.D\r";  //コマンド内容⇒DM500デバイスの10進数32ビット符号ありの値を読み出す    


//配列定義
char[] chArray2 = strRDCom.ToCharArray();
byte[] bArray_send = new byte[chArray2.Length];

//データをバイト配列に変換
for (int iCount = 0; iCount < chArray2.Length; iCount++)
{
    bArray_send[iCount] = Convert.ToByte(chArray2[iCount] & 0xFFFF);
}

///////コマンド送信  処理終了確認用コマンド/////////
ns.Write(bArray_send, 0, bArray_send.Length);

//レスポンス格納用バイト配列定義
int byteValue = 50;    //レスポンス用バイト容量 適当余裕を持たせて。
byte[] bArray_res = new byte[byteValue];

//////レスポンスデータ受信//////
ns.Read(bArray_res, 0, bArray_res .Length);

//レスポンス文字列
string res = Encoding.GetEncoding(932).GetString(bArray_res);

//通信クローズ
ns.Close();
ns.Dispose();

client.Close();
client.Dispose();

WRコマンド処理

//NetworkStreamを取得
NetworkStream ns = client.GetStream();

//コマンド
string strWRCom = "WR DM502.D 2\r";  //コマンド内容⇒DM502デバイス番号に[2]を書き込む    

//配列定義
char[] chArray2 = strWRCom.ToCharArray();
byte[] bArray_send = new byte[chArray2.Length];

//コマンド文字列をバイト配列に変換
for (int iCount = 0; iCount < chArray2.Length; iCount++)
{
    bArray_send[iCount] = Convert.ToByte(chArray2[iCount] & 0xFFFF);
}

//コマンド送信
ns.Write(bArray_send, 0, bArray_send.Length);

//レスポンス格納用バイト配列定義 
int byteValue = 50; 

//レスポンス用バイト容量 適当余裕を持たせて。 
byte[] bArray_res = new byte[byteValue]; 

//////レスポンスデータ受信////// 
ns.Read(bArray_res, 0, bArray_res .Length); 

//レスポンス文字列 
string res = Encoding.GetEncoding(932).GetString(bArray_res); //正常終了なら[OK]が返ってくる

//通信クローズ
ns.Close();
ns.Dispose();

client.Close();
client.Dispose();

 

PLCとPCを通信してデータをPCのデータベースに格納蓄積して、商品のトレーサビリティを実現するシステムの一部で役に立ってます。

他の記事も参考にして下さい。

【PLC】キーエンスKV-7500で上位リンク通信でPCとPLCの通信を確立してデータを読み書きする方法