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

        }
    }
}
相关推荐
花间相见8 小时前
【计算基础|网络14】网络层:IP、ICMP 与 ping
网络·网络协议·tcp/ip
半杯咖啡半行码10 小时前
Linux 驱动开发入门:内核模块编程基础
linux·服务器·网络
智能直播10 小时前
RK3528 V4L2 框架 UVC 接口自动获取 H.264 / MJPEG / YUYV 格式:从内核采集到硬解分发
java·网络·实时音视频·视频编解码·h.264
睿智の男孩11 小时前
MIG IP核对DDR3的输出时序分析记录
网络·网络协议·tcp/ip
艾芯微科技11 小时前
高充放电流锂电充放 SoC:ETA9885E10,便携储能、小移动电源 BOM 选型笔记
网络·单片机·嵌入式硬件·集成测试·51单片机
2401_8685347811 小时前
数据交换方式
服务器·网络
艾芯微科技11 小时前
钰泰 ETA6973PQ3Y|QFN3×3 2A 同步降压 Buck,I2C 可配置多档输出,动态调压 PMIC
网络·单片机·嵌入式硬件·fpga开发·集成测试·51单片机
默|笙11 小时前
【Linux网络】_udp_socket(认识)
linux·网络·udp
2401_8685347812 小时前
以太网物理层标准
服务器·网络