ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

欧姆龙CP1H自由口通讯与台达VFD-M变频器Modbus RTU实战指南

欧姆龙CP1H自由口通讯与台达VFD-M变频器Modbus RTU实战指南

之前接手过一个现场改造项目,设备上摆着几台台达VFD-M变频器驱动风机和泵,原来全靠人在面板上调启停和频率。甲方想在中控室远程操作,还要把运行数据收回来。这个需求非常典型,而我最后给的方案,就是用欧姆龙CP1H的自由口通讯(也叫无协议通讯)功能,直接组Modbus RTU报文和变频器对话。

自由口通讯这名字听着高大上,实际就是把串口完全交给用户程序控制,想发什么字节就发什么字节,协议自己拼。好处是灵活,坏处是仪式感全得自己扛。台达VFD-M这类小型变频器基本都内置Modbus RTU从站协议,只要把报文拼对,启停、调速、读频率、读电流全都能通过一对RS-485线搞定。

这篇文章把整个链路完整讲一遍:Modbus RTU报文格式、VFD-M寄存器地址、CP1H串口参数设置、TXD/RXD指令用法、梯形图逻辑骨架,最后是现场调试最容易踩的坑和排查顺序。适合正在做设备改造、或者第一次接触自由口通讯想要个完整参考的同行。

1. 自由口通讯的典型用武之地:从一次现场改造说起

先算一笔需求账。原方案里,每台变频器要启停、要调速、要频率反馈,如果用模拟量控制,每一路都要单独占PLC的模拟量通道,几台设备下来通道数和接线成本都很可观。而且4-20mA或者0-10V信号在动力电缆旁边跑,抗干扰能力有限,频率显示跳来跳去的情况我见过太多次。

RS-485通讯方案就清爽多了:一根屏蔽双绞线把所有变频器串下去,启停、调速、监视全包在数字帧里。数字信号对共模干扰的容忍度比模拟量高不少,线缆成本也大幅下降。这个项目里PLC正好用的是欧姆龙CP1H,CPU自带RS-232C口,扩展一块CP1W-CIF11板还能直接拉出RS-422/485口,做自由口通讯几乎零额外成本。

1.1 通讯控制相比模拟量控制的取舍

模拟量方案不是没用,它胜在逻辑简单、响应直接,不依赖任何协议解析。可它的硬伤是一一对应:每个模拟量点要占一个通道,通道不够就得加扩展模块,扩展模块价格不低。而通讯方式物理层只涉及一对线,多台设备并联在同一总线上,以后加设备也只是总线再挂一台的事情,不用重新布线。

通讯控制的第二个优势是双向性。下发运行命令的同时能读取运行电流、输出频率、母线电压、故障代码等一堆监视数据,这些信息用模拟量做的话,通道数量直接翻倍,根本不合算。第三个优势是抗干扰。Modbus RTU这种数字帧在收到噪声时大概率表现为"整帧丢弃、无响应",而模拟量信号会表现为"数据缓慢漂移",前者靠重发机制能恢复,后者往往让人在程序里找半天原因。

当然通讯方案也有代价:程序复杂度明显提高,时序、超时、重发、CRC校验都要自己处理;一旦总线上某个设备因为接线问题把线路拉死,整条总线都会受影响。所以后面讲程序时,我会把超时、重发、故障报警这些工程化处理作为重点。这些内容是任何手册都不会替你操心的。

1.2 CP1H自由口通讯的整体链路

CP1H的自由口通讯本质上是把串口交给用户程序,通过TXD和RXD两条指令直接收发字节流。它和那些内置Modbus主站功能的PLC不一样,从站地址怎么填、功能码怎么用、CRC16怎么算,全由程序自己组。

整体链路大致是:CP1H内置串口模式设为无协议,程序里按Modbus RTU格式组装报文,TXD指令把报文发到串口,RS-232转RS-485转换器把电平转成总线信号,VFD-M作为从站应答,PLC再通过RXD指令把响应收回来,程序做CRC校验和数据分析。简单说就是四个动作循环往复:拼报文、发出去、收回来、解析。

2. Modbus RTU报文格式与台达VFD-M寄存器解析

通讯这件事,核心是对齐话术。PLC问得对不对,决定变频器理不理你。所以先把Modbus RTU报文结构吃透,后面所有程序逻辑都建立在它上面。

2.1 RTU报文的基本结构

Modbus RTU报文由四部分组成:从站地址、功能码、数据区、CRC16校验。每个部分都是十六进制字节,整体一次性发出去。举个例子,读1号站输出频率的完整请求是:

01 03 20 02 00 01 CRC_L CRC_H

