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");

        }
    }
}
相关推荐
源远流长jerry25 分钟前
DPDK 内存管理深度解析:从大页到 Mbuf 的完整链路
linux·服务器·网络
大鹏说大话1 小时前
Java 锁膨胀机制深度解析:从偏向锁到重量级锁的进化之路
开发语言·c#
Predestination王瀞潞2 小时前
5.4.2 通信->WWW万维网内容访问标准(W3C):WWW(World Wide Web) 核心技术规范
网络·网络协议·https·www
@insist1232 小时前
软件设计师-组网技术基础:网络设备、传输介质与局域网核心协议
开发语言·网络·软考·软件设计师·软件水平考试
虾..2 小时前
TCP协议
网络·网络协议·tcp/ip
上去我就QWER2 小时前
详解HTTP协议中的multipart/form-data
网络·网络协议·http
武藤一雄3 小时前
WPF处理耗时操作的7种方法
microsoft·c#·.net·wpf
@encryption3 小时前
TCP,IP
服务器·网络·tcp/ip
武藤一雄4 小时前
C#常见面试题100问 (第一弹)
windows·microsoft·面试·c#·.net·.netcore
F1FJJ4 小时前
我用一条命令把内网的 RDP 桌面开到了浏览器里 —— Shield CLI 与主流隧道工具的技术对比
网络·golang