Bài viết này hướng dẫn cách tạo ứng dụng Windows Desktop bằng C# Windows Forms để kết nối với PLC Keyence KV Series qua giao thức MC Protocol và đọc trạng thái device DM100.
Yêu cầu
- Visual Studio 2019/2022 (Community Edition miễn phí)
- .NET Framework 4.7.2 hoặc .NET 6/7/8
- PLC Keyence KV Series với Ethernet
- Kết nối mạng TCP/IP
Tạo Project trong Visual Studio
- File → New → Project → Windows Forms App (.NET Framework)
- Đặt tên: PLCKeyenceMonitor
- .NET Framework 4.7.2
- Click Create
Code C# đầy đủ
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace PLCKeyenceMonitor
{
public partial class Form1 : Form
{
private TcpClient tcpClient;
private NetworkStream networkStream;
private bool isConnected = false;
public Form1()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
string ip = txtIP.Text;
int port = int.Parse(txtPort.Text);
tcpClient = new TcpClient();
tcpClient.Connect(ip, port);
networkStream = tcpClient.GetStream();
isConnected = true;
UpdateStatus("Đã kết nối");
Log($"✅ Kết nối thành công: {ip}:{port}");
}
catch (Exception ex)
{
Log($"❌ Lỗi kết nối: {ex.Message}");
}
}
private void btnRead_Click(object sender, EventArgs e)
{
if (!isConnected) { Log("⚠️ Chưa kết nối PLC"); return; }
ReadDevice();
}
private void ReadDevice()
{
try
{
string device = txtDevice.Text;
byte[] frame = BuildMCProtocolFrame(device);
networkStream.Write(frame, 0, frame.Length);
byte[] buffer = new byte[256];
int bytesRead = networkStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
var result = ParseResponse(buffer);
if (result.value.HasValue)
Log($"📊 {device} = {result.value.Value}");
else
Log($"⚠️ Lỗi: {result.message}");
}
}
catch (Exception ex)
{
Log($"❌ Lỗi đọc: {ex.Message}");
}
}
private byte[] BuildMCProtocolFrame(string device)
{
// MC Protocol 3E Frame cho đọc device
using (var ms = new System.IO.MemoryStream())
{
ms.WriteByte(0x50); ms.WriteByte(0x00); // Subheader
ms.WriteByte(0x00); ms.WriteByte(0xFF); // Network
ms.WriteByte(0xFF); ms.WriteByte(0x03); // PC Number
ms.WriteByte(0x00); ms.WriteByte(0x0C); // Data length
ms.WriteByte(0x00); ms.WriteByte(0x10); // Monitoring timer
ms.WriteByte(0x01); ms.WriteByte(0x04); // Command: Read
ms.WriteByte(0x00); ms.WriteByte(0x00); // Subcommand
ms.WriteByte(0xA8); // Device code: DM
ms.WriteByte(0x64); ms.WriteByte(0x00); ms.WriteByte(0x00); // Address: 100
ms.WriteByte(0x01); ms.WriteByte(0x00); // Points: 1
return ms.ToArray();
}
}
private (ushort? value, string message) ParseResponse(byte[] data)
{
if (data.Length < 11) return (null, "Response too short");
ushort endCode = (ushort)(data[9] | (data[10] << 8));
if (endCode != 0) return (null, $"End code: {endCode:X4}");
if (data.Length >= 13)
{
ushort value = (ushort)(data[11] | (data[12] << 8));
return (value, "OK");
}
return (null, "No data");
}
private void UpdateStatus(string message)
{
lblStatus.Text = $"Trạng thái: {message}";
}
private void Log(string message)
{
txtLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}
");
}
}
}
Thiết kế Form
- GroupBox "Cấu hình kết nối": txtIP, txtPort
- GroupBox "Device": txtDevice (nhập DM100)
- Button: btnConnect, btnRead
- TextBox: txtLog (MultiLine, ScrollBars=Vertical)
- StatusStrip: lblStatus
Device Codes
- DM: 0xA8
- R: 0x9C
- MR: 0x90
- T: 0xC2
- C: 0xC3
Code dựa trên tài liệu Keyence KV Series. Tested với KV-7500 và KV-8000.
