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

        }
    }
}
相关推荐
KKKlucifer5 小时前
拨开接口黑盒迷雾:运营商第三方合作接口安全审计与准入管控落地实践
网络·人工智能·安全
青瓦梦滋6 小时前
传输层UDP/TCP协议
linux·网络·c++·网络协议·tcp/ip·udp
江畔柳前堤6 小时前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
小绫网络安全6 小时前
【每日一讲】学习网络安全的一些注意事项
网络·安全·web安全
椒颜皮皮虾྅7 小时前
OpenVINO C# API 3.3.1:支持OpenVINO 2026.3及GenAI增强
人工智能·c#·openvino
星恒讯工业路由器8 小时前
5G LAN + Wi-Fi 6融合组网:工业路由器如何为柔性产线“剪掉辫子”
网络·5g·工业路由器·工业物联网·5g la·柔性产线·5g工业路由
SamChan909 小时前
PDF翻译API的JWT签名鉴权与速率限制设计:安全实战指南
网络·安全·pdf
xiaoxiangsiyan9 小时前
HCIA 网络技术基础核心模块详解
运维·网络·网络协议·tcp/ip·运维开发·网络基础
AGCSDNl10 小时前
葛姓的来源
网络
半亩码田10 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#