去年做一条老产线的设备升级,遇到个挺典型的需求:现场有一批RS485接口的仪表和变频器,控制器换成了支持以太网通信的PLC,可原来的上位系统、触摸屏都走网口,新PLC自带的串口又不够用。整条线拆了重改代价太大,最好的办法就是让PLC用TCP通信,经过一个网口转串口的小设备,把网络报文转成RS485去操作底下的老设备。
当时用的PLC是汇川Easy320(AM320系列,InoProShop编程环境),转接设备是常见的串口服务器。这个方案做完之后我记了不少踩坑笔记,今天整理出来,给正在折腾汇川PLC以太网通信、或者想把老旧串口设备并入以太网系统的朋友一个参考。不管你是电气工程师、设备维护还是搞自动化集成的,这篇都能帮你在调试路上少走几趟弯路。
1. 整体设计与思路拆解
1.1 方案本质:网络包变成串口字节流
说穿了,“网口转串口控制设备”就是把PLC的TCP/IP报文,经过串口服务器的协议转换,变成RS232/RS485总线上的字节流,让那些只认串口的仪表、变频器、温控器能够被以太网侧的PLC控制。整个过程对PLC来说,它只是在做一个正常的TCP Client连接,而对下位机来说,它看到的还是传统的串口通信。
这种架构的长处在于:
- 老设备不用换,省下大量改造成本
- 物理布线简单,网线比RS485走得更远、抗干扰更好
- 一台PLC可以通过网络访问多台串口服务器,相当于扩展了N个串口
1.2 为什么选汇川Easy320
选它不是因为指标多惊艳,而是当时的实际需求推动的:项目要求必须用国产品牌,现场又需要PLC带以太网口、支持多路TCP连接,还要有灵活的自由协议通信能力。Easy320在这个价位上把点数和通信接口给得比较足,InoProShop基于CODESYS V3.5内核,支持结构文本(ST)、梯形图等编程方式,做通信协议拼包、解析时用ST会比梯形图顺手得多。
实测下来,Easy320的Socket通信功能可以同时维持好几个TCP连接,运行稳定性也扛得住长时间的轮询。对中小型项目来说够用了。
1.3 网口转串口的选型逻辑
串口服务器这个市场已经非常成熟,有简化版只做TCP转RS485透传的,也有带Modbus网关功能的高级货。选型时重点看这几个参数:
- 串口电平:RS485半双工还是RS232全双工,老设备是哪种接口必须对应
- 工作模式:透传(Transparent)还是Modbus网关(Modbus Gateway)
- 以太网口速率:10/100M即可,串口设备通信速率一般也就9600bps到115200bps
- 供电方式:现场没有合适电源的话,优先选支持PoE或者宽压供电的型号
我自己用的是一款支持网页配置的串口服务器(USR-N510类型,具体型号按你手里的采购清单走),它既有透传模式也有Modbus网关模式,两种模式在实际项目里都有用,后面会详细说。
2. 硬件连接与串口服务器配置
2.1 硬件清单和接线表
列举一下调试时需要的材料,避免到现场东缺西缺:
| 序号 | 物料 | 数量 | 备注 |
|---|---|---|---|
| 1 | 汇川Easy320 PLC | 1台 | 带以太网口,InoProShop编程 |
| 2 | 串口服务器(USR-N510类) | 1台 | 至少1路RS485,支持TCP Server/Client |
| 3 | 笔记本电脑 | 1台 | 用于配置PLC和串口服务器 |
| 4 | 网线/交换机 | 若干 | PLC、电脑、串口服务器组同一个局域网 |
| 5 | RS485屏蔽线 | 若干 | 串口服务器到变频器/仪表 |
| 6 | 24V开关电源 | 1个 | 给串口服务器供电 |
有线时记住一条原则:RS485的A/B线不能接反,屏蔽层单端接地。有些老工程师会告诉你“A接B没关系,试一下就知道”,我不建议这么干,带多个从站时A/B接反会导致整条总线通信异常。
2.2 串口服务器的网络参数配置
拿到串口服务器先别急着往PLC程序里写,第一步是把它本身的参数配置对。大多数串口服务器支持网页配置,默认IP一般印在机身标签上。
我的操作习惯是:
- 把电脑的IP改成和串口服务器默认IP同网段(比如设备是192.168.1.7,就把电脑设成192.168.1.8)
- 浏览器打开默认IP,进登录页面(账密参考说明书,一般是admin/admin)
- 先把IP设成现场局域网地址,比如192.168.1.30,子网掩码255.255.255.0,网关按现场填
- 设置串口参数:波特率、数据位、停止位、校验位,一定要和变频器/仪表侧完全一致
- 选择工作模式
关于工作模式,我后面会做一个对比。这里先提一下:
- 透传模式(TCP转TTL/RS485):串口服务器把收到的TCP数据原封不动转成串口字节流,把串口收到的字节流打包成TCP发给PLC。适合非标协议设备
- Modbus网关模式:PLC发Modbus TCP报文,串口服务器自动转成Modbus RTU报文往RS485上发。PLC侧写程序更简单,但前提是下位设备必须走Modbus协议
2.3 PLC与串口服务器组网
接好线、配好串口服务器参数后,先别急着写PLC程序。我习惯先把网络连通性确认好:
- PLC的IP设成192.168.1.10,串口服务器设成192.168.1.30
- 电脑IP设成192.168.1.8
- 三者都接入同一台交换机或路由器
- 电脑上ping 192.168.1.10和192.168.1.30,确认都能通
如果ping不通,优先查IP是否冲突、网线是不是好的、防火墙是不是拦了ICMP。这个环节别偷懒,网络不通时去查通信程序会浪费大量时间。
3. 汇川Easy320侧TCP通信程序实现
3.1 在InoProShop里新建工程
打开InoProShop,新建项目时选择Easy320对应的CPU型号。不同固件版本对通信库的支持略有差异,建议做通信项目前把PLC固件升级到官方最新版,避免踩到老版本bug。
建好工程后,在库管理器里添加通信相关的库。InoProShop基于CODESYS内核,系统库里有Socket通信相关的功能块,一般叫TcpClientOpen、TcpClientSend、TcpClientReceive之类。如果你那版软件里名字不同,可以在库管理器里搜一下含“Tcp”或者“Socket”关键字的库,选中添加到工程就行。
这里有个经验:初次上手时,先用最简单的例程跑通“连接→发送→接收”再往里面填业务逻辑,不要一上来就写全功能程序,不然排查问题时会混成一团。
3.2 TCP Client连接管理
Easy320作为TCP Client去连接串口服务器,先要做连接管理。下面这个ST程序片段展示了核心逻辑:
VAR // TCP连接相关状态 fbTcpOpen : TcpClientOpen; // 系统库提供的TCP连接功能块 fbTcpSend : TcpClientSend; // 发送功能块 fbTcpReceive : TcpClientReceive; // 接收功能块 eOpenState : INT; // 连接状态输出 bDoConnect : BOOL := TRUE; // 触发连接 bConnected : BOOL := FALSE; // 已连接标志 sRemoteIP : STRING := '192.168.1.30'; // 串口服务器IP uiRemotePort : UINT := 5000; // 串口服务器TCP端口 bSendRequest : BOOL := FALSE; // 触发发送 bStartReceive : BOOL := FALSE; // 触发接收 bRecvDone : BOOL := FALSE; // 接收完成 END_VAR连接建立的调用模式大致是:
// 未连接时尝试建立TCP连接 IF NOT bConnected THEN fbTcpOpen(ipAddress := sRemoteIP, uiPort := uiRemotePort, execute := bDoConnect); eOpenState := fbTcpOpen.state; IF eOpenState = ESTABLISHED THEN bConnected := TRUE; bDoConnect := FALSE; END_IF END_IF实际项目里不建议让连接建立和业务处理交织在一个周期里,最好用状态机把“等待连接”“建立成功”“正常通信”“异常重连”区分开。CODESYS风格的程序里,通信状态机是一个很常见的写法,好处是逻辑清晰,出了故障能快速定位是连不上还是发送卡住。
3.3 Modbus RTU请求封包与CRC计算
现在到了整个方案最关键的环节:PLC通过TCP把Modbus RTU请求发给串口服务器,由串口服务器透传到RS485总线上,驱动变频器或仪表返回数据。所谓“手把手”,实际上就是在教你这个报文怎么拼、怎么算校验、怎么解析返回值。
以“读从站地址为1的变频器运行频率”为例(Modbus功能码03,从寄存器0x0000开始读1个字),标准的Modbus RTU请求帧是:
01 03 00 00 00 01 CRC_L CRC_H其中:
- 01:从站地址
- 03:功能码(读保持寄存器)
- 00 00:起始寄存器地址高8位、低8位
- 00 01:读取寄存器数量
- CRC_L CRC_H:CRC16校验值,低字节在前
CRC16-Modbus的计算逻辑可以用ST写一个函数:
FUNCTION F_CRC16_MODBUS : WORD VAR_INPUT pData : POINTER TO BYTE; uiLen : UINT; END_VAR VAR i : UINT; j : INT; crc : WORD := 16#FFFF; byte : BYTE; END_VAR FOR i := 0 TO uiLen - 1 DO byte := pData[i]; crc := crc XOR byte; FOR j := 0 TO 7 DO IF (crc AND 16#0001) <> 0 THEN crc := (crc SHR 1) XOR 16#A001; ELSE crc := crc SHR 1; END_IF; END_FOR; END_FOR; F_CRC16_MODBUS := crc;注意Modbus RTU协议要求CRC低字节先发、高字节后发,所以拼报文时要把计算出来的WORD拆开,先放低8位,再放高8位。这个细节很多人第一次写都会栽跟头,我也是调了半小时才发现高低字节反了,从站一直返回错误。
组装请求报文的核心逻辑如下:
// 示例:读取从站1,启动地址0x0000,长度1 // 报文结构:01 03 00 00 00 01 CRC_L CRC_H // 使用数组作为发送缓冲区,先填字节,再调用CRC函数,最后填CRCCRC计算这个函数写好后,可以复用在所有Modbus RTU请求构建场景里,无论是读还是写、是变频器还是仪表,只要有Modbus协议就能用。这也是“网口转串口”玩法里最值钱的一段代码。
3.4 完整通信流程与代码组织
我的程序组织方式是分成三个主要Part:
- Part 1:周期发送请求:用一个定时器,每500ms触发一次发送。发送内容根据业务需求变化:读频率、读电流、写启停、写给定频率等
- Part 2:接收与解析:每次发送完成后打开接收窗口(比如等待50ms),把收到的字节存入接收缓冲区,然后按Modbus RTU报文格式解析出从站地址、功能码、数据段
- Part 3:数据映射:把解析到的原始值转换成工程量(比如频率寄存器值除以100得到Hz),更新到全局变量里供HMI或上位机使用
下面是一个简单的发送程序示意:
// 启动周期发送 IF bConnected AND TON_500ms.Q THEN TON_500ms(IN := FALSE); // 构建读请求:功能码03,起始地址0x0000,数量1 txBuffer[0] := 16#01; txBuffer[1] := 16#03; txBuffer[2] := 16#00; txBuffer[3] := 16#00; txBuffer[4] := 16#00; txBuffer[5] := 16#01; crcValue := F_CRC16_MODBUS(ADR(txBuffer[0]), 6); txBuffer[6] := LOBYTE(crcValue); // CRC低字节 txBuffer[7] := HIBYTE(crcValue); // CRC高字节 bSendRequest := TRUE; TON_500ms(IN := TRUE); END_IF这类代码用ST写非常直观,用梯形图写就会绕很多。所以我对通信功能的建议是:哪怕你平时习惯梯形图,通信相关的模块也用ST来写,调试效率高得多。
3.5 接收解析与数据有效性判断
接收端要注意的是:串口服务器是透传的,它把RS485总线上的原始字节流一股脑打包TCP发过来,PLC收到的不一定正好是一帧完整的Modbus RTU报文,可能会多收、少收,需要自己做组帧判断。
我常用的解析方法是:
- 判断接收缓冲区长度是否大于等于6个字节(最简述:地址+功能码+至少4字节数据)
- 校验CRC是否正确
- 校验从站地址是否匹配
- 根据功能码解析数据
如果接收超时(我给的是50ms),就清空缓冲重新等下一帧。这里有个小技巧:先把接收缓冲区在每次发送完成后清零,再开始等应答,不然上一轮的遗留数据会干扰解析。
4. 常见问题与排查技巧实录
4.1 通信故障速查表
把我在调试过程中最常见的几个故障整理成一张表,方便你带去现场对照:
| 故障现象 | 可能原因 | 排查与解决 |
|---|---|---|
| TCP始终连接不上 | IP/端口配置错误、串口服务器未上电、网线松动 | 先ping通设备,再检查端口号,确认串口服务器监听模式和端口一致 |
| 能连上但收不到任何数据 | 串口参数(波特率/校验位)不匹配 | 核对RS485设备的通信参数,串口服务器和从站必须完全一致 |
| 收到数据但CRC校验失败 | 报文拼错、CRC高低字节颠倒 | 用Modbus调试工具抓包比对,检查CRC发送顺序 |
| 数据间歇性丢失 | RS485走线过长、A/B接反、未接地 | 检查屏蔽层接地,缩短总线长度,降低波特率到9600bps |
| PLC重启后通信恢复不了 | 缺少断线重连逻辑 | 在程序里做连接状态监控,掉线后自动重新执行TcpOpen |
4.2 关于透传模式与Modbus网关模式的取舍
前面提到串口服务器有两种工作模式,这里展开说下取舍逻辑。
用透传模式时,所有Modbus RTU报文的拼包、CRC校验、超时重发都要在PLC里自己做。好处是灵活,不管下位设备走什么私有协议,只要你能用字节流描述通信过程,它就能工作。坏处是程序量相对大,而且对PLC处理器的周期占用要仔细评估。
用Modbus网关模式时,串口服务器内部集成了Modbus RTU和Modbus TCP的转换逻辑,PLC只需要按Modbus TCP格式发送请求(功能码、起始地址、数量、数据),剩下的RTU封装、CRC校验由串口服务器自动完成。这对程序员最友好,但前提是下位设备必须标准支持Modbus协议,且串口服务器固件对特殊功能码的兼容性要好。
我的实际经验是:如果下位机是标准变频器或智能仪表,优先选Modbus网关模式,省心省力;如果你面对的是老式定制设备、PLC本身又要处理非标协议,那就老老实实走透传模式,程序麻烦一点,但什么情况都能控制。
4.3 三个特别值得注意的坑
坑一:连接状态不能只看“通了”
调试时经常遇到TCP连接已经建立,但是发出去的命令没有响应。这种问题的根源往往不在网络层,而在串口侧的参数匹配。手动排查时,可以先关掉PLC程序,用电脑上的TCP调试工具直接连串口服务器,手动发送一条CRC正确的Modbus RTU请求,看从站有没有回应。这一步能把故障范围快速缩小——如果电脑发命令设备也没反应,那问题在串口参数或接线;如果电脑发有反应、PLC发没反应,再看PLC程序。
坑二:通信周期不要写得太激进
有些刚上手的朋友喜欢把发送周期调到100ms甚至50ms,觉得这样响应快。但RS485是半双工总线,从站处理指令也需要时间,而且串口服务器内部有转发延迟。我一般把周期设在300ms到500ms之间,实测完全能满足产线控制需求,通信稳定性和总线寿命都更有保障。对速度有极端要求的控制场景,就尽量不要用网口转串口这条链路了,直接选带EtherCAT或Profinet的驱动器更合适。
坑三:掉线重连必须做成自动的
TCP连接不像串口那么“健忘”,它有一个明显的状态。但现场环境复杂,交换机重启、网线松动、串口服务器死机都可能导致TCP连接失效。如果不做掉线重连,PLC可能一直维持一个半死不活的连接对象,后续发送全部失败。我的做法是:每个扫描周期都读取连接状态,一旦发现非ESTABLISHED状态,立即释放连接资源,延时2秒后重新触发TcpOpen。实测下来,即使串口服务器断电重启,PLC也能自动恢复通信,不需要人工干预。
5. 性能优化与后续扩展
5.1 多从站轮询策略
如果一台串口服务器下面挂了8台、16台变频器,逐个轮询太慢。常规优化手段是:
- 把多个寄存器的读取合并成一条报文,减少往返次数
- 把不频繁变化的参数(如额定电流、最高频率)放到大间隔轮询,把实时参数(频率、电流、状态字)放到小间隔轮询
- 根据协议允许的最长间隔做分时处理,避免总线拥堵
比如读取1号到10号变频器的运行频率(每个站的频率地址都是0x0000),依然需要分站读取,因为Modbus是主从一对多架构,从站地址不同没法合并。但每台变频器可以把“运行频率、输出电流、母线电压、状态字”一次性读回,用一条读保持寄存器指令读4个字,比发4条指令快得多。
5.2 从串口扩展到以太网设备的场景
这套方案的思路完全可以平移到别的场景中:
- 用网口转串口操作老式条码枪、RFID读卡器
- 通过串口服务器把多台RS485电表接入PLC做能源监测
- 把温湿度传感器、温控器的数据汇总到上位机
原理都一样:PLC利用TCP Socket把字节流发到串口服务器,再由串口服务器匹配对应物理接口的速率和协议,变成RS485/RS232信号。学会这一个链路以后,几乎可以应对所有“网络主站控制串口从站”的需求。
5.3 关于用InoProShop调试通信的一些建议
调试这类通信程序,有几个工具能大幅提高效率:
- Modbus调试工具(如Modbus Poll/ModScan):先用电脑模拟主站验证从站和串口服务器这条链路是否正常
- Wireshark抓包:抓取PLC和串口服务器之间的TCP包,确认数据确实发出去了、内容是否正确
- 串口服务器自带的TCP调试工具:很多型号支持网页上的调试页面,可以直接从网页发测试数据给串口,顺手验证RS485是否正常
个人经验是:先工具验证链路,再写PLC程序,至少能省半天调试时间。
6. 结尾心得
这套“Easy320 + TCP + 网口转串口”的组合,我后来在好几个项目里都复用了,一次比一次顺手。要说最深的体会,就是搞工业通信,三分靠配置、七分靠协议——串口参数的匹配和报文的正确组装,比单纯“把线接上”重要得多。
如果你第一次搞这个,建议先拿一台变频器、一台串口服务器、一台PC把链路跑通,再接入PLC去做联调。别一上来就追求全套设备一次打通,通信这东西,一次叠加太多变量,出了问题很难定位。先用最简单的模式(电脑发、设备回)验证基础链路,再一步一步增加程序逻辑层次,你会觉得整个调试过程顺畅很多。