Hướng dẫn tạo Windows Desktop App C# kết nối PLC Keyence KV Series – Đọc Device DM100

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.

Bài viết đã được tạo 2

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Bài liên quan

Bắt đầu nhập từ khoá bên trên và nhấp enter để tìm kiếm. Nhấn ESC để huỷ.

Trở lên trên