S7-1200与英威腾GD变频器Modbus RTU通讯实战
1. 项目背景与整体方案选型1.1 为什么用S7-1200加英威腾GD这套组合前阵子接手了一个产线改造项目现场的设备说复杂不复杂就是3台英威腾GD系列变频器分别驱动3台输送电机工艺上要求这几台电机既能独立启停、调速又要能在上位机或者触摸屏上统一监控运行频率、电流、故障状态。原来的方案是每台变频器硬接按钮和电位器操作工得跑到设备跟前去调故障了也只能看变频器面板上的代码生产数据更是没法记录车间主任想统计个运行时长都得靠人工拿本子记。这种场景其实特别典型尤其是很多中小型产线上变频器就是“单机运行”状态没有联网也没有远程监控手段。改造需求也很直接要能远程启停、远程调速、实时读取运行参数、故障报警能第一时间知道。我当时评估了几个方案一种是走DP总线但S7-1200这边要加DP模块成本高而且英威腾GD的DP扩展卡还得另外配另一种是走PROFINETGD系列有PN版本但现场这几台是老款不支持直接扩展PN最后定下来用Modbus RTU理由很实在——成本低、S7-1200本体就能支持、英威腾GD系列标配RS485通讯口3台变频器串联一条两芯屏蔽线就搞定了。这里有个点要跟各位说清楚Modbus RTU虽然不是最快的通讯方式波特率一般也就9600到19200但对于变频器这种控制对象来说完全够用。变频器响应启停命令、频率给定本质上是在毫秒级到几十毫秒级的范畴而Modbus RTU一条指令的通讯时间在9600波特率下大约也就10毫秒左右3台轮流问一遍一个扫描周期内搞定根本不影响控制效果。1.2 系统架构与通讯协议选型先把这个项目的整体架构说清楚大家可以对着自己的现场情况做个参考。系统组成大概是这样的主站西门子S7-1200 PLC型号是1214C DC/DC/DC本体集成一个RS485接口通过CM1241通讯模块扩展也行我这次用的是本体上的接口因为1214C自带一个RS485口省了一块模块的钱。注意S7-1200本体自带的那个RS485口是支持Modbus RTU主站的不需要额外授权直接调用库函数就行。从站3台英威腾GD200系列变频器每台设一个从站地址分别是1、2、3。通讯链路RS485屏蔽双绞线手拉手串联首尾两端不用接终端电阻距离短20米以内实测不接也没问题但正规做法是超过50米建议接120欧终端电阻。监控层一台昆仑通态触摸屏通过以太网连接S7-1200不直接占通讯口。选Modbus RTU还有一个让我比较放心的地方就是英威腾GD系列的Modbus寄存器地址非常规整文档里写得很清楚不会出现那种映射来映射去映射不明白的情况。后面我会把关键地址列出来。有一点必须提醒大家S7-1200的RS485接口虽然有但你需要确认硬件型号。1214C有两个版本一个是AC/DC/RLY继电器输出一个是DC/DC/DC晶体管输出两者的RS485接口位置和引脚定义是一样的但注意看CPU面板上有没有X150这个接口标注。我这个项目用的是DC/DC/DC版本确认过X150接口是标准RS485。2. 硬件接线与通讯参数配置2.1 硬件清单与选型理由先列一下我实际用到的硬件清单都是比较常规的东西采购也方便序号名称型号/规格数量用途说明1PLCS7-1200 1214C DC/DC/DC1主站控制器2变频器英威腾GD200-2R2G-433台4kW电机驱动3屏蔽双绞线RVSP 2×0.75mm²30米RS485通讯链路4触摸屏昆仑通态TPC70621远程监控与操作524V电源明纬DR-45-241PLC及通讯供电6网线超五类屏蔽网线若干PLC与触摸屏通讯选型的时候有几个考虑一个是授权问题S7-1200的Modbus RTU库指令在TIA Portal里是自带的不额外收费另一个是通讯线材我用的是RVSP屏蔽双绞线这种线在工业现场抗干扰能力明显好于普通网线或者平行线尤其在变频器这种强干扰源旁边屏蔽层接地处理得当的话能省掉后面很多麻烦事。再补充一个硬件层面的常识RS485是差分信号抗共模干扰能力强但总线上的设备数量、线缆长度、布线走向都会影响通讯质量。3台从站设备加起来才4个节点属于小规模总线对于1200米的理论最大通讯距离来说现场这几十米的长度绰绰有余。唯一要注意的是线径不能太细0.75平方毫米是底线太细了压降大长距离通讯容易丢包。2.2 RS485接线实操细节接线这件事看着简单但恰恰是Modbus RTU通讯故障的重灾区。我这边的接线方式是手拉手串联从PLC的X150接口的T/R和T/R-两个端子分别对应接到第1台变频器RS485端子的A和B然后再从第1台接到第2台第2台接到第3台形成一条总线。这里有个细节英威腾GD系列变频器上的RS485端子一般标的是A和B-对应的就是485和485-跟PLC这边的T/R和T/R-接法要一致不能交叉。A接AB接B这是一条铁的纪律。我曾经见过有人把A和B接反的现象就是通讯时通时断或者干脆不通查了半天才发现是两根线接反了。屏蔽层的处理也是一个关键点。我的做法是屏蔽层在PLC这一端单端接地接到柜体上的接地铜排变频器那一端不接地这样可以避免形成地环流。地环流一旦形成轻则通讯数据偶尔出错重则直接把RS485芯片烧掉。这一点在变频器柜里尤其要注意变频器本身的开关频率会产生高频干扰如果屏蔽层两端都接地干扰电流就会顺着屏蔽层跑反而把干扰引进来了。端子接线用屏蔽层压接好的话还能顺便解决一个受力问题线缆不要悬空受力最好用线槽或者扎带固定在柜内避免运行中振动导致端子松动。通讯线也不要跟变频器的主回路动力线绑在同一个线槽里必须要分开走间距至少20厘米条件允许的话越远越好。2.3 通讯参数统一约定Modbus RTU通讯要跑通关键参数必须保证主站和从站完全一致有一项对不上就通讯失败。我这个项目的通讯参数表如下参数名称PLC侧设置变频器侧设置波特率96009600数据位88校验方式无校验None无校验停止位11从站地址不涉及主站1#机为12#机为23#机为3有的朋友可能会问为什么不用偶校验其实用偶校验在抗干扰上会好一些但英威腾GD系列默认设置在无校验模式下也能稳定运行而且无校验时数据帧少一个字节通讯效率略高。稳妥起见我直接把两边都设成无校验、8数据位、1停止位也就是常见的9600,8,N,1格式这样省得后面调试时还要来回核对校验位。波特率这里也多说一句9600是Modbus RTU最保险的选择虽然19200速度更快但现场只要有稍微长一点的通讯线或者干扰稍大高速率就容易出问题。变频器通讯这种场合控制周期要求在100毫秒以内就够了9600完全够用没必要为了那点速度提升去冒通讯不稳的风险。3. PLC侧程序编写与轮询逻辑实现3.1 MB_COMM_LOAD组态指令详解S7-1200做Modbus RTU主站核心就是要调用两个指令MB_COMM_LOAD和MB_MSG。前者是通讯端口初始化后者是数据收发指令。在TIA Portal里这两个指令在“通信-通信处理器-Modbus”目录下能找到。MB_COMM_LOAD的作用是把CPU的RS485接口配置成Modbus RTU协议。它的输入参数有端口号PORT、波特率BAUD、校验方式PARITY、从站数量等。我这里端口号填的是CPU本体RS485口的硬件标识符在设备组态里能看到一般是269或者类似的值。BAUD填9600PARITY填0表示无校验。还有一个参数叫做FLOW_CTRL填0禁用流量控制。MB_COMM_LOAD只需要在首次扫描时调用一次不需要每个扫描周期都执行。所以我用一个边缘检测指令R_TRIG配合一个置位标志位来控制MB_COMM_LOAD的调用初始化完成后把标志位置1后续就只调用MB_MSG做数据交互。如果不做这个处理每次扫描都去重新初始化端口通讯反而会乱套甚至导致从站响应超时。3.2 轮询调度与MB_MSG调用接下来是重头戏——轮询调度。Modbus RTU是单主站总线协议主站必须一个一个地跟从站通讯同一时刻只能有一条指令在总线上不能像以太网那样多发并行。3台变频器每台都需要读状态、读电流、读频率、写启停、写频率给定如果一条一条轮着写程序会变得很长。我的做法是建立一个轮询数组每台变频器安排若干条读写任务然后用一个整数型轮询指针POINTER在当前任务、下一任务之间循环切换。每完成一次MB_MSG调用就把指针加1指向下一个任务最后一个任务执行完后再回到第1个任务。具体每台变频器的任务清单是这样的任务1写启停命令写单个保持寄存器任务2写频率给定写单个保持寄存器任务3读运行状态读2个保持寄存器状态字当前频率任务4读电流值等运行参数读4个输入寄存器电流、电压、母线电压、模块温度3台变频器共12个任务轮询一圈的时间在9600波特率下大约300到400毫秒。这个速度对于监控画面更新来说完全够用操作工在触摸屏上看到的参数基本是实时的。MB_MSG指令的两个关键参数是RW和DATA_ADDR。RW1表示写RW0表示读。DATA_ADDR在S7-1200的Modbus库里有特别的规定数据地址是0开始的写保持寄存器时填400001读保持寄存器时填400001但库内部会自动减1变成40000。这里有个坑要特别注意——S7-1200的Modbus地址范围是0到65535对应Modbus协议里的40001到465535英威腾手册里给的地址如果是40001那你在PLC里要填的就是400001。很多新手在这上面栽过跟头地址填错一位数据读出来全是乱的。MB_MSG还有一个关键参数是DATA_PTR指向PLC侧的数据存储区。比如读回来的数据存在DB块里就把DB块的地址指针传给DATA_PTR。写数据时要把待写入的值先放到这个存储区里然后MB_MSG会自动把存储区里的值发到总线上。这里注意存储区的数据类型S7-1200的Modbus库默认读写是16位字如果你传的是32位浮点数还得自己做类型转换。我后面会具体讲这个转换过程。3.3 数据读写与工程量转换读写指令本身其实不复杂复杂的是数据到了PLC之后怎么处理。以读取变频器电流为例英威腾GD系列变频器的电流寄存器地址是1000H十六进制对应Modbus地址40001加偏移。但变频器返回的数据是16位无符号整数单位是0.1A意思是如果返回值是123那实际电流就是12.3A。所以在PLC侧要做一次工程量转换实际电流 原始值 × 0.1。这个换算我要做一个浮点转换功能块把从MB_MSG读回来的INT类型数据转成REAL再做乘法。同理频率给定也是0.01Hz为单位原始值5000代表50.00Hz写的时候要把50.00Hz乘以100再取整然后转成十六进制写到变频器。写启停命令这块GD系列变频器用的是控制命令字寄存器往里面写1、2、6、7等数值分别对应正转、反转、点动正转、点动反转等操作。我做了两个功能码写1执行正转启动写6执行停止。停止时我再多写一次7也就是自由停车命令这样在急停情况下可以快速切断输出。这个逻辑看起来有点绕但实际运行下来比单一停止命令更可靠。以下是SCL结构化文本编写的单任务轮询骨架供参考// 轮询指针自增范围1~12 IF #poll_pointer 12 THEN #poll_pointer : 1; ELSE #poll_pointer : #poll_pointer 1; END_IF; // 根据当前轮询指针选择从站地址和任务类型 CASE #poll_pointer OF 1: // 1#写启停 #slave_addr : 1; #rw : 1; #data_addr : 400001; // 控制命令寄存器 #data_len : 1; #send_data : #cmd_1; 2: // 1#写频率 #slave_addr : 1; #rw : 1; #data_addr : 400002; // 频率给定寄存器 #data_len : 1; #send_data : #freq_1; // ... 依此类推 END_CASE;这里要提醒一个节奏问题Modbus通讯不是越快越好每个任务之间最好留出一个短暂的时间间隔我实操时在轮询循环末尾加了个2毫秒的延时避免CPU扫描太快导致连续发送指令从站还没来得及响应。这个延时可以通过TON定时器实现也可以用S7-1200的循环周期直接控制简单来说就是让轮询频率别太疯。4. 变频器侧参数设置要点4.1 电机基本参数与加减速时间变频器侧的参数设置是整个项目里最容易被忽略但同样重要的一环。很多人喜欢一上来就设通讯参数结果变频器通讯是通了电机转起来却不对加速过流、减速过压各种报警。所以我的习惯是先把电机基本参数设准确再谈通讯。英威腾GD系列变频器在快速调试菜单里主要有以下几个参数要核对参数代码功能说明我的设置值P00.01电机额定功率4.0kWP00.02电机额定电压380VP00.03电机额定电流8.2AP00.04电机额定频率50.00HzP00.05电机额定转速1440rpm这些数据在电机铭牌上都有照着填就行千万别自己估。电机启动如果加速时间太短启动电流会非常大触发变频器过流报警减速时间太短母线电压会被泵升机制拉高触发过压报警。我设置的加减速时间分别是5秒和6秒对于输送带这种轻负载来说足够平缓也不会让操作工觉得反应太慢。另外如果这台电机是带编码器或者有特殊负载的还需要设置相应的控制方式比如矢量控制、V/F控制。我这个项目用的是普通异步电机V/F控制模式就够用了。GD系列默认的控制方式我记得就是V/F不需要额外调整如果电机的特性比较特殊再考虑改成矢量控制但矢量控制需要电机参数自学习操作上会多一些步骤。4.2 通讯参数组配置英威腾GD系列的通讯参数主要集中在一组功能码里我用的设置如下参数代码功能说明我的设置值P14.00本机通讯地址1#设12#设23#设3P14.01通讯波特率9600P14.02数据位校验8-N-1无校验P14.03通讯协议Modbus RTUP14.04通讯超时时间10秒通讯超时时间这个参数有点意思。它的含义是如果在设定时间内收不到主站的任何报文变频器就认为通讯中断然后按照P14.05设定的方式处理。我这边P14.05设的是2意思是通讯中断后变频器停止运行并报警。这样做的目的是出于安全考虑——万一PLC死机或者通讯线断了变频器不会傻乎乎地按最后的频率一直转下去而是立刻停下来避免设备失控引发安全事故。这个超时时间我试过几种值最短的1秒实测下来偶尔会误报警比如PLC那边正在下载程序或者触摸屏操作暂时占用通讯链路时1秒超时太敏感了。设为10秒相对稳妥既不会误动作也能在真正通讯故障时及时停车。具体项目里可以根据现场的容忍度去调整但原则上不要小于3秒。4.3 命令源与频率源选择这是整个变频器参数设置中最关键的一步告诉变频器“你听谁的指挥”。英威腾GD系列变频器有两个关键参数命令源选择决定启动停止从哪里接收和频率源选择决定速度给到哪里。我的设置如下P10.00命令源选择设为2即通讯控制。这样变频器的启动、停止指令完全由Modbus通讯下发面板上的启动停止键就会失效。P10.01频率源选择设为2即通讯给定。频率值也由Modbus通讯写入。这里有一个很常见的坑如果你只设了命令源为通讯但频率源还是面板电位器给定那么即使频率写进去也没有效果变频器还是按面板上的电位器速度在转。反过来也是一样只设频率源不设命令源你写启停指令也没反应。两个参数必须同时设为通讯方式控制权才完成交接。设置完这两个参数之后面板上的按键会失效如果现场需要应急操作可以在P10.00里加一个“通讯优先、面板可切换”的选项。不过我这个项目直接锁死为通讯控制因为触摸屏是现场唯一的操作入口这样也避免操作工在面板和触摸屏之间搞混。5. 常见问题与调试经验实录5.1 通讯中断与恢复机制这个项目调试过程中最让我头疼过的就是通讯中断问题。主要表现为触摸屏上显示的某个变频器状态突然变成离线操作工一按启动按钮没有任何反应过几分钟又自己恢复了。排查的时候我拿了笔记本接在总线上监听Modbus报文发现某个从站偶尔会不响应主站的请求导致MB_MSG指令返回错误码16#8204从站无响应或响应超时。这个错误码在S7-1200的Modbus库文档里写得很清楚意思是从站在设定时间内没有返回数据。问题根源找到了变频器侧的电抗器在运行时产生电磁干扰耦合到了RS485通讯线上导致某个从站的通讯芯片接收到了错误数据帧但它不会自动丢弃错误帧而是等超时后才重新监听总线这个期间就表现为不响应主站。解决思路有两个方向一个是软件层面把主站轮询每个从站的超时时间适当调长一点默认的1000毫秒改成2000毫秒给对方留出重新同步的时间另一个是硬件层面把通讯线的屏蔽层接地重新处理了一下把原先两端悬空的屏蔽层改为PLC侧单端接地干扰明显减少。现场实测下来这两招同时用通讯中断基本消失了。我做了一个故障自恢复逻辑如果MB_MSG错误码连续出现3次就把这个从站的轮询暂时跳过等下一个周期再试避免一个故障站点堵住整条总线。这个逻辑虽然简单但保护了整个系统的可用性——一台变频器通讯坏了另外两台不受影响。5.2 数据错位与字节顺序问题另一个调试中遇到的问题是数据错位。具体现象是触摸屏上显示的1#变频器电流值实际上是3#变频器的电流值2#显示的是1#的值数据整体串位了。排查过程很有意思程序逻辑从头看了一遍轮询指针、从站地址、数据存储区看起来都正确。最后用Modbus调试工具访问从站分别读取1、2、3号变频器的电流寄存器数值都能正确返回。那问题只能在数据存储区的映射上。真相大白我在MB_MSG的DATA_PTR参数里每一路任务都用了同一个数据存储区起始地址也就是每个任务读回来的数据都往同一个DB块偏移位置里写。当3个任务依次执行时后一个任务的数据就把前一个覆盖了。触摸屏读的时候因为时序差不多的原因正好读到的是最后一个任务写入的数据所以出现了串位。解决方式很粗暴但有效给每个从站的每类数据分配独立的存储区也就是1#变频器的电流、频率、状态分别存在DB1.DBD10、DB1.DBD14、DB1.DBW182#的从DB1.DBD20开始3#的从DB1.DBD30开始。这样数据各归各谁也不会覆盖谁。关于字节顺序这里也要多说一句。英威腾GD系列变频器的Modbus数据默认是高字节在前Big-Endian西门子S7-1200也是高字节在前两边一致所以不需要交换字节顺序。但如果你用Modbus调试工具的时候发现读回来的数据大小端反了那就可以考虑工具软件的显示设置或者其他厂商的设备这时候才需要做交换处理。PLC里交换字节顺序可以用SWAP_BYTE指令甚至简单点的移位运算也能搞定。5.3 干扰问题处理实录再分享一个跟干扰有关的经验。项目交付后运行了大概两个月现场反馈说偶尔会出现频率给定漂移就是触摸屏设定50Hz变频器实际运行频率却变成49.7Hz或者50.3Hz有时候还会闪一下52Hz。这种情况十有八九是干扰导致的通讯数据错误。Modbus RTU本身没有数据校验机制准确说RTU模式下用的是CRC校验但这个CRC只能检查数据在传输过程中有没有被篡改不能纠正一旦CRC校验失败这帧数据就被丢弃不会产生错误动作。但如果干扰信号恰好没有破坏到CRC校验字节那错误数据就会被当作有效数据接受。我的对策有两层第一层是在PLC侧程序里做数值合理性判断比如读回来的频率值如果大于55Hz或者小于0Hz就认为是垃圾数据直接保留上一次有效值并且置一个报警标志。第二层是在写频率给定值之前先做一个斜坡限制避免设定值突变超过2Hz/100ms这样就算通讯上有毛刺也不会造成频率瞬间跳变对电机冲击也能小很多。实测下来这个方法很管用干扰毛刺还在但已经不影响系统运行了操作工再也没有反馈过频率漂移的问题。这个方法也推荐给大家因为你不可能完全消灭现场干扰但可以通过软件逻辑把干扰造成的影响降到最低。这也是自动化控制里常说的“防错”思维硬件做不到的事情软件兜底来补。再补充一点实际运行数据这套系统目前已经稳定运行了大概8个月期间除了变频器本体的一次散热风扇故障之外通讯链路没有出现过一次需要维护的故障。轮询周期、响应时间、数据刷新率都完全满足工艺要求。6. 一些实操上的心得与经验补充分享聊了这么多技术细节最后再分享几个我前后做了好几个类似项目后沉淀下来的心得算不上什么高深理论但都是实打实省过时间的经验。第一做这类PLC加变频器通讯项目强烈建议先拿单台变频器做最小系统验证。就是把一台变频器接上485线用Modbus调试工具比如Modbus Poll先单独把所有寄存器地址、数据格式摸清楚确认能读到正确的数据之后再接第二台、第三台。这个步骤能避免你在后面三台设备联调时出了错还要回头排查到底是哪一台的参数有问题。第二S7-1200的Modbus库指令虽然官方文档写得算清楚但里面有些细节要自己试出来。比如MB_MSG的DONE和ERROR输出我建议在主程序里用一个Q点或者M点把它们引出来调试时直接监控这两个点比每次去DB块里翻错误码要直观得多。DONE置位说明一帧通讯完成ERROR置位说明这一帧出错了这两个点一监控通讯状态一目了然。第三关于变频器的参数备份我强烈建议在调试完成后把所有变频器的参数上传到电脑里存一份做一个参数备份文件。英威腾GD系列的面板可以插拔先把面板参数拷贝到面板里然后再从面板上传到电脑。这样万一以后变频器更换了新变频器直接把参数下载进去不用一台台手输参数。手输参数的麻烦程度试过一次的人都会深有体会几十个功能码挨个确认不仅费神还容易敲错。另外还有个小技巧如果现场有不止一块触摸屏或者以后有上位机系统可以把PLC的通讯接口空出来一个以太网口用S7-1200内置的PUT/GET功能把变频器的监控数据通过以太网再转发一层。这样就算以后增加监控层站点也不影响RS485总线上原有的Modbus轮询逻辑扩展性会好很多。这个方案我在另一个项目中已经用上了实际效果很不错。最后就是老生常谈的一句话项目调试过程中遇到的问题一定要记录下来包括现象、排查过程、最终原因、解决办法这些经验才是你作为工程师最宝贵的资产。我这篇文章里写的这些坑基本都是实际踩过之后记录下来的希望对正在做类似项目的朋友有帮助。如果你们在调试中也遇到了什么奇怪的问题欢迎交流讨论有些东西确实是聊着聊着才想明白的。