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

        }
    }
}
相关推荐
枷锁—sha2 小时前
Burp Suite 抓包全流程与 Xray 联动自动挖洞指南
网络·安全·网络安全
云飞云共享云桌面2 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
爱学习的程序媛2 小时前
PSTN(公共交换电话网)的起源与发展
网络·信息与通信
roman_日积跬步-终至千里3 小时前
【Java并发】Java 线程池实战:警惕使用CompletableFuture.supplyAsync
java·开发语言·网络
2的n次方_3 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
E_ICEBLUE4 小时前
PPT 批量转图片:在 Web 预览中实现翻页效果(C#/VB.NET)
c#·powerpoint·svg
郝学胜-神的一滴5 小时前
深入浅出:使用Linux系统函数构建高性能TCP服务器
linux·服务器·开发语言·网络·c++·tcp/ip·程序人生
天若有情6735 小时前
【自研实战】轻量级ASCII字符串加密算法:从设计到落地(防查岗神器版)
网络·c++·算法·安全·数据安全·加密
胖咕噜的稞达鸭5 小时前
网络基础:初识TCP/IP协议
网络·网络协议·tcp/ip