拆开看:01是站号,03是"读保持寄存器"功能码,20 02是寄存器起始地址(即十六进制的0x2002),00 01表示读取1个寄存器,最后两字节是由前面所有字节算出来的CRC16校验值。

功能码里面最常用的就两个:03读寄存器,06写单个寄存器。03可以一次连续读多个寄存器,06一次只能写一个。如果要写多个参数,可以用10H功能码,但VFD-M这类小型变频器的应用场景里很少需要批量写,我通常就只用03和06。

有一个特别容易搞错的地方:CRC两个字节发送时是低字节在前、高字节在后。我第一次调试就栽在这里,把高低字节放反了,变频器一直不给反应,排查费了快半天。后面详解。

2.2 VFD-M的寄存器地址映射

台达VFD-M的Modbus寄存器大致分两类:控制类和监视类。以我实测过的那个固件版本,常用地址如下。

寄存器方向含义数据说明
0x2000写运行命令0=停止,1=正转,2=反转
0x2001写频率指令单位0.01Hz,50.00Hz写5000
0x2100读输出频率单位0.01Hz,返回数值除以100
0x2101读输出电流单位0.01A,返回数值除以100

这段话我必须强调一句:不同生产批次的VFD-M地址定义可能有细微差异,最终以随机附带操作手册里的"通讯协议"章节为准。我做程序时的习惯是把这些地址统一定义成符号常量,真发现不对只改一处,不至于满程序找魔法数。

有了地址表,报文拼装就有依据。写启动命令的报文是:

01 06 20 00 00 01 CRC_L CRC_H

表示1号站,用06功能码,往0x2000寄存器写入数据0001,即启动正转。写频率指令的报文是:

01 06 20 01 13 88 CRC_L CRC_H

0x1388换算成十进制是5000,对应50.00Hz。这里的寄存器值是十六进制数据,也就是两个字节,高字节在前,低字节在后,这是Modbus的大端字节序。

2.3 CRC16校验怎么在PLC里做

CRC是Modbus RTU的看门狗,任何一个字节算错,从站直接无视整帧。算法本身不神秘:多项式0xA001,初值0xFFFF,操作流程是每个字节先和CRC低字节异或,然后右移8次,每次最低位为1就再异或0xA001。

在电脑里写这段算法几行就完事,但在梯形图里逐位操作非常啰嗦。CP1H支持ST语言,我建议直接在CX-Programmer里用ST写一个子程序,梯形图里调用。参考逻辑如下:

// 假设输入是报文缓冲区Data,长度Len crc := 16#FFFF; FOR i := 0 TO Len - 1 DO crc := crc XOR WORD(Data[i]); FOR j := 0 TO 7 DO IF (crc AND 1) = 1 THEN crc := (crc SHR 1) XOR 16#A001; ELSE crc := crc SHR 1; END_IF; END_FOR; END_FOR; // 按Modbus要求,发送时CRC低字节放前,高字节放后

如果只会梯形图,也可以用循环指令和移位指令把这段算法翻译过去,就是程序会长不少。计算完的CRC附加到报文尾部时,低字节放倒数第二位,高字节放最后一位,千万别反。

3. 通讯链路搭建设置:PLC和变频器两端一次配齐

很多通讯调不通,问题根本不在程序,而是物理链路和两端参数没对齐。这节把接线、变频器参数、PLC串口设置一次讲完。

3.1 RS-485接线与常见误区

CP1H内置串口是RS-232C,只有TX、RX、GND三根信号,要挂RS-485总线需要一只RS232转RS485转换器。市面上常见的无源转换器就能用,但更推荐选带隔离的型号,现场稳定性好很多。转换器的485端分出A和B两根线,接到变频器的通讯端子上。

VFD-M的通讯端子一般标X1、X2,也有批次标D+、D-,顺着端子接就行,不用纠结名字。最容易踩的坑是A/B接反。很多转换器标的A/B和变频器标的D+/D-并不严格同名,有时候你的A恰好对应变频器的B。接完如果不通,第一件事就是把这两根线对调一下,这比怀疑程序管用多了。

其他接线要点:

  • 通讯线用屏蔽双绞线,屏蔽层在PLC这一端单点接地,不要在变频器端也接地,否则容易形成地环路,反而引入干扰。
  • 总线较长、或者变频器台数超过3台时,在最远端一台变频器的端子那里并联一只120Ω终端电阻,防止信号反射。
  • 通讯线务必远离变频器输出动力线,不要走同一个线槽,间隔至少20厘米以上,否则高频开关噪声会直接耦合进通讯链路。

3.2 台达VFD-M侧的参数设置

