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

伟肯变频器中国区域服务商    

伟肯变频器

联系方式
  • 联系人:吴经理
  • 电话:18576370666
  • 邮件:18576370666@163.com
新闻分类
  • 暂无分类
站内搜索
 
首页 > 新闻中心 > C#与FX5U通过以太网SLMP通讯!
新闻中心
C#与FX5U通过以太网SLMP通讯!
发布时间:2025-11-10        浏览次数:3        返回列表

C# 与三菱 FX5U PLC 通过以太网基于 SLMP(Seamless Message Protocol,无缝消息协议)通讯,是工业自动化中实现上位机与 PLC 数据交互的常用方式。SLMP 是三菱专用以太网协议,支持读写 PLC 的软元件(寄存器、继电器等),以下是详细实现步骤:

一、前期准备

1. 硬件与软件环境

  • PLC:FX5U 系列(需配备以太网接口,如内置或通过 FX5-ENET/IP 模块扩展)。

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

  • 网络连接:PLC 与 PC 通过网线连接(直连或同局域网,确保 IP 地址在同一网段)。

2. PLC 端设置(GX Works3)

  • 设置 IP 地址:在 GX Works3 中,打开 PLC 参数→以太网端口设置,配置 PLC 的 IP 地址(如192.168.3.100)、子网掩码(255.255.255.0),与 PC 的 IP(如192.168.3.1)保持同一网段。

  • 启用 SLMP 服务:FX5U 默认支持 SLMP 协议(端口号5007),无需额外设置,确保 “以太网通信设置” 中未禁用该协议。

  • 测试连接:在 PC 端通过ping 192.168.3.100验证网络通畅。

二、SLMP 协议基础

SLMP 通讯通过报文帧实现数据交互,核心是构建符合格式的请求帧,PLC 响应后解析返回帧。

