返回主站|会员中心|保存桌面

尼得科变频器专营    

变频器,驱动器

联系方式
  • 联系人:姚经理
  • 电话:18520143666
新闻分类
  • 暂无分类
首页 > 新闻中心 > C#与FX5U通过以太网SLMP通讯!
新闻中心
C#与FX5U通过以太网SLMP通讯!
发布时间:2025-11-13        浏览次数:2        返回列表

C# 与三菱 FX5U PLC 通过以太网基于 SLMP(Seamless Message Protocol)协议通讯,是工业自动化中实现上位机与 PLC 数据交互的常用方式。SLMP 是三菱专用协议,支持 TCP/UDP 传输,可实现对 PLC 软元件(如 D 寄存器、M 继电器、X/Y 输入输出等)的读写操作。以下是具体实现步骤和代码示例:

一、前期准备

1. 硬件与软件环境

  • PLC:FX5U 系列(需配备以太网模块,如 FX5-ENET/IP)。

  • 上位机:安装 Visual Studio(2019/2022),用于编写 C# 程序。

  • 网络连接:PLC 与上位机通过交换机或直连网线连接,确保 IP 地址在同一网段(如 PLC:192.168.3.3;上位机:192.168.3.100)。

2. PLC 侧设置(GX Works3)

  • 配置以太网参数

    1. 在 GX Works3 中打开项目,进入 “参数”→“模块参数”→“以太网模块”,设置 PLC 的 IP 地址(如192.168.3.3)、子网掩码(255.255.255.0)。

    2. 启用 SLMP 协议:在 “SLMP 设置” 中勾选 “允许 SLMP 连接”,端口号默认5007(可自定义,需与上位机一致)。

  • 写入程序并运行:确保 PLC 处于运行状态(RUN 模式)。

二、SLMP 协议基础

SLMP 通讯通过发送特定格式的报文实现数据读写,核心是帧结构命令码

  • 帧结构(TCP 模式)

    字段长度(字节)说明
    报头(Header)4固定为50 00 00 00
    网络号1默认为00
    站号1默认为FF(广播)或 PLC 站号
    预留2固定为00 00
    命令码204 01(读软元件)、14 01(写软元件)
    子命令码2区分操作类型(如软元件类型)
    数据长度2后续数据的字节数
    数据内容N软元件地址、长度、数据等
  • 常用命令码

    • 读软元件:04 01

    • 写软元件:14 01

三、C# 实现 SLMP 通讯(TCP 模式)

1. 核心步骤

  1. 建立 TCP 连接(目标 IP 为 PLC 的 IP,端口号 5007)。

  2. 构造 SLMP 读写报文(按帧结构拼接字节数组)。

  3. 发送报文并接收 PLC 响应。

  4. 解析响应数据,提取或验证结果。

2. 代码示例(读写 D 寄存器)

csharp

using System;using System.Net.Sockets;using System.Text;namespace FX5U_SLMP_Communication{
    class FX5UCommunicator
    {
        private TcpClient client;
        private NetworkStream stream;
        private string plcIp;
            {
                client = new TcpClient(plcIp, port);
                stream = client.GetStream();
                return true;
        // 断开连接
        public void Disconnect()
        {
            stream?.Close();
            client?.Close();
        }

        // 读取D寄存器(示例:读D100开始的2个寄存器)
        public ushort[] ReadDRegister(ushort startAddress, ushort count)
        {

            // 起始地址(D100 → 0x0064)
            command[14] = (byte)(startAddress >> 8); // 高8位
            command[15] = (byte)(startAddress & 0xFF); // 低8位
            // 数量(2个寄存器 → 00 02)
            command = command.Concat(new byte[] { 0x00, 0x02 }).ToArray();

            try
            {
                // 发送命令
                stream.Write(command, 0, command.Length);
                // 接收响应(响应长度 = 报头4 + 状态2 + 数据长度2 + 数据n + 校验等,此处简化处理)
                byte[] response = new byte[1024];
                int bytesRead = stream.Read(response, 0, response.Length);

                // 解析响应(假设成功,提取数据)
                // 响应数据从第10字节开始,每个D寄存器占2字节(高低位互换)
                ushort[] result = new ushort[count];
                for (int i = 0; i < count; i++)
                {
                    // 三菱数据为大端模式,需转换为小端
                    result[i] = (ushort)((response[10 + i * 2 + 1] << 8) | response[10 + i * 2]);
                }
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine("读取失败:" + ex.Message);
                return null;
            }
        }

        // 写入D寄存器(示例:向D100写入1234,D101写入5678)
        public bool WriteDRegister(ushort startAddress, ushort[] data)
        {
            if (!client.Connected || data == null) return false;

            // 构造SLMP写命令报文
            int dataLength = 2 + 2 + data.Length * 2; // 地址(2) + 数量(2) + 数据(n*2)
            byte[] command = new byte[14 + dataLength];
            // 报头
            command[0] = 0x50;
            command[1] = 0x00;
            command[2] = 0x00;
            command[3] = 0x00;
            // 网络号、站号
            command[4] = 0x00;

                stream.Write(command, 0, command.Length);
                // 接收响应,验证是否成功(响应第8-9字节为00 00表示成功)
                byte[] response = new byte[1024];
                int bytesRead = stream.Read(response, 0, response.Length);
                return response[8] == 0x00 && response[9] == 0x00;
            }
            catch (Exception ex)
            {
                Console.WriteLine("写入失败:" + ex.Message);
                return false;

    // 测试代码
    class Program
    {
        static void Main(string[] args)
        {
            FX5UCommunicator comm = new FX5UCommunicator("192.168.3.3");
            if (comm.Connect())
            {
                Console.WriteLine("连接成功!");

                // 读取D100-D101
                ushort[] readData = comm.ReadDRegister(100, 2);
                if (readData != null)
                {
                    Console.WriteLine($"D100: {readData[0]}, D101: {readData[1]}");
                }

                // 写入D100=1234, D101=5678
                bool writeSuccess = comm.WriteDRegister(100, new ushort[] { 1234, 5678 });
                Console.WriteLine("写入结果:" + (writeSuccess ? "成功" : "失败"));

                comm.Disconnect();
            }
            Console.ReadKey();
        }
    }}

四、关键说明

  1. 数据格式转换:三菱 PLC 采用大端模式(高位字节在前),而 C# 默认是小端模式,读写时需注意高低位互换(如ushort类型数据拆分与拼接)。

  2. 软元件子命令码:不同软元件对应不同子命令码,例如:

    • X/Y 输入输出:00 01

    • M 继电器:00 00

    • D 寄存器:00 02

    • W 寄存器:00 03

  3. 错误处理:PLC 响应报文中的第 8-9 字节为状态码,00 00表示成功,非 0 则为错误(如01 01表示地址错误),需根据状态码调试。

  4. 效率优化:频繁读写时建议使用长连接(保持 TCP 连接不中断),减少连接建立开销;批量读写比单次读写更高效。

五、常见问题

  • 连接失败:检查 IP 地址、端口号是否正确,PLC 是否处于 RUN 模式,防火墙是否拦截端口。

  • 数据读写错误:确认子命令码与软元件类型匹配,地址是否超出 PLC 范围(如 FX5U 的 D 寄存器最大地址),数据高低位是否正确转换。

通过上述方法,C# 可稳定与 FX5U 通过 SLMP 协议通讯,实现工业数据采集与控制逻辑。

收缩
  • QQ咨询

  • 电话咨询

  • 18520143666
  • 添加微信客服