VFD-M的参数是按组编号的,通讯相关的集中在00组。现场需要确认的主要是五处:

参数设定值作用
00-101从站地址,对应报文里的站号
00-11对应9600波特率,必须和PLC一致
00-12对应8E1数据格式,8数据位、偶校验、1停止位
频率来源参数通讯主频率命令来源改为Modbus给定
运转信号来源参数通讯启停命令来源改为Modbus给定

波特率和数据格式的设定值在不同批次面板上显示不同,有的直接显示9600,有的显示数字编号,改完必须对照说明书确认。这里有个关键点:如果只设了通讯地址和波特率,却没把频率来源和运转信号来源切换成通讯,那PLC发多少命令变频器都不会理它——因为设备还在等着面板按键呢。不少"参数全设了怎么不动作"的求助,问题就出在这一步。

3.3 欧姆龙CP1H侧的串口设置

在CX-Programmer左侧工程树里双击"设置",打开"串口1"选项卡。内置RS-232C口对应串口1,扩展的CP1W-CIF11 485板对应串口2,设置逻辑完全相同。

需要改三个地方:

  • 通信设置:波特率选9600,格式选8位、偶校验、1停止位,和变频器完全一致。
  • 通信模式:选"无协议",这是开自由口通讯的关键。默认可能是"串行网关",不改的话TXD/RXD指令根本不会按预期工作。
  • 数据位、停止位、奇偶校验按表对齐,否则物理层都握不上手。

改完设置要传送到PLC,然后断电再上电,串口参数才会真正生效。这个步骤特别容易忽略,很多人在线改完设置不重启,或者只做了在线传送没有彻底复位,通讯模式其实还是旧的,等半天也不通。所以养成习惯:串口相关的参数改动,必须断电重启再调试。

4. 程序实现:从报文组装到响应解析的完整链路

物理层和参数都就位以后,重头戏是PLC程序。这里核心不是单个指令怎么用,而是整个通讯状态机怎么转得稳定。

4.1 先把通讯流程设计成状态机

我调试时习惯把通讯流程做成一个状态机,用状态字控制每个步骤,最简版本如下:

0:空闲/初始化 10:组装启动报文,触发发送 20:延时等待变频器响应 30:接收响应并做CRC校验 40:组装频率报文,触发发送 50:延时等待 60:接收响应并校验 70:组装读频率报文,发起读 80:等待,接收返回数据并解析 90:全部完成,置位本周期完成标志

状态机的好处是每个动作之间有明确的等待间隔,不会出现"上一条没回完、下一条又发出去"的情况。变频器响应时间通常在10~30ms,50ms的等待间隔足够;如果现场总线负载高,把间隔放到100ms更稳。轮询逻辑放在常ON循环里执行,完成标志置位后清空再进入下一轮。

4.2 发送指令与报文缓冲区的组织

以写启动命令为例,要发出的原始字节是01 06 20 00 00 01,加上CRC后总共8个字节,在PLC里用连续字做缓冲区,比如D100到D103,按TXD指令要求的顺序逐字填充。

TXD指令的用法,助记符写法如下:

TXD D100 #0 &8

三个操作数分别是:发送缓冲首地址D100、控制字#0(选择串口1)、发送字节数8。CPU从D100开始连续取8个字节发出去。如果是扩展的串口2,控制字要改成对应串口2的值。

这里有一个极易踩的细节:TXD发数据时,每个字内部是先发低位字节再发高位字节。如果直接把报文按字地址顺序塞进去,实际发出的字节顺序会和想象相反。我第一次写这个程序就被坑过,后来靠串口助手抓包才发现。所以现场第一次联调,强烈建议先用电脑串口助手抓一下PLC发出的原始报文,确认字节顺序正确了再往下调。这种第一次必须抓包确认的意识,能省下很多时间。

4.3 RXD接收与数据解析

RXD指令负责把串口收到的字节搬到PLC内存,用法和TXD对称:

RXD D200 #0 &7

D200是接收缓冲首地址,&7是期望接收的字节数。注意这里是"实际响应长度",别随便写大。读单个寄存器时,VFD-M会回:地址1字节、功能码1字节、字节计数1字节、数据2字节、CRC2字节,总共7字节。写命令时因为从站把发来的命令原样回抄,响应长度是8字节。RXD设定的接收数比实际长,PLC就会一直等,后续逻辑半天不往下走。

接收完成后第一件事是校验CRC。把收到的响应重新算一遍CRC,和报文末尾的CRC字节对比,相同就是通讯成功,不同就该计数重发了。解析数据时注意Modbus是大端序,寄存器的高位字节在前、低位字节在后。读输出频率时,把这两个字节组合成16位整数,再除以100就是实际频率值。