1. 帧结构(精简版,适用于 FX5U)

  • 请求帧(PC→PLC)

    字节位置含义示例(读 D100)
    0-1指令长度(字节数)00 0C(共 12 字节)
    2-3指令代码(读:04 01;写:04 0204 01(读指令)
    4-5软元件代码(D 寄存器:00 0200 02(D 寄存器)
    6-9软元件地址(D100→00 00 00 6400 00 00 64(100)
    10-11读取数量(1 个→00 0100 01
  • 响应帧(PLC→PC):成功时返回数据,失败时返回错误码(如05 01表示地址错误)。

三、C# 实现步骤(基于 TCP/IP)

1. 建立 TCP 连接

通过TcpClient类与 PLC 的 5007 端口建立连接:

csharp

using System;using System.Net.Sockets;using System.Text;public class FX5U_SLMP{
    private TcpClient client;
    private NetworkStream stream;
    private string plcIp; // PLC的IP地址
    private int port = 5007; // SLMP默认端口

    public FX5U_SLMP(string ip)
    {
        plcIp = ip;
    }

    // 连接PLC
    public bool Connect()

2. 构建 SLMP 请求帧(以读 D 寄存器为例)

需将请求参数转换为符合 SLMP 格式的字节数组:

csharp

/// <summary>/// 读取D寄存器/// </summary>/// <param name="address">寄存器地址(如100→D100)</param>/// <param name="count">读取数量</param>/// <returns>读取的值(整数数组)</returns>public int[] ReadD(int address, int count){
    if (!client.Connected) return null;

    // 构建请求帧
    byte[] command = new byte[12];
    // 指令长度(12字节)
    command[0] = 0x00;
    command[1] = 0x0C;
    // 读指令代码(04 01)
    command[2] = 0x04;
    command[3] = 0x01;
    // 软元件代码(D寄存器:00 02)
    command[4] = 0x00;
    command[5] = 0x02;
    // 地址(4字节,高位在前)
    byte[] addrBytes = BitConverter.GetBytes((uint)address);
    Array.Reverse(addrBytes); // 转换为大端模式
    Array.Copy(addrBytes, 0, command, 6, 4);
    // 读取数量(2字节,高位在前)
    byte[] countBytes = BitConverter.GetBytes((ushort)count);
    Array.Reverse(countBytes);
    Array.Copy(countBytes, 0, command, 10, 2);

    // 发送请求
    stream.Write(command, 0, command.Length);

    // 接收响应(响应长度=8 + 2*count,8字节为头部)
    byte[] response = new byte[8 + 2 * count];
    int bytesRead = stream.Read(response, 0, response.Length);

    // 解析响应(成功时第2-3字节为00 00)
    if (response[2] != 0x00 || response[3] != 0x00)
    {
        Console.WriteLine("读取失败,错误码:" + response[2].ToString("X2") + response[3].ToString("X2"));
        return null;
    }
    return result;}

3. 写 D 寄存器实现

类似读操作,指令代码为04 02,并附加要写入的数据:

csharp

/// <summary>/// 写入D寄存器/// </summary>/// <param name="address">起始地址</param>/// <param name="values">要写入的值</param>/// <returns>是否成功</returns>public bool WriteD(int address, int[] values){
    if (!client.Connected) return false;
    int count = values.Length;
    int frameLength = 12 + 2 * count; // 基础12字节 + 2字节/数据
    byte[] command = new byte[frameLength];

    // 指令长度
    byte[] lenBytes = BitConverter.GetBytes((ushort)frameLength);
    Array.Reverse(lenBytes);
    Array.Copy(lenBytes, 0, command, 0, 2);
    // 写指令代码(04 02)
    command[2] = 0x04;
    command[3] = 0x02;
    // 软元件代码(D寄存器:00 02)
    command[4] = 0x00;
    command[5] = 0x02;
    // 地址
    byte[] addrBytes = BitConverter.GetBytes((uint)address);
    Array.Reverse(addrBytes);
    Array.Copy(addrBytes, 0, command, 6, 4);
    // 写入数量
    byte[] countBytes = BitConverter.GetBytes((ushort)count);
    Array.Reverse(countBytes);
    Array.Copy(countBytes, 0, command, 10, 2);
    // 写入数据(每2字节一个值,大端模式)
    for (int i = 0; i < count; i++)
    {
        byte[] data = BitConverter.GetBytes((ushort)values[i]);
        Array.Reverse(data);
        Array.Copy(data, 0, command, 12 + i * 2, 2);
    }

    // 发送请求
    stream.Write(command, 0, command.Length);

    // 接收响应(8字节)
    byte[] response = new byte[8];
    stream.Read(response, 0, 8);

    // 验证响应(00 00表示成功)
    return response[2] == 0x00 && response[3] == 0x00;}

4. 断开连接

csharp

public void Disconnect(){
    stream?.Close();
    client?.Close();}

四、调用示例

csharp

class Program{
    static void Main(string[] args)
    {
        FX5U_SLMP plc = new FX5U_SLMP("192.168.3.100");
        if (plc.Connect())
        {
            // 读D100的值
            int[] readData = plc.ReadD(100, 1);
            if (readData != null)
                Console.WriteLine("D100的值:" + readData[0]);

五、关键注意事项

  1. 数据格式转换:SLMP 协议使用大端模式(高位在前),而 C# 默认是小端模式,需通过Array.Reverse()转换字节序,否则会出现数据错误(如地址或值读取异常)。

  2. 软元件代码对应表:不同软元件对应不同代码(如 M 继电器:00 01,Y 输出:00 03),需根据需求修改请求帧的第 4-5 字节:

    软元件代码(Hex)软元件代码(Hex)
    X00 00D00 02
    Y00 03W00 04
  3. 异常处理:需添加超时处理(client.ReceiveTimeout = 1000)、断线重连逻辑,避免程序因网络波动卡死。

  4. 批量读写优化:频繁读写时,尽量批量操作(如一次读 10 个 D 寄存器),减少通讯次数,提高效率。

六、工具推荐

  • Wireshark:抓包分析 SLMP 报文,验证请求 / 响应帧是否正确。

  • GX Works3 监控:在 PLC 端监控软元件值,确认 C# 程序读写是否生效。

通过以上步骤,可实现 C# 与 FX5U 的 SLMP 以太网通讯,适用于数据采集、远程控制等场景。

收缩
  • QQ咨询

  • 电话咨询

  • 18576370666
  • 添加微信客服