1. 项目从哪儿来一台老PLC带三个新脑子1.1 现场需求拆解前阵子接了一个小设备改造的活儿主控用的还是三菱FX1s设备上有三台电机原来靠变频器面板手动启停操作工每天要跑到电柜前面按按钮、拧旋钮效率低不说换品种调速度还得拿手册翻参数。用户的要求很直接把三台变频器换成带RS485通讯的型号用触摸屏远程启停、调速、看运行状态不动PLC主体。拆开需求以后其实就两条线一是三台变频器要能被同一个PLC控制二是触摸屏要把数据和命令传下去。最开始有人建议干脆把FX1s扔了换FX3U或者FX5U说FX1s不带内置Modbus指令做通讯纯属给自己找麻烦。但现场PLC还有十几个点位在跑现有的逻辑IO接得满满当当重写程序加改线风险和时间成本都不低。最后定了方案保留FX1s走无协议RS指令自己拼Modbus RTU帧用轮询方式控制三台台达MS300。这套路子在老设备改造里其实挺常见。FX1s虽然便宜老迈但编程口自带RS422电平配上转换模块就能变成RS485主站控制变频器绰绰有余。它硬件上没有专门的通讯指令如ADPRW也没有像FX3U那样内置Modbus指令但这不代表做不了只是需要自己把帧构造、CRC校验、轮询调度这些活全干了而已。1.2 为什么不用模拟量控制很多人第一反应是三台变频器直接用0~10V模拟量调速多简单何必折腾通讯。这话放在单台变频器、控制精度要求不高的场合没毛病但放到三台联动的场景就不太行了。模拟量方案要占用PLC模拟量输出模块FX1s本体不带模拟量扩展能力只能外挂特殊功能模块成本不低。三路线要分别走屏蔽电缆抗干扰是老大难稍微离动力线近一点变频启停瞬间速度就会抖。最麻烦的是没法回读状态变频器过载、报警、实际频率是多少PLC一概不知触摸屏上只能靠猜。用Modbus通讯这些问题基本全绕开了。一根双绞线串三台变频器站号区分频率写0.01Hz精度状态字实时回传启停、正反转、故障复位全在寄存器里操作。通讯轮询一圈几十毫秒对于这种小设备完全够用。所以选型上我和客户沟通后一致同意走通讯这也符合当前工控项目里“能用总线不用模拟量”的大方向。1.3 方案整体架构整套系统的数据流是这样的触摸屏通过串口或编程口与FX1s交换数据写入目标频率和启停命令FX1s内部做帧拼接、CRC计算通过编程口转RS485模块发往三台台达MS300变频器返回响应帧FX1s解析后把运行状态、输出频率存好触摸屏轮询读取显示。通讯协议采用Modbus RTUPLC作为主站三台变频器站号分别设为1、2、3。波特率统一96008数据位无校验1停止位。这个组合在低速短距离环境下非常稳定也是三菱PLC做无协议通讯最经典的一组参数。2. 硬件链路编程口如何变成RS485主站2.1 三种接法对比FX1s做RS485通讯硬件方案我梳理过三条路。第一条是加通讯扩展板。遗憾的是FX1s根本没有扩展板安装位FX1N、FX3U才支持挂485BD这类通讯板所以这条路直接堵死。第二条是用FX1s的编程口做RS422通讯配台达的RS422接口板但MS300标准机型标配RS485没有RS422口还得加转换器多一层转换多一层坑不推荐。第三条就是我最常用的做法买一根或者自制一根“三菱FX编程口转RS485模块”的线。这种模块一头是8针圆头插编程口另一头出两个接线端子或者标准RS485口里面做了RS422与RS485的电平转换。接线简单成本几十块实测稳定。要做就做第三条这个方案几乎所有做维修、改造的老师傅都熟市面上的成品模块也很多只要是FX1S/FX1N/FX2N/FX3U全兼容的就能用。2.2 编程口接线要点编程口的物理接口是8针圆形mini-DIN里面走的是RS422差分信号分SDA、SDB、RDA、RDB几根线。成品模块一般把SDA、SDB引出来接到RS485的A、B端子或者直接给出A、B两个端子。这里有个特别容易踩的坑不同厂家模块的A/B定义不统一。我调试时遇到过模块标着SDA接A、SDB接B结果死活通不上后来把A、B对调一下通讯立刻正常。所以接好线以后先别急着写程序用一个RS485转USB工具或者直接在触摸屏上做一个小测试确认主站发帧时变频器有响应再往下做。接线还有几个细节双绞线用屏蔽线屏蔽层单端接地不要两端都接最远一台变频器两个端子之间并联一颗120欧终端电阻通讯线尽量远离变频器的进线和电机线别跟动力电缆走同一个线槽变频器侧的地线端子要可靠接地有些现场通讯不稳定就是地线虚接闹的。2.3 台达MS300参数设置台达MS300的通讯参数在面板菜单里设置不同批次固件菜单名称略有差异但思路一样。需要改的参数可以分为三组。第一组是通讯协议组包括站号、波特率、数据格式参数项设置值说明通讯地址1、2、3三台依次设置不能重复通讯速率9600与PLC的D8120保持一致通讯协议Modbus RTUASCII模式不选数据格式8N18数据位、无校验、1停止位第二组是命令来源组这是新手最容易忽略的。很多变频器装上以后通讯参数全设好了PLC也发帧了面板也显示频率在变化电机就是不转。原因就是频率来源和运转指令来源还停留在面板模式。必须在参数里把主频率来源改为“通讯”把运转信号来源改为“RS485”不然Modbus写进去的频率和命令都不生效。第三组是故障保护组包括通讯超时时间和通讯故障处理方式。建议把通讯超时设成1~3秒通讯故障处理设成“停车”防止PLC与变频器通讯中断后电机带着负载乱跑。这个在实际生产中非常重要宁可停机报警也不能失控运行。3. 协议细节Modbus RTU在FX1s上的关键点3.1 通信帧长什么样Modbus RTU的帧格式本身不复杂一帧数据依次是设备地址、功能码、数据区、CRC校验低字节、CRC校验高字节。我这里用到了三种功能码功能码06写单个寄存器用来写变频器的运行命令也可以写频率功能码10写多个寄存器可以把频率和命令一次写完功能码03读多个寄存器用来读变频器的状态字和输出频率。台达MS300的几个关键寄存器地址要记清楚寄存器地址含义操作2000H主频率命令单位0.01Hz写2001H运行命令正转、反转、停止写2100H状态字运行中、正转、反转等读举例来说要把1号变频器频率设为20.00Hz可以先算20.00Hz对应的寄存器值是20×1002000十六进制就是0x07D0。然后构造写频率帧设备地址01H功能码06H寄存器地址2000H写入数据07D0HCRC校验两个字节完整帧就是01 06 20 00 07 D0 96 B8其中96 B8是CRC校验低字节和高字节。注意Modbus RTU规定CRC先发低字节再发高字节这一点后面程序实现时特别容易出错。运行命令帧也类似。正转写2001H寄存器数据0001H即01 06 20 01 00 01 05 14反转写0002H停止写0000H即把运行命令清掉。实测在我的现场固件版本下写0000H能可靠停车。台达不同固件对停止字定义可能略有差异有的用0003H表示停止稳妥做法是先翻一遍对应手册或者用串口工具试一下。3.2 D8120、M8161与RS指令的配合FX1s做无协议通讯核心是三样东西D8120设定通讯格式、M8161切换8位处理模式、RS指令开辟收发缓冲区。D8120是通讯格式寄存器它是一堆位定义的集合。我最常用的设置值是H0087对应的含义就是波特率9600、8数据位、无校验、1停止位。对应的梯形图初始化程序是M8002 |--[MOV H0087 D8120] |--[SET M8161]M8161必须置ON否则RS指令会按16位模式处理数据帧发出去全乱。这一点是FX1s做Modbus最容易踩的隐藏坑官方案例里写得很清楚但很多人第一次没注意折腾一晚上都找不到原因。RS指令的用法是M8000 |--[RS D100 K8 D200 K32]这段指令的含义是把D100开始的8个字节作为发送缓冲区D200开始的32个字节作为接收缓冲区。M8000常通驱动意味着PLC随时准备好接收数据。需要发送时程序把数据填到D100然后置位M8122PLC就把这8个字节从通讯口发出去。发送完成时M8122自动复位。收到完整一帧后M8123会置ON程序取完数据必须手动复位M8123才能接收下一帧。这里还有一个字节序的坑RS指令发送D寄存器时是每个D寄存器的高8位先发、低8位后发。所以如果我要发送01 06 20 00 07 D0 96 B8这8个字节D100到D103的存放方式应该是寄存器高字节先发低字节后发D1000106D1012000D10207D0D10396B8也就是D100H0106D101H2000D102H07D0D103H96B8。如果按习惯把D100当成一个整数往里填发送顺序就会变成06 01 00 20 D0 07 B8 96变频器根本没法识别。3.3 CRC16计算与那个高低字节的坑CRC16-Modbus的算法逻辑其实就四句话CRC初始化为FFFFH每取一个字节与CRC低字节异或把这个结果右移8次每次右移一位如果移出去的那一位是1就和A001H异或所有字节处理完以后低字节先发、高字节后发。我在PLC里用子程序实现思路是这样的P0 子程序CRC计算 输入D100开始的数据、帧长度字节数 输出把CRC填到发送帧末尾 1. D41 HFFFF 2. 对帧里每一个字节 2.1 取出当前字节放入D42 2.2 D41 D41 XOR D42 2.3 循环8次 如果D41的最低位是1 D41 D41右移1位 D41 D41 XOR HA001 否则 D41 D41右移1位 3. CRC结果在D41中低字节放到帧倒数第二个字节高字节放到帧倒数第一个字节梯形图里没有高级语言的FOR循环实际编程时我用计数器加跳转指令实现或者用变址寄存器Z逐个取字节。原理搞清楚了代码怎么写都行核心就是别把高低字节弄反。我调试时专门用串口工具抓过PLC发出的帧发现频率和命令都对但变频器就是不响应最后抓包一看CRC字节顺序发反了。这个错误对新手特别有迷惑性因为从串口工具上看帧格式、功能码、数据全都天衣无缝唯独校验错一个位就从站就认为帧无效直接丢弃。所以建议程序写完后第一步用串口工具验证CRC而不是直接连变频器调。4. 程序实现完整的发送、接收与轮询逻辑4.1 寄存器分配与程序框架程序整体我分成四块初始化、发送帧构造、接收解析、轮询调度。寄存器分配尽量留出余量方便以后扩展第四台变频器。寄存器用途D0轮询指针1~3D10~D121~3号目标频率单位0.01HzD20~D221~3号运行状态字D100~D107发送缓冲区8字节D104CRC临时存储D200~D231接收缓冲区32字节D250轮询超时计时M0~M2触摸屏正转按钮信号M10~M12触摸屏停止按钮信号M8122发送触发M8123接收完成标志轮询思路很简单D0从1循环到3每次处理一台。对当前这一台变频器依次发送频率帧、命令帧、读取状态帧然后跳到下一台。三台跑完一圈再从头开始。4.2 初始化与RS指令初始化在M8002通电瞬间做一次M8002 |--[MOV H0087 D8120] |--[SET M8161] |--[MOV K1 D0]然后M8000常通执行RS指令负责持续的收发监听M8000 |--[RS D100 K8 D200 K32]这里发送缓冲区长度我固定为8字节因为06功能码写单寄存器的帧长度正好是8字节。如果后面改用10功能码写多寄存器帧长会变需要把K8改掉。4.3 发送帧的拼接与CRC子程序以1号变频器为例目标频率存在D10触摸屏写入的单位是0.01Hz所以在屏上输入20.00D10里的实际值就是2000。PLC要做的事是把这个值拼进帧里。拼接过程我用了一个简单的思路先把设备地址、功能码、寄存器地址、数据分别放入D100到D103再调用CRC子程序把CRC填入D104。由于RS指令发送时每个D是高字节先发所以D100到D103的赋值必须和发送顺序严格对齐1号变频器写频率帧 D100 H0106 // 01地址、06功能码 D101 H2000 // 20寄存器地址高、00寄存器地址低 D102 H07D0 // 07数据高、D0数据低 D104 CRC结果 // 由子程序填好低字节和高字节同理命令帧把D101改成H2001D102放命令字就行。正转命令字是H0001反转是H0002停止是H0000。CRC子程序在每次拼接完成后调用一次。调用前把帧长度放到一个公用寄存器我用的D40然后把CRC算好填回D104。这里要注意如果用的是D100到D103帧长度就是4个寄存器、8个字节千万别填错。4.4 接收解析与状态存储读取状态帧我用03功能码读2100H寄存器一个长度帧结构是01 03 21 00 00 01 CRC_LO CRC_HI变频器正常响应时返回的数据长这样01 03 02 状态高 状态低 CRC_LO CRC_HI接收缓冲区里D200开始是响应帧。由于RS指令收进来的每个D也是高字节在前D200H0103D201H0200D202就是状态字。我把D202的数据整理后存到D20~D22里触摸屏直接读取显示。这里有个很实际的小经验接收完成标志M8123一旦置ON程序处理完以后必须立刻RST M8123。如果忘记复位高速轮询时下一帧数据来了但标志还卡在上一次接收缓冲会被覆盖状态值就会乱跳。我第一版程序就吃过这个亏触摸屏上状态忽有忽无查了半天才发现是M8123没复位。4.5 三台变频器的轮询与超时保护轮询调度我用“发送完成后触发下一帧”的方式。流程是D01时拼1号变频器频率帧发送M8122发送完成拼1号命令帧发送命令帧发送完成拼1号读状态帧发送读状态帧的响应到达M8123置ON解析状态然后把D0加1开始2号变频器D0大于3时回到1。这个流程全部用发送完成标志M8122和接收完成标志M8123互相衔接不会出现同一时刻有两帧在线上冲突的情况。相对于固定定时轮询这种事件驱动方式更稳变频器响应快慢不会影响下一帧的发送时机。加超时保护是必须的。如果某台变频器掉线、参数错误或者通讯线断PLC会一直等M8123整个轮询就卡死在那里后面几台全跟着瘫痪。我在程序里加了一个监视定时器发完任意一帧后启动D250计时如果100ms内M8123还没来就认为本帧超时直接跳过这台记录一个通讯故障标志继续轮询下一台。这样一台掉线不影响另外两台正常工作触摸屏上还能把掉线设备标红报警。5. 现场排查实录五类常见问题5.1 问题速查表调试过程中踩了不少坑整理成一张速查表方便以后直接对着查。现象可能原因排查方法变频器完全没响应站号、波特率、数据格式不匹配先用RS485工具单独测变频器确认参数PLC串口助手能收到乱码RS指令16位模式M8161没置ON检查M8161是否在M8002时SET帧格式正确但CRC报错高低字节装反或CRC计算有误用串口工具抓包用软件计算器比对CRC只第一台正常后面不稳缺终端电阻屏蔽层没接地末端并120欧电阻屏蔽层单端接地能调频但电机不转变频器频率来源还是面板把主频率来源和运转指令来源改为通讯轮询一段时间后全部卡死接收超时没处理M8123没复位加超时跳过机制处理完立即RST M8123在线监控时通讯中断编程口被GX Works占用运行时不要插编程电缆或调完立即拔掉5.2 几个值得写进笔记本的细节第一个细节是通讯线接线顺序。成品转换模块的A/B端子和台达MS300的D/D-端子看起来应该A接D、B接D-但实际上不同批次设备定义有出入。我在现场就遇到过A接D不行、对调以后才通的情况。所以初次接线别急着锁端子用万用表或者直接发一帧试一下通了再固定。第二个细节是频率命令的单位。台达MS300的2000H寄存器默认单位是0.01Hz触摸屏上如果要显示20.00Hz屏上数值和寄存器值正好差100倍。这个比例关系在屏上做一次缩放就行但一定要在程序注释里写清楚不然过几个月自己回来看都容易懵。第三个细节是停止命令的处理。我用写0000H到2001H来停车实测有效。但不同固件版本对运行命令字的定义有差异有些版本支持0003H表示停止有些则是位定义方式正转位、反转位、故障复位位各占一个bit。这种差异不是靠猜能猜出来的拿到一台不熟悉的设备先翻手册确认命令字再用面板点动验证最后才接入PLC程序。第四个细节是触摸屏与PLC的通讯也会占用编程口。FX1s只有一个通讯口触摸屏如果直连这个口那么电脑就不能同时在线监控。我在现场调试时经常用“触摸屏连着、电脑拔了”的模式改完程序下载完立刻拔线再让触摸屏接管。如果调试时非要监控就得把485转换模块先断开不然两边抢口通讯时通时断特别容易误判为干扰问题。5.3 扩展想法要不要把写频率和写命令合并这套程序我用的是06功能码逐条写每条8字节一台变频器一轮要发三条帧频率、命令、读状态。三台变频器轮一圈大概几百毫秒对小设备足够了。如果后续设备变多或者要求更快的轮询刷新率可以改成10功能码写多寄存器一帧把频率和命令同时写进去01 10 20 00 00 02 04 07 D0 00 01 CRC这帧的意思是对设备01连续写2个寄存器从2000H开始第一个写频率07D0H第二个写命令0001H。一帧代替两帧效率提升明显而且逻辑上更紧凑。代价是发送缓冲区长度要改成11字节CRC子程序循环的字节数也跟着变其他地方不用大动。等哪天需要扩展第四台甚至更多台时我大概率会把程序改成这种合并写法。这台设备投运以后触摸屏上能实时看到三台变频器的运行状态操作工改配方只用在屏上敲几个数字。整套改造最大的成本不在硬件而在把Modbus RTU协议在FX1s上跑通的那两天调试时间。但摸清楚这套路之后以后凡是遇到老旧PLC控制新变频器的活我心里就特别有底了。