C#与三菱PLC FX5U通信

目录

一.报文格式

[1. Read](#1. Read)

[2. Write](#2. Write)

[二.C# Code](# Code)

此篇是C#与三菱PLC FX5U使用Socket进行通信

相当于使用Socket建立通信发送报文给PLC读取和写入PLC program中的内容

一.报文格式

head = 500000FF03FF00

1. Read

假设我想读取M4001寄存器中的内容

message = head+ dataLength + writeCmd + digit

readCmd = monitorTime + 04010000 + M* + startAddress + digit

monitorTime(4位): 0010 // 2*250ms(替换成十进制的2)

M*:是M寄存器的意思(如果其他寄存器,则是D*)

startAdd(6位): 001000 //M1000,如果是M100,则是000100

digit(4位) : 0001 //读取一位的意思

readCmd = 0010 04010000 M* 001000 0001

dataLength :writeCmd的十六进制长度

message = 500000FF03FF00 0018 0010 04010000 M* 004001 0001

2. Write

writeCmd = monitorTime + 14010000 + M* + startAddress + digit + m

上述部分与上面一样

m: 0000 close

0001 open

writeCmd = 0010 14010000 M* 004001 0001 0001

dataLength :writeCmd+m的十六进制长度
message = 500000FF03FF00 0018 0010 14010000 M* 004001 0001 0001 //打开M4001寄存器

二.C# Code

lift.cs

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace SF_lift
{
    public class Lift
    {
        public Socket client;
        public IPEndPoint serverEndPoint;
        public string head = "500000FF03FF00";
        public string MonitorTime = "0010";  //监视器时间2*250ms=0.5s
        public string wCmd;
        public string rCmd;
        public string totalWrite;
        public string totalRead;
        public string writeMessage;
        public string readMessage;
        public byte[] msg_bytes;
        public byte[] msg_bytes1;
        public byte[] response;
        public int bytesRead;

        public Lift(string IP, int port)
        {
            this.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.serverEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
            this.client.Connect(this.serverEndPoint);
            Console.WriteLine("已连接到lift服务器");
        }

        //写入x寄存器x100一位
        //x:register编号   x=D*, x=M*  比如M寄存器,D寄存器
        //startAdd格式(6位):000100, digit格式(4位):0001
        //m(输入状态4位) 0001:on    0000:off
        public void write(string x,string startAdd,string digit,string m)
        {
            this.wCmd = this.MonitorTime+"14010000"+ x + startAdd + digit;
            this.writeMessage = this.head + (this.wCmd+m).Length.ToString("X4") +this.wCmd+ m;
            this.msg_bytes = Encoding.ASCII.GetBytes(this.writeMessage);
            this.client.Send(msg_bytes);

            // 接收响应
            byte[] buffer = new byte[1024]; 
            // 缓冲区大小可根据协议调整
            int bytesRead = this.client.Receive(buffer);
            // 转成字符串并打印
            string response = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("响应内容: " + response);
        }

        //x:register编号   x=D*, x=M*  比如M寄存器,D寄存器
        //startAdd:000100, digit = 0001
        //读取x寄存器x100一位
        public void read(string x,string startAdd, string digit)
        {
            this.rCmd = this.MonitorTime + "04010000" + x + startAdd + digit;
            this.readMessage = this.head + this.rCmd.Length.ToString("X4") + this.rCmd;
            this.msg_bytes1 = Encoding.ASCII.GetBytes(this.readMessage);
            this.client.Send(msg_bytes1);
            this.response = new byte[1024];
            this.bytesRead = this.client.Receive(this.response);
            string respStr = Encoding.ASCII.GetString(this.response, 0, this.bytesRead);
            Console.WriteLine("响应字符串:" + respStr);

            // 解析最后的数据部分 
            // 响应格式: D000...0008 0000 [数据] 
            // 最后4位就是数据值
            if (respStr.Length >= 4) 
            { 
                string dataValue = respStr.Substring(respStr.Length - 4); 
                // 取最后4位
                string status = dataValue == "0001" ? "enable" : 
                dataValue == "0000" ? "disable" : "未知"; 
                Console.WriteLine($"寄存器 {x}{startAdd} = {dataValue} ({status})"); 
            }

        }

    }
}

program.cs

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SF_lift
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Lift lift1 = new Lift("10.0.1.130", 5000);
            lift1.read("M*", "004001", "0001");

            Lift lift = new Lift("10.0.1.130", 5001);
            lift.write("M*", "004100", "0001", "0000");

        }
    }
}
相关推荐
Scout-leaf20 小时前
WPF新手村教程(三)—— 路由事件
c#·wpf
用户298698530141 天前
程序员效率工具:Spire.Doc如何助你一键搞定Word表格排版
后端·c#·.net
mudtools2 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的2 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
唐宋元明清21883 天前
.NET 本地Db数据库-技术方案选型
windows·c#
DianSan_ERP3 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
lindexi3 天前
dotnet DirectX 通过可等待交换链降低输入渲染延迟
c#·directx·d2d·direct2d·vortice
呉師傅3 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑
qq_454245033 天前
基于组件与行为的树状节点系统
数据结构·c#
bugcome_com3 天前
C# 类的基础与进阶概念详解
c#