スポンサーリンク
目的
PCとKEYENCE社製PLCを通信させて、PCからPLCのデバイス値の読み書きできるようしたいと思います。
PC側のプログラムはC# .NETを使用します。今回は上位リンクという機能を使用していきたいと思います。
PLC側の設定
KV-8000 / KV STUDIO ver10を例にします。
ハードウェアはKV-7500やKV-NC1EPでも同じように行えるかと思います。
- [ユニット構成エディタ] → [KV-8000 ユニット設定タブ] → [基本]の[IPアドレス]
- [ユニット構成エディタ] → [KV-8000 ユニット設定タブ] → [ポート番号]の[ポート番号(上位リンク)]
上記2項目を設定するだけで、特別なラダーやKVスクリプト記述は必要ありません。
この例では下記のように設定しました。
IPアドレス | 192.168.2.35 |
サブネットマスク | 255.255.255.0 |
デフォルトゲートウェイ | 0.0.0.0 |
DNSサーバ | 0.0.0.0 |
ポート番号(上位リンク) | 8501(デフォルト値) |
PC側の設定
PLCと同じネットワークグループに接続しておきます。
プログラム
書き込み
MR001の値を0から1に変更したいと思います。
static void Main(string[] args)
{
// PLCのIPアドレス
string host = "192.168.2.35";
// 上位リンクのデフォルト設定は8501
int port = 8501;
//TcpClientを作成し、サーバーと接続する
TcpClient tcp = new TcpClient();
tcp.Connect(host, port);
if (tcp.Connected)
{
Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})",
((IPEndPoint)tcp.Client.RemoteEndPoint).Address,
((IPEndPoint)tcp.Client.RemoteEndPoint).Port,
((IPEndPoint)tcp.Client.LocalEndPoint).Address,
((IPEndPoint)tcp.Client.LocalEndPoint).Port);
}
// Timeoutを設定する
NetworkStream ns = tcp.GetStream();
ns.ReadTimeout = 10000;
ns.WriteTimeout = 10000;
// MR001のデバイス値を1に書き込み
string sendMsg = "WR MR001 1";
Encoding enc = Encoding.ASCII;
byte[] sendBytes = enc.GetBytes(sendMsg + '\r');
//データを送信する
ns.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine(sendMsg);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] resBytes = new byte[256];
int resSize = 0;
do
{
//データの一部を受信する
resSize = ns.Read(resBytes, 0, resBytes.Length);
//Readが0を返した時はサーバーが切断したと判断
if (resSize == 0)
{
Console.WriteLine("サーバーが切断しました。");
break;
}
//受信したデータを蓄積する
ms.Write(resBytes, 0, resSize);
//まだ読み取れるデータがあるか、データの最後が\nでない時は、
// 受信を続ける
} while (ns.DataAvailable || resBytes[resSize - 1] != '\n');
//受信したデータを文字列に変換
string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length);
ms.Close();
//末尾の\nを削除
resMsg = resMsg.TrimEnd('\n');
Console.WriteLine(resMsg);
//閉じる
ns.Close();
tcp.Close();
Console.WriteLine("切断しました。");
}
実行結果
WR MR001 1
OK
切断しました。
モニターモードでMR001の値が変更されたことが確認できたかと思います。
読み込み
MR001のデバイス値を読み込んでみます。
26行目が少し違うだけで後は同じです。
static void Main(string[] args)
{
// PLCのIPアドレス
string host = "192.168.2.35";
// 上位リンクのデフォルト設定は8501
int port = 8501;
//TcpClientを作成し、サーバーと接続する
TcpClient tcp = new TcpClient();
tcp.Connect(host, port);
if (tcp.Connected)
{
Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})",
((IPEndPoint)tcp.Client.RemoteEndPoint).Address,
((IPEndPoint)tcp.Client.RemoteEndPoint).Port,
((IPEndPoint)tcp.Client.LocalEndPoint).Address,
((IPEndPoint)tcp.Client.LocalEndPoint).Port);
}
// Timeoutを設定する
NetworkStream ns = tcp.GetStream();
ns.ReadTimeout = 10000;
ns.WriteTimeout = 10000;
// MR001のデバイス値を読み込む
string sendMsg = "RD MR001";
Encoding enc = Encoding.ASCII;
byte[] sendBytes = enc.GetBytes(sendMsg + '\r');
//データを送信する
ns.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine(sendMsg);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] resBytes = new byte[256];
int resSize = 0;
do
{
//データの一部を受信する
resSize = ns.Read(resBytes, 0, resBytes.Length);
//Readが0を返した時はサーバーが切断したと判断
if (resSize == 0)
{
Console.WriteLine("サーバーが切断しました。");
break;
}
//受信したデータを蓄積する
ms.Write(resBytes, 0, resSize);
//まだ読み取れるデータがあるか、データの最後が\nでない時は、
// 受信を続ける
} while (ns.DataAvailable || resBytes[resSize - 1] != '\n');
//受信したデータを文字列に変換
string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length);
ms.Close();
//末尾の\nを削除
resMsg = resMsg.TrimEnd('\n');
Console.WriteLine(resMsg);
//閉じる
ns.Close();
tcp.Close();
Console.WriteLine("切断しました。");
}
実行結果
RD MR001
1
切断しました。
DM001.TにABCDという文字列を書き込みたいときには26行目を"WR DM001.T ABCD"
と変更すればOKです。
スポンサーリンク
スポンサーリンク