4.4 梯形图逻辑骨架参考

具体梯形图代码工程各异,我把关键逻辑写成伪代码,方便移植:

主循环: 如果 本周期完成标志为0 且 通讯空闲: 按状态机步骤执行 状态10: 拼装"01 06 20 00 00 01"到D100,调用CRC子程序, 附加CRC到报文尾部,执行TXD(D100,#0,&8) 状态20: 延时定时器到50ms后切到状态30 状态30: 执行RXD(D200,#0,&8),调用CRC校验 通过则清发送标志,置本周期完成标志 失败则重发计数加1,超过3次置通讯故障位 状态40... 后续步骤类似处理

这段逻辑看着简单,实际工程里必须加保护:写运行命令的地方要串入运行允许条件,比如急停回路、安全门反馈、工艺联锁。不能只依赖变频器内部参数,否则程序误动可能造成设备骤停或误启动。这些是现场安全事故的高发点,必须先想清楚再动手写程序。

5. 现场实测调试中踩过的坑与排查顺序

这节是我最想写的内容。下面每个坑我都踩过,按排查顺序列出来,遇到同样问题可以直接照着走。

5.1 变频器完全不应答,按这个顺序查

现象是程序发了指令,RXD什么都收不到。别看表象简单,原因能排一长串,我的排查顺序固定如下:

  1. 用电脑加USB转RS-485转换器直连变频器,手动发一条读命令。这一步能把"PLC程序"和"物理链路"切成两段。如果电脑也收不到应答,问题在变频器或链路,不在PLC程序。
  2. 查接线,A/B有没有接反,转换器供电够不够。无源转换器靠RS-232口的握手信号借电,有些PLC串口驱动能力弱,换有源转换器可能直接解决问题。
  3. 查参数,站号、波特率、数据格式,PLC和变频器任何一项不一致,Modbus请求都会被无视。
  4. 查报文,用串口助手对照发出的字节是不是和标准Modbus请求一致,CRC高低位、字节顺序问题在这一步直接暴露。
  5. 以上都查完,最后回头看PLC串口模式是不是真的改了无协议,改完之后有没有断电重启。

这套顺序我建议直接写在调试笔记本上,十次里有九次能锁定问题。

5.2 能通信但数据不对:CRC和字节序的坑

能收到响应说明物理层通了,但如果解析出来的频率永远是0或者看起来毫无规律,问题多半在数据解析层,常见两类。

第一,CRC高低字节顺序反了。Modbus标准要求CRC低字节在前、高字节在后,但有些参考程序示例会写成反的。收到错误CRC的从站一般选择不响应,表现和5.1完全一样,比较隐蔽。第二,解析寄存器值时高低位颠倒。Modbus寄存器数据是大端序,高字节在前,如果PLC里按小端序解析,50Hz读出来就成了一堆乱码。

遇到这类问题,我习惯在串口助手上同时打开HEX显示,手动算一遍CRC,再和PLC计算的CRC对比,很快能定位是哪一步出的错。别嫌麻烦,这比对着程序猜快得多。

5.3 通讯时好时坏、偶发失败的处理思路

通讯一会儿通一会儿不通,大多数时候和程序逻辑无关,是物理层和时序问题。优先查三点:

  • 屏蔽层接地是否合规。地环路是偶发失败的头号原因,屏蔽层必须单端接地。
  • 终端电阻。总线距离超过20米或者挂了三台以上设备,末端不并120Ω电阻,很容易出现信号反射导致偶发丢帧。
  • 轮询节奏。有些程序把多条指令挤在几十毫秒内连发,变频器响应不过来就会丢包。把每条命令之间的间隔拉大到100ms以上,丢包率会明显下降。

还有一个容易被忽略的细节:变频器侧如果还有外部端子控制线(比如正反转端子悬空或误接),运行过程中可能触发变频器自行停机,PLC读到的状态和预期不一致,表面看像"通讯内容错乱",实际是控制逻辑在打架。遇到诡异现象,先排除外部控制线干扰,别一头扎进协议里钻牛角尖。

到这里,CP1H自由口通讯驱动台达VFD-M的完整链路算是走通了。我个人在实际项目里的体会是:自由口通讯难的不是指令用法,而是把每个细节都对齐——接线接对、参数设对、CRC算对、时序安排好。只要把上面这些点逐个确认,再复杂的设备也能拿下来。最后再分享一个技巧:把通讯状态、超时次数、重发次数实时映射到触摸屏上,调试时能省一半力气,后期设备维护也方便很多。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进