ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

三菱FX系列PLC与PC上位机通讯全指南:从协议到C#实现

三菱FX系列PLC与PC上位机通讯全指南:从协议到C#实现 简介本资源是面向工业自动化开发者与PLC工程师的三菱FX系列PLC与PC通讯实战源码包解决上位机与FX系列控制器间数据读写、状态监控及远程控制等核心需求适用于设备集成、产线数据采集与HMI开发等场景。压缩包共47个文件含7个C源文件cpp、9个头文件h、1个Visual Studio解决方案sln及配套资源文件rc、res、ico等涵盖串口通信封装SerialComn.h/cpp、主界面逻辑PC_FXPLCDlg.cpp/h、寄存器读写模块PC_FXPLCDlg_RW.cpp/h及测试用例PC_FXPLCDlg_Test.cpp/h结构完整、模块清晰。资源大小为19.12MB已获195人学习下载。读者可直接编译运行快速掌握FX系列PLC通讯协议解析、寄存器地址映射、数据打包解包及错误重试机制等关键实现细节并基于现有框架扩展多设备通讯或接入上位机系统。 做工业上位机的朋友十有八九都绕不开三菱FX系列PLC。不管是给老设备加数据采集还是新项目里做MES对接第一步就是让PC和三菱PLC把话说上。网上关于这个话题的帖子零零散散要么只讲串口要么只有理论没有代码能把协议拆开揉碎、还能直接抄作业的文章真不多。这篇文章我打算把三菱FX系列PLC与PC通讯这件事从头到尾捋一遍。从通讯方案选型、协议帧结构、地址映射规则到C#上位机完整例程、变频器频率读写实战再到常见的坑和排查思路全给你安排上。不管你是刚接手设备改造的电气工程师还是第一次做上位机开发的软件工程师这篇文章都能让你少走不少弯路。1. 通讯方案选型先想清楚路怎么走三菱FX系列家族很大从老的FX2N、FX3U到现在的FX5U硬件接口和通讯能力差异不小。动手写代码之前一定要先搞清楚自己手里的PLC是什么型号、有什么通讯接口、现场有什么网络条件。这一步省了后面全是坑。1.1 串口通讯老设备改造的平稳路径FX2N和FX3U原生自带一个编程口物理上是圆头的RS-422接口通常用USB-SC09或者USB-SC09-FX这种编程电缆连到电脑。在很多车间里这种电缆几乎是调试标配工程师包里总有一根。但正经做上位机通讯走编程口有一条要求PLC的运行开关必须拨到RUN或者STOP之外的档位否则通讯可能不稳定。更关键的是编程口同一时间只能有一个主站如果你用GX Work2在线监控上位机就抢不到这个口必须等监控断开才能通讯。如果不想占用编程口可以给FX3U加一块通讯扩展板比如FX3U-232-BDRS-232或者FX3U-485-BDRS-485扩展出一个独立串口PLC程序和上位机各用各的口互不干扰。这在实际项目中是更稳妥的选择。串口通讯的优势是简单稳定9600波特率、偶校验一根线就搞定抗干扰能力在短距离内也够用。缺点是速度慢100米以上就得加485中继器而且只能一对一通讯。如果现场有多台PLC需要同时采集串口方案就会变得非常啰嗦。1.2 以太网通讯新项目的主流选择如果是FX5U天生自带以太网口直接网线连接交换机上位机走TCP/IP就能通讯速度和便利性都不是串口能比的。如果是FX3U也有两个选择加装FX3U-ENET以太网模块或者干脆换FX5U。FX3U-ENET模块支持MC协议上位机通过TCP连接PLC的端口号默认是2000以上具体看模块设置通讯效率高支持多客户端同时连接这是串口完全做不到的。新项目我一般都建议直接上以太网。原因很简单速度快百兆/千兆不占用串口资源可以多台上位机同时采集而且通讯距离只要在局域网内都不是问题。PLC程序侧也不需要额外写什么通讯代码MC协议是系统级的只要硬件支持上位机直接发起请求就行。1.3 选型对比场景不同选择不同对比项串口通讯编程口/232/485以太网通讯MC协议硬件要求FX2N/FX3U原生或扩展板FX5U内置/FX3UENET模块通讯速度9600bps~115200bps实际常用9600百兆/千兆网络连接数量基本一对一支持多客户端协议复杂度FX编程口协议帧结构简单MC协议帧结构稍复杂但稳定典型场景单台设备改造、环境简单多设备组网、MES/SCADA对接成本低一根电缆即可需要模块或换PLC选型说到底就是一道权衡题。如果你手头是FX2N、现场就一台设备、数据量也不大老老实实用串口方案省钱省事。如果是新上项目、现场有组网需求、或者日后要接数据库和MES直接走以太网别再纠结。2. 协议拆解读懂三菱的两套通讯语言方案定下来之后真正的硬骨头就是协议。三菱FX系列有两套常见的通讯协议经典FX编程口协议也叫计算机链接协议和MC协议三菱通用协议。前者多用于串口后者多用于以太网。两头都吃透了写代码才有底气。2.1 FX编程口协议串口通讯的核心FX编程口协议是一种基于ASCII字符的通讯协议帧结构很简单但每个细节都别理解错。请求帧格式如下STX | CMD | 地址(4字符) | 读取点数(2字符) | ETX | FCS(2字符)STX固定0x02一帧开始CMD命令字符批量读是00x30批量写是10x31地址4个ASCII字符是十六进制表示的起始地址读取点数2个ASCII字符十六进制表示ETX固定0x03一帧结束FCS2个ASCII字符十六进制表示的校验值FCS校验算法很关键从CMD字符开始到ETX为止把这些字符的ASCII码逐位异或得到的结果取低8位再转换成2个十六进制ASCII字符。用C#写就是先收集命令字符然后循环异或最后ToString(X2)。例如要读D100开始的4个字CMD0地址0064100的十六进制是64点数04帧内容0x02 0x30 0x30 0x30 0x36 0x34 0x30 0x34 0x03 [FCS]PLC正确应答的帧结构是ACK | ...数据... | STX | 数据 | ETX | FCS先收到一个ACK0x06然后接着是数据区最后是STX数据ETXFCS的部分。很多新手只盯着最后的STX找数据却忘了前面还有个ACK导致解析错位。2.2 MC协议以太网通讯的标准姿势MC协议是三菱的中大型PLCQ系列、L系列、FX5U通用的通讯协议在FX5U和FX3UENET模块上走TCP/IP。它有二进制模式3E帧和ASCII模式4E帧两种编码方式帧结构逻辑一样只是一个用二进制字节一个用ASCII字符。4E帧的请求格式大致这样以批量读字软元件为例副头 | 帧长度 | PLC编号 | 监视定时器 | 命令 | 子命令 | 起始软元件 | 软元件点数副头4个ASCII字符固定5000可省略看具体设备帧长度4个ASCII字符是从PLC编号到结束的字节数命令0401表示批量读子命令0000表示按字访问0001表示按位访问起始软元件软元件代码(2字符)地址(6字符)位号(1字符)软元件点数4个字符软元件代码有点讲究D寄存器是A8M继电器是90X输入是9CY输出是9D。地址则是6个字符的十六进制数比如D100的地址就是000064注意是6位。应答帧也很规律先是完成标志正常是0000紧跟着就是读回来的数据。我建议在调试阶段先用4E帧ASCII模式因为可以直接用串口调试工具看字符对着手册核对很方便。等通信稳定了想压榨性能再切3E帧二进制模式。2.3 地址映射从梯形图到上位机的桥不管是编程口协议还是MC协议上位机直接面对的是软元件地址而不是梯形图里那个直观的D100。所以代码里必须有一套地址转换逻辑。D寄存器在两种协议下基本一致就是寄存器编号转十六进制。比如D100编程口协议地址是0064MC协议是000064。但M继电器就有讲究了。FX编程口协议里M0对应地址0000M100对应0064看起来是编号直接转十六进制但M的软元件类型不同比如M0~M7679是一种M8000以后是特殊继电器有些型号会有地址偏移。这是最容易算错的地方。X和Y输入输出更麻烦FX系列是八进制编号X0、X1...X7、X10、X11...转成协议地址时还得先把八进制转成十进制再求十六进制。比如X7的编号是八进制7地址算出来还是0007但X10的编号是八进制10实际十进制是8地址就是0008。我的建议是不要自己在代码里裸算这些地址而是写一个地址映射工具类把所有换算逻辑集中管理这样哪一天遇到一个特殊的FX型号改一个地方就行不用满代码去找。实操中我在这个工具类上踩过的坑比在通讯代码本身踩的还要多。3. 实操C#上位机完整代码实现协议看懂了接下来就是动手。我用C#分别写一套串口通讯类和一套以太网通讯类都是在实际项目里跑过、验证过的代码。你会看到我刻意把帧构造、校验、解析三个环节拆成独立方法这是为了方便排查问题——出bug的时候能清晰定位到底是哪一段逻辑出了问题。3.1 串口通讯类手写协议读D寄存器三菱FX编程口协议用C#实现并不复杂核心就是拼帧、发帧、解析返回帧。下面是一个精简但完整的串口通讯类。using System; using System.IO.Ports; using System.Text; using System.Threading; public class FxSerialClient { private SerialPort _port; public FxSerialClient(string comPort, int baudRate 9600) { _port new SerialPort(comPort, baudRate, Parity.Even, 8, StopBits.One); _port.ReadTimeout 1000; _port.WriteTimeout 1000; } public void Open() _port.Open(); public void Close() _port.Close(); // 计算FCS校验值从数据起始索引到数据结束索引之间所有字节异或 private byte CalcFcs(byte[] data, int start, int end) { byte fcs 0; for (int i start; i end; i) { fcs ^ data[i]; } return fcs; } // 读取D寄存器 public ushort[] ReadD(int startAddress, int count) { // 地址转4位十六进制ASCII string addrHex startAddress.ToString(X4); // 点数转2位十六进制ASCII string countHex count.ToString(X2); // 请求帧主体不含STX和ETX string body 0 addrHex countHex; // 构建完整请求帧 Listbyte frame new Listbyte(); frame.Add(0x02); // STX frame.AddRange(Encoding.ASCII.GetBytes(body)); frame.Add(0x03); // ETX // 计算FCS从body起始字符到ETX之前 byte fcs CalcFcs(frame.ToArray(), 1, frame.Count); frame.AddRange(Encoding.ASCII.GetBytes(fcs.ToString(X2))); // 发送并接收 _port.Write(frame.ToArray(), 0, frame.Count); Thread.Sleep(50); int header3 _port.ReadByte(); // ACK if (header3 ! 0x06) { if (header3 0x15) { throw new Exception(PLC返回NAK请求被拒绝); } throw new Exception($PLC未返回ACK实际返回值: 0x{header3:X2}); } // 跳过数据区的第一个STX int stx2 _port.ReadByte(); if (stx2 ! 0x02) { throw new Exception($数据区STX错误: 0x{stx2:X2}); } // 读数据区长度每个寄存器2字节ASCII方式一字节一个字符共4字符 int dataLen count * 4; byte[] dataBuf new byte[dataLen]; int offset 0; while (offset dataLen) { int n _port.Read(dataBuf, offset, dataLen - offset); offset n; } // 读取ETX int etx _port.ReadByte(); if (etx ! 0x03) { throw new Exception($数据区ETX错误: 0x{etx:X2}); } // 读取FCS并校验 byte[] fcsBuf new byte[2]; _port.Read(fcsBuf, 0, 2); byte calcFcs CalcFcs(dataBuf, 0, dataBuf.Length); byte readFcs Convert.ToByte(Encoding.ASCII.GetString(fcsBuf), 16); if (calcFcs ! readFcs) { throw new Exception($FCS校验失败计算值: {calcFcs:X2}接收值: {readFcs:X2}); } // 解析数据每4个ASCII字符是一个16位寄存器值 ushort[] result new ushort[count]; for (int i 0; i count; i) { string hexStr Encoding.ASCII.GetString(dataBuf, i * 4, 4); result[i] Convert.ToUInt16(hexStr, 16); } return result; } }这份代码有几点值得说FCS校验的计算范围是从body的第一个字符到ETX之前千万别把STX算进去我当时第一次写就把STX也异或进去了结果永远对不上。PLC返回的数据区长度是点数乘以4因为每个寄存器在ASCII模式下是4个字符。但注意三菱这里返回的是高低字节反序的十六进制串比如寄存器里存的是0x1234返回来的ASCII是3412。我在代码里直接用Convert.ToUInt16(hex, 16)解析语义上其实不做字节交换因为上位机读出来之后要做数据换算到底怎么处理要看数据类型定义。实际项目里int16、uint16、float的高低位规则完全不同这块要格外小心。实际通讯中我加了一个50ms的延时这个是为了避免发送后立刻读取导致缓存不满。生产环境里最好改成按接收字节数循环读取配合ReadTimeout做兜底而不是固定睡眠。现场通讯慢的时候固定延时会拖慢采集周期。3.2 以太网通讯类基于MC协议的TCP读写以太网通讯用MC协议4E帧。下面是一个C#实现的TCP客户端核心逻辑一样是组帧、发送、解析应答。using System; using System.Net.Sockets; using System.Text; public class FxMcTcpClient { private TcpClient _tcp; private NetworkStream _stream; public void Connect(string ip, int port 2000) { _tcp new TcpClient(); _tcp.Connect(ip, port); _stream _tcp.GetStream(); _stream.ReadTimeout 2000; _stream.WriteTimeout 2000; } public void Close() { _stream?.Close(); _tcp?.Close(); } // 构建批量读请求帧4E帧 private byte[] BuildReadRequest(int startAddr, int count) { // 副头 string subHeader 5000; // PLC编号 string plcNo FF; // 监视定时器 string timer 0010; // 命令0401 批量读 string cmd 0401; // 子命令0000 字单位 string subCmd 0000; // 软元件代码D A8 string devCode A8; // 起始地址6位十六进制 string addr startAddr.ToString(X6); // 位号 string bitNo 0; // 点数 string countHex count.ToString(X4); string frame subHeader 0000 // 帧长度占位 plcNo timer cmd subCmd devCode addr bitNo countHex; // 帧长度 (总字符数 - 副头长度) / 2 int byteLen (frame.Length - subHeader.Length) / 2; frame subHeader byteLen.ToString(X4) frame.Substring(subHeader.Length 4); return Encoding.ASCII.GetBytes(frame); } // 读取D寄存器 public ushort[] ReadD(int startAddr, int count) { byte[] req BuildReadRequest(startAddr, count); _stream.Write(req, 0, req.Length); // 读取响应先读固定长度头部副头长度PLC编号定时器命令子命令 byte[] header ReadBytes(18); string headerStr Encoding.ASCII.GetString(header); // 检查完成标志命令后2字符正常是00 00 // 这里要注意帧长度字段之后是PLC编号、定时器、命令、子命令最后是完成代码 string completeCode headerStr.Substring(14, 4); if (completeCode ! 0000) { throw new Exception($PLC返回错误完成码: {completeCode}); } // 读取数据区每个寄存器4个ASCII字符 byte[] data ReadBytes(count * 4); ushort[] result new ushort[count]; for (int i 0; i count; i) { string hexStr Encoding.ASCII.GetString(data, i * 4, 4); result[i] Convert.ToUInt16(hexStr, 16); } return result; } private byte[] ReadBytes(int length) { byte[] buf new byte[length]; int offset 0; while (offset length) { int n _stream.Read(buf, offset, length - offset); if (n 0) throw new Exception(连接已关闭); offset n; } return buf; } }这段代码最需要注意的地方是帧长度的计算。4E帧的帧长度字段表示的是从PLC编号到帧末尾的字节数不包括副头本身。我写的时候容易把副头也算进去导致PLC一直收不到合法请求。另一个关键点是应答帧的解析。应答帧的前两个字符是副头5000接着是帧长度然后是PLC编号、监视定时器、命令、子命令再往下才是完成代码和数据。完成代码在解析时一定要检查否则PLC返回错误你可能当成正常数据处理现场会出大事。MC协议的好处是PLC不需要写任何通讯代码PLC程序和上位机通讯完全是并行关系。这一点和串口编程口协议有本质区别串口在PLC程序扫描周期内如果正好在执行通讯指令可能会干扰但MC协议是系统底层处理的稳定性高很多。3.3 工程案例读写变频器频率的完整链路看到这里你可能觉得有点抽象我拿一个真实场景来讲透它。热词里反复出现三菱PLC读取写入变频器频率这其实是工控领域最常见的应用之一。假定你手里的设备是FX3U通过RS485连接一台三菱FR-E740变频器现在要做一套PC上位机能实时显示变频器当前频率也能远程修改目标频率。整体通讯链路是这样的PC上位机通过编程口或以太网和PLC通讯PLC再通过RS485和变频器通讯。PLC在这里是个中转站它把变频器的运行频率读进某个D寄存器上位机只要读这个D寄存器就能显示频率上位机要把频率改到某个值就先把目标频率写进另一个D寄存器PLC程序检测到值变化后通过RS485把频率指令下发给变频器。这样说可能还有点抽象我拆成三步。第一步PLC侧程序。PLC通过RS485和变频器通讯可以用三菱的变频器通讯指令IVRD和IVWR。IVRD是读变频器参数IVWR是写变频器参数。梯形图里大致这样安排每100ms执行一次IVRD读取变频器当前运行频率存到D100和D10132位浮点同时检测D200的值是否发生改变一旦改变就执行IVWR把D200的值写入变频器的频率寄存器。这里的D200就是上位机写目标频率的入口D100就是上位机读实际频率的出口。PLC程序本身不算复杂但通讯状态的处理是要仔细想的比如变频器不在线时、通讯超时时你的PLC程序要保证不会卡死别让整个设备停下来。第二步上位机读频率。上位机只需要定时调用我们前面写的ReadD方法读D100和D101两个寄存器然后把这两个字拼成一个32位浮点数就是变频器的当前运行频率。很多人在这一步栽跟头因为三菱PLC里32位浮点数是用两个字存储的高低字顺序和C#的BitConverter默认顺序不一样通常需要自己做字节交换。第三步上位机写频率。上位机把目标频率转成32位浮点拆成两个16位字写入D200和D201。PLC程序检测到D200变化后自动把它下发到变频器。这里有个细节不是每次写都能成功上位机最好在写入之后再读回来核对一下形成闭环不然你改了频率现场没反应操作工要找你了。这个链路最大的好处是职责清晰PLC负责和变频器打交道上位机只跟PLC通信不需要关心Modbus RTU协议也不需要关心变频器寄存器地址。哪怕你现场换了一个不同品牌的变频器只要PLC程序改好上位机代码一行都不用动。3.4 数据解析与轮询策略上位机通讯开发中数据解析是基本功但轮询策略往往决定整个系统的稳定性。轮询方式最常见的是单线程顺序轮询上位机依次读取每个需要监控的寄存器组每组读完后等待一小段时间再读下一组。这种方式逻辑简单资源占用低适合寄存器数量不多、实时性要求不高的场景。但如果寄存器多或者一台电脑要连好几台PLC单线程顺序轮询就会很慢一个通讯超时就卡住后面所有数据。更稳妥的做法是把轮询放在后台线程用BlockingCollection或Channel管理读写请求队列每个请求设置独立的超时时间。读失败的寄存器不要立即重试而是标记为异常状态等到下一轮周期再读避免连续重试把CPU和串口占死。关于数据解析这里藏着一个大坑三菱FX系列PLC内部寄存器的字节序和C#平台不一样。FX的16位寄存器高字节在前还是低字节在前取决于数据是怎么写入的32位数据又牵扯到高低字顺序。所以建议在代码里写几个通用的解析工具方法比如FloatFromWords(high, low)、Int32FromWords(high, low)把字节序处理集中起来。实测下来这是排查数据不对时最头疼的地方没有之一。网络环境不稳定的情况我也遇到过。上位机在车间里Wi-Fi时好时坏串口偶发干扰这时候轮询策略和超时重试机制就是保命符。我的经验是超时时间设成500ms到2秒之间不要设太短连续3次重试失败后把这个设备标记为离线不要无限重试离线后自动进入断线重连流程恢复后把数据追平然后继续正常轮询。这套逻辑写好了系统长时间运行基本不用人管。4. 常见问题与排查技巧实录写代码一时爽现场调试火葬场。做上位机通讯这么多年我踩过的坑都能写一本手册了。这里挑几个高频问题整理成排查列表希望对你有用。4.1 通讯超时无应答现象请求发出去PLC那边什么反应都没有上位机一直等最后超时。排查思路从硬件到软件一层层来先确认物理连接串口线是否完好、线序是否正确、网线是否插好、PLC的通讯口是否被别的软件占用。确认通讯参数波特率、校验位、数据位、停止位和PLC侧是否完全一致。FX3U默认9600、偶校验、8位、1停止位但如果你改了PLC参数上位机也要跟着改。确认PLC处于RUN状态。有些老型号PLC在STOP状态下编程口通讯不响应这是正常现象。用串口调试助手抓一下返回数据。如果发请求后连ACK都收不到大概率是物理层或者PLC通讯参数的问题如果收到ACK但后续数据不完整那就是时序问题调整读取超时时间或者增加接收缓冲区长度。4.2 FCS校验失败现象能收到PLC的返回帧程序报FCS校验失败。这个问题的根源几乎都是校验计算范围搞错了。FX编程口协议中FCS要从CMD字符开始算一直算到ETXSTX不参与校验。很多人一着急把STX也算进去算出来自然对不上。另外有个容易忽略的细节FCS结果是十六进制的两位ASCII字符比如计算值是0x5A你要发的是5和A这两个ASCII字节而不是0x5A这一个字节。这个问题在串口调试时特别容易暴露出来因为你看缓冲区里字节数不对一数就发现少了一个。4.3 数据错位或值不对现象能收到数据读回来的值跟PLC监控软件里看到的完全对不上。这种情况十有八九是字节序或数据类型的问题。同样的两个字节按int16解析是一个值按uint16解析是另一个值按Modbus大端还是小端又不一样。还有32位数据高位字在D100、低位字在D101还是反过来全看PLC程序怎么存放的。我的排查方法很简单在PLC里给D寄存器写一个已知值比如1234十六进制0x04D2这个值在协议报文里会显示为D2 04还是04 D2一眼就能看出字节序规则。先用已知值做测试再解析真实数据能省下一大半时间。4.4 PLC返回NAK错误码现象上位机收到ACK之后的NAK或者PLC直接返回错误码0x15。NAK0x15表示PLC拒绝了你的请求。错误码紧跟其后一般有两个ASCII字符比如02表示地址越界03表示命令格式错误。遇到NAK先别急着改上位机代码先到PLC侧确认D寄存器是否存在、地址是否在合法范围内。很多FX2N的D区范围只有0~7999你读D8000当然会返回错误。另外注意FX2N和FX3U的软元件范围不完全一样同样的地址在FX3U上合法在FX2N上可能是非法的。代码里最好在启动时读一次PLC型号或者通过通讯测试来确定支持范围。4.5 串口被占用打不开现象上位机提示串口打开失败或者打开后收不到任何数据。常见原因有两个。一是你开了GX Work2或者GX Developer在监控PLC编程口被占了。解决办法很简单调试上位机的时候把PLC编程软件完全关掉。二是你电脑上插了多个USB转串口设备COM口号对不上到设备管理器里看一下实际分配的COM口改成代码里用的那个。如果用了USB转串口的线还有一个隐患USB转串口芯片不稳定电脑休眠唤醒后COM口会失效。所以生产环境里我建议上位机加上串口拔插检测功能检测到串口消失就提示用户重新插拔或者自动重新初始化。4.6 网络环境不好时的一些处理建议现场网络环境不好可能是车间里Wi-Fi干扰大也可能是有路由器IP冲突。我的做法是在代码里做了几层防护第一所有以太网通讯都设置极短的连接超时1~2秒不要用系统默认的20多秒。这样断线了能快速感知。第二读失败不要立刻重试把设备标记为异常等下一轮轮询再处理。第三长时间离线后自动重连重连成功后先把关键数据读一遍把离线期间的数据空洞补上。这几点看着简单但真的能让上位机在恶劣网络环境下的可用性提升一大截。5. 经验心得几个实用建议和扩展方向最后聊点实在的。做三菱FX系列PLC和PC通讯这件事我的核心建议就三条。第一能用现成库就别自己造轮子。HslCommunication这个开源库我用了好几年对三菱FX系列支持得非常好从编程口协议到MC协议全覆盖而且代码质量高、文档完整。自己写代码确实能学到东西但生产项目里时间就是金钱别跟现成库过不去。前提是你要能看懂它内部的协议实现万一出问题能快速定位。第二调试阶段一定要配一个串口/网络调试助手。发什么报文、收什么报文一目了然。很多问题你不用看代码就能判断出来是协议组错了还是物理链路不稳调试助手能帮你省下一半的排查时间。第三代码结构上把协议解析和业务逻辑彻底分开。通讯层只负责收发字节流和解析帧业务层只负责处理数据。这样你以后从串口切换到以太网、或者从FX3U迁移到FX5U的时候只需要换通讯层业务层完全不用动。后续扩展的方向也很多。最常见的是把采集到的数据写到数据库里做历史趋势分析和报表再进一步可以和MES系统对接把设备状态、产量数据实时上报还有人在做多台PLC的集中监控一台电脑同时采集十几台设备的数据这时候以太网方案的优势就体现出来了串口完全撑不住这种规模。我在实际项目中摸索出一个比较顺手的组合PLC走以太网MC协议上位机用HslCommunication做通讯层业务数据存到本地SQLiteWeb端通过API读取展示。这套组合从数据采集到展示全链路打通维护起来也不累。FX系列PLC虽然老但在中小型设备控制领域依然占据着大量份额掌握好它的通讯技术这个技能很长时间内都不会过时。如果你正在做类似的项目卡在某一步走不下去不妨按我文章里的思路先梳理一下通讯方案选了什么、协议帧格式对不对、地址换算对不对、调试工具有没有用起来。大部分问题出在这几个环节而不是代码本身。搞定了这些你的FX系列PLC上位机通讯就能顺顺当当跑起来。本文还有配套的精品资源点击获取
返回列表