基于C#实现欧姆龙PLC FINS_TCP通信

一、通信协议基础

1. FINS/TCP协议框架

// FINS帧结构示例(读取DM区)
byte[] frame = new byte[26]
{
    0x46,0x49,0x4E,0x53,  // FINS标识
    0x00,0x00,            // 数据长度(后续计算)
    0x00,0x00,            // 保留字段
    0x00,0x01,            // 目标网络号
    0x00,0x01,            // 目标节点号
    0x00,0x00,            // 目标单元号
    0x00,0x00,            // 源网络号
    0x0A,0x00,            // 源节点号(PC端)
    0x00,0x00,            // 源单元号
    0x01,0x01,            // 服务ID(01读/02写)
    0x01,0x00,            // 命令码(01读/02写)
    0x02,0x00,            // 数据区域(02=DM)
    0x00,0x00,0x00,0x00,  // 起始地址(高位在前)
    0x00,0x0A,            // 数据长度(10个字)
    0x00                  // 错误码
};

2. 关键参数配置

参数 默认值 说明
IP地址 192.168.250.1 PLC端IP需与PC同网段
端口号 9600 FINS/TCP标准端口
服务ID 0x01 01=读,02=写
数据区域代码 0x02 02=DM区,0x30=CIO区

二、开发环境搭建

1. 开发工具配置

// 使用.NET Framework 4.7.2及以上版本
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

2. PLC连接配置

// PLC参数类
public class OmronPLCConfig
{
    public string IpAddress { get; set; } = "192.168.250.1";
    public int Port { get; set; } = 9600;
    public byte SourceNode { get; set; } = 0x0A; // PC节点号
    public byte DestinationNode { get; set; } = 0x01; // PLC节点号
}

三、核心通信实现

1. TCP连接管理

public class OmronFinsClient
{
    private TcpClient _client;
    private NetworkStream _stream;
    
    public bool Connect(OmronPLCConfig config)
    {
        try
        {
            _client = new TcpClient();
            _client.Connect(config.IpAddress, config.Port);
            _stream = _client.GetStream();
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"连接失败: {ex.Message}");
            return false;
        }
    }
    
    public void Disconnect()
    {
        _stream?.Close();
        _client?.Close();
    }
}

2. FINS帧构造

private byte[] BuildReadFrame(ushort startAddr, ushort length)
{
    byte[] frame = new byte[26 + 2 * length];
    
    // 固定头部
    Array.Copy(new byte[] { 0x46,0x49,0x4E,0x53 }, 0, frame, 0, 4);
    Array.Copy(BitConverter.GetBytes(2 + 2 + 2 + 2 + length * 2), 0, frame, 4, 4); // 数据长度
    
    // 地址信息
    Array.Copy(BitConverter.GetBytes(0x00000000), 0, frame, 8, 4); // 目标地址
    Array.Copy(BitConverter.GetBytes(0x0A000000), 0, frame, 12, 4); // 源地址
    
    // 命令参数
    frame[16] = 0x01; // 服务ID
    frame[17] = 0x01; // 命令码(读)
    frame[18] = 0x02; // 数据区域(DM)
    Array.Copy(BitConverter.GetBytes(startAddr), 0, frame, 19, 2);
    Array.Copy(BitConverter.GetBytes(length), 0, frame, 21, 2);
    
    // 计算数据长度
    ushort dataLength = (ushort)(2 + 2 + 2 + length * 2);
    Array.Copy(BitConverter.GetBytes(dataLength), 0, frame, 4, 2);
    
    return frame;
}

3. 数据读写操作

public byte[] ReadData(ushort startAddr, ushort length)
{
    try
    {
        byte[] request = BuildReadFrame(startAddr, length);
        _stream.Write(request, 0, request.Length);
        
        byte[] buffer = new byte[1024];
        int bytesRead = _stream.Read(buffer, 0, buffer.Length);
        return buffer.Take(bytesRead).ToArray();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"读操作失败: {ex.Message}");
        return null;
    }
}

public bool WriteData(ushort startAddr, ushort[] values)
{
    try
    {
        ushort length = (ushort)values.Length;
        byte[] frame = new byte[26 + 2 * length];
        
        // 构建写命令帧(代码结构类似读命令,需修改服务ID和命令码)
        // ...省略头部构建...
        
        // 写入数据
        Array.Copy(BitConverter.GetBytes(startAddr), 0, frame, 19, 2);
        Array.Copy(BitConverter.GetBytes(length), 0, frame, 21, 2);
        Array.Copy(BitConverter.GetBytes(values), 0, frame, 23, 2 * length);
        
        _stream.Write(frame, 0, frame.Length);
        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"写操作失败: {ex.Message}");
        return false;
    }
}

四、通信测试与调试

1. 使用Wireshark验证

  1. 过滤FINS协议:tcp.port == 9600
  2. 典型通信流程: 客户端发送FINS请求帧 PLC返回ACK确认帧 数据传输阶段 连接终止帧

2. 异常处理策略

// 重连机制
public bool Reconnect(OmronPLCConfig config, int retryCount = 3)
{
    for(int i=0; i<retryCount; i++)
    {
        if(Connect(config)) return true;
        Task.Delay(1000).Wait();
    }
    return false;
}

// 心跳检测
private async Task KeepAlive()
{
    while(true)
    {
        await Task.Delay(30000);
        SendKeepAlivePacket();
    }
}

推荐代码 C#开发欧姆龙TCP通讯 www.youwenfan.com/contentcng/51558.html

五、高级功能实现

1. 批量数据读写优化

// 使用异步操作提升性能
public async Task<byte[]> AsyncRead(ushort startAddr, ushort length)
{
    return await Task.Run(() => ReadData(startAddr, length));
}

// 分块传输大块数据
public void WriteLargeData(ushort startAddr, ushort[] values)
{
    const int chunkSize = 128; // 每包128字
    for(int i=0; i<values.Length; i+=chunkSize)
    {
        ushort end = (ushort)Math.Min(i+chunkSize, values.Length);
        WriteData(startAddr + i, values.Skip(i).Take(chunkSize).ToArray());
    }
}

2. 数据解析示例

public Dictionary<string, object> ParseResponse(byte[] response)
{
    var result = new Dictionary<string, object>();
    
    // 解析头部
    ushort dataLength = (ushort)(response[4] << 8 | response[5]);
    
    // 解析数据区
    if(response[16] == 0x01) // 读响应
    {
        ushort addr = (ushort)(response[19] << 8 | response[20]);
        ushort count = (ushort)(response[21] << 8 | response[22]);
        ushort[] data = new ushort[count];
        for(int i=0; i<count; i++)
        {
            data[i] = (ushort)(response[23 + 2*i] << 8 | response[24 + 2*i]);
        }
        result["data"] = data;
    }
    
    return result;
}

六、工程实践建议

  1. 网络配置规范

    • PLC IP段:192.168.250.x(x为1-254)
    • 子网掩码:255.255.255.0
    • 禁用PLC防火墙
  2. 性能优化方案

    • 使用连接池管理TCP连接
    • 实现数据缓存机制
    • 采用二进制协议替代ASCII
  3. 安全增强措施

    // 添加HMAC-SHA256校验
    private byte[] AddChecksum(byte[] data)
    {
        using(var hmac = new HMACSHA256(key))
        {
            byte[] hash = hmac.ComputeHash(data);
            return data.Concat(hash).ToArray();
        }
    }
    

七、调试工具推荐

  1. Omron FINS调试助手:官方提供的命令构造工具
  2. SocketTool:第三方TCP调试工具
  3. Wireshark:网络协议分析工具
  4. PLC模拟器:使用Sysmac Studio进行离线测试

该方案完整覆盖了C#与欧姆龙PLC的TCP通信开发全流程,开发者可根据实际需求调整数据解析逻辑和通信参数。建议结合Sysmac Studio进行PLC端配置,并通过日志系统记录通信异常。

posted @ 2025-09-10 16:02  kiyte  阅读(446)  评论(0)    收藏  举报