上次现场做一台四工位转台的位置控制,客户要求三个位置快速切换,定位精度0.1mm,单段节拍2秒以内。现场PLC没有多余脉冲口,伺服柜到转台距离七八米,用脉冲方式还得加模块、铺屏蔽线,成本和时间都不划算。后面直接用汇川SV660P伺服加ModBus RTU通信来解决,一根485线搞定位置指令下发,整台设备跑下来定位稳定,通信响应也完全够用。这篇就把从伺服参数配置、ModBus寄存器读写,到多段位置控制的完整过程整理出来,给同样被“低成本多轴定位”困扰的朋友做个参考。
这个方案适合两类人:一类是PLC没有脉冲口、不想换总线型PLC,但需要控制伺服做点对点定位的;另一类是做设备调试、想用手头485口临时驱动伺服验证动作的工程师。读完你可以直接用ModBus RTU把SV660P跑起来,实现电机使能、回零、多段位置切换,后面换EtherCAT也只是换一套通信框架,思路是相通的。
1. 方案选型与系统搭建:为什么是SV660P加ModBus RTU
1.1 这个项目要解决什么问题
转台有四个工位,每个工位需要在三个不同角度停下,做点焊和检测动作。核心需求其实就两个:位置能精确到0.1mm级别,切换速度要够快。电机负载经过5:1减速器带同步轮,电机轴转一圈,负载走62.8mm左右,0.1mm精度折算到电机编码器上,大概是一万多个脉冲,SV660P这种23位编码器配置冗余量非常大,精度不是问题。
真正的瓶颈在指令下发通道。原来方案走脉冲,但PLC端没有高速脉冲输出口,扩展一个脉冲模块少说也要几百块,而且从柜子到转台要重新布脉冲线、方向线,线缆成本加上人工,现场安装周期硬生生多出半天。后来想干脆走485通信,伺服和PLC都支持ModBus RTU,一根屏蔽双绞线就能解决问题。
当时也没底,担心485通信速度跟不上。实际算下来,ModBus RTU在115200波特率下,读一条状态字大概3ms,写一条目标位置6ms左右,一个完整的“写位置-触发-读完成”流程也就20ms上下,对于需要2秒以内完成一次定位的转台项目,这个响应速度完全不是瓶颈。
1.2 系统拓扑与硬件清单
这套方案里PLC是主站,伺服驱动器是ModBus从站。PLC通过RS485口发出读写下指令,SV660P伺服驱动器响应指令,驱动电机运动,编码器信号只在伺服和电机之间闭环,PLC并不参与实时闭环,只负责下目标和判断状态。
硬件上我用了这些:
- 汇川SV660P伺服驱动器一台,配套MS1系列伺服电机
- PLC选用的是汇川H5U系列,自带RS485通信口,支持ModBus主站功能
- USB转RS485调试线一根(电脑调试阶段用)
- 屏蔽双绞线若干米,用于柜内到电机侧通信连接
- 120Ω终端电阻两个,485线路两端各接一个
这里提醒下,485通信虽然能看到两根线,但实际工程里不是随便接两根线就能稳定跑的,后面接线部分细说。
1.3 接线要求与通信线缆
SV660P的RS485通信口在驱动器的CN3端子,具体针脚定义翻一下随机附带的手册,不同批次可能略有差异。接线时把485A接到PLC的485A,485B接到PLC的485B,千万别接反,接反的表现是通信偶尔通偶尔不通,或者完全没反应,排查起来很绕。
线缆我建议用屏蔽双绞线,屏蔽层在伺服侧单端接地。之前有台设备偷懒用了普通平行线,结果伺服一启动,电机运行过程中通信时不时报超时,最后换回屏蔽线才解决。高频干扰就是这么现实,电机动力线和编码器线不可避免会走同一个线槽,485线没有屏蔽层就很容易把噪声耦合进去。
如果现场通信距离超过50米,或者在同一个485总线上挂了多台伺服,记得在总线两端各并联一个120Ω终端电阻。这个电阻不是可选项,少了它,长线传输时信号反射会导致误码。短距离实验可以不接,现场设备建议老老实实接上。
1.4 三种控制方式的取舍
控制伺服的无非三条路:脉冲方式、ModBus RTU、EtherCAT总线。我在这三者之间选ModBus,不是因为ModBus最先进,而是它在“够用”和“成本”之间最平衡。
脉冲方式最传统,PLC发脉冲给伺服,伺服跟着脉冲走。优点是实时性好、PLC程序直观;缺点是硬件成本高,一个轴至少占一个脉冲口,多轴就得加模块,而且高速脉冲线对屏蔽要求高,布线麻烦。
EtherCAT总线性能最强,支持多轴同步、位置插补,适合机械手、龙门同步这类场景。但EtherCAT需要PLC支持总线主站功能,中型PLC起步,伺服也要配总线选项,整套成本比ModBus方案高出一截。转台这种简单多工位定位用EtherCAT,有点大炮打蚊子。
ModBus RTU正好卡在中间,用485线就能跑,PLC自带通信口,没有额外硬件成本。虽然不能做多轴同步,但对于“单轴走到某个位置停下,再来指令再走”的应用,性能完全够用。如果你的设备后续要升级成多轴联动,选型时就得考虑伺服是否支持EtherCAT,别在ModBus一棵树上吊死。
2. 伺服驱动器参数配置:先把底子打好
2.1 恢复出厂与初始化
拿到一台新的SV660P,或者是从别的设备上拆下来的旧机器,第一步先把参数恢复成出厂状态。原因很简单,伺服参数可能被之前的人改过,一些隐藏设置会影响后面通信调试,不如清干净重新来。
面板操作方式不细说了,说明书里都有,我一般习惯在伺服调试软件里做,连接好USB后一键恢复。没有调试软件的话,面板上也能操作,找个“参数初始化”或者“恢复出厂”的菜单项,确认执行后断电重启。
恢复出厂后切记先把编码器类型、电机型号这些信息核对一遍。SV660P大多配置汇川自家电机,驱动器会自适应读取电机铭牌参数,一般不用手输。如果是替换电机或者非标电机,一定要手动核对电机额定电流、额定转速、编码器分辨率,这些参数错了,后面调什么都白搭。
2.2 通信协议与通信参数
SV660P支持ModBus、CANopen、CANlink等协议,出厂默认可能不是ModBus,所以参数配置第一步是把通信协议切到ModBus上。这块参数在H0C组,H0C-00是通信协议选择,设成0就是ModBus RTU,具体值以手上说明书为准,不同固件版本对协议编号的定义可能不一样。
切完协议后继续调H0B组的通信参数,这组管波特率、数据格式、站号和响应延时。我用的配置是:波特率115200,数据格式1-8-N-2(一个起始位、8个数据位、无校验、2个停止位),站号设为1。
提示:这里的站号就是ModBus从站地址,如果你后期要挂多台伺服,每台的站号必须唯一,范围一般1到247。设成0或者重复,通信都会出乱子。
波特率选择要结合通信距离来考虑。柜内短距离跑115200没问题,几十上百米就降到38400或者19200更稳妥。我这次通信距离比较短,所以用了115200,响应速度最快。要注意PLC主站那边的波特率、数据格式必须和伺服完全一致,两边差一个参数都握手不上。
2.3 控制模式与指令来源
SV660P支持速度模式、位置模式、转矩模式。多段位置控制必须用位置模式,在H05组把控制模式设成位置控制。
接下来是关键一步,设置指令来源。SV660P的运行指令(使能信号)、位置指令分别有独立的来源选择:是面板控制、端子控制,还是通信控制。选ModBus通信后,必须把这两项都指到“通信”上,否则PLC发再多报文,伺服也会当成没看见。
这个坑我踩过不止一次。第一次调试时,控制模式已经切成位置模式,ModBus参数也配好了,PLC往目标位置寄存器写了值,伺服就是不动,面板上一直显示“端子使能无效”之类的状态。后来查手册才想起来,使能信号来源还停在“面板/端子”上,伺服默认还在等外部IO给使能,通信过来的使能报文被忽略了。
2.4 电子齿轮比与位置单位换算
这是整个配置过程中最需要动脑子的地方。SV660P的位置指令单位有“用户单位”和“编码器单位”两种概念。如果选用户单位,就需要设置电子齿轮比;如果直接选编码器单位,目标位置直接填编码器脉冲个数,省去换算。
我这次为了省事,直接把位置控制单位设成编码器单位。230万分辨率电机(23位编码器,8388608脉冲/转),写多少脉冲就走多少脉冲,PLC程序里自己算毫米和脉冲的换算关系。
假设电机轴通过5:1减速器带动直径100mm的同步轮,同步轮周长314.159mm,负载跑一圈,电机要转5圈,所以电机一圈对应的行程是62.832mm。要移动50mm,需要的编码器脉冲数就是:
50 ÷ 62.832 × 8388608 ≈ 6676384个脉冲
这个数字在PLC里用浮点数算出来再转成32位整数发给伺服即可。
如果你希望直接在PLC里用mm作为单位下发,不用脉冲数,那就得设置电子齿轮比,让用户单位直接对应0.01mm之类的工程单位。电子齿轮比数值按公式算出来后约分成整数比填进对应参数。实际调的时候比较麻烦,因为减速比和同步轮周长往往不是整数关系,约分后分子分母很大,写入和调试都费劲。我的建议是:通信控制优先用编码器单位,PLC侧做一次换算,逻辑更可控。
2.5 参数保存与重启
SV660P修改参数后,部分参数是掉电不保存的,需要通过面板或软件执行“参数保存”操作,然后重新上电才能完全生效。尤其是通信协议、控制模式这类基础参数,改完不保存,一断电全部恢复默认,第二天来现场发现伺服怎么都不通信,那种感觉太崩溃了。
保存完成后我习惯把伺服面板切回显示“rdy”等运行状态。如果面板上显示报警代码,例如编码器相关、过流、过压等报警,先按说明书处理报警,确认伺服处于无报警状态再往下调。带着报警做通信调试,即使报文全对,伺服也会拒绝执行运动指令。
3. 寄存器地址与ModBus报文:看懂这层,你就能自己开发
3.1 汇川ModBus地址映射规则
SV660P的ModBus寄存器地址不是随便给的,它和伺服内部功能码一一对应。功能码H0B-00对应ModBus地址0x0B00,H0B-01对应0x0B01,依此类推。也就是说,你要读写哪个功能码,只需要把功能码组的编号和参数序号拼成十六进制地址,就是ModBus的寄存器地址。
比如要改站号H0B-02,地址就是0x0B02;要读当前位置H00-03,地址就是0x0003。这样理解之后,即使手边没有完整地址表,只要翻到手册的功能码列表,你也能推算出来该读写哪个寄存器。
32位参数占两个寄存器,比如目标位置这类数据,低位字和高位字分别映射到相邻地址,例如0x2002和0x2003。写32位参数时,要么用10功能码一次连续写两个寄存器,要么分两条06指令先写低字再写高字,后者要注意时序,动作期间拆分写容易导致数据不完整。
3.2 常用寄存器速查表
这里把我当时用的通信对象地址整理一下。这套地址是从SV660P通信章节附表里查来的,不同固件版本可能略有差异,使用前一定核对说明书里的“通信对象字典”表。
| 寄存器地址 | 功能 | 说明 |
|---|---|---|
| 0x0B00 | 通信波特率 | 0:38400,1:19200,2:9600,3:57600,4:115200 |
| 0x0B01 | 通信数据格式 | 0:1-8-N-2,1:1-8-E-1,2:1-8-O-1,3:1-8-N-1 |
| 0x0B02 | 通信站号 | 1到247 |
| 0x0003 | 当前位置 | 32位参数,只读,单位由位置单位决定 |
| 0x0002 | 当前速度 | 只读,用于监控 |
| 0x2000 | 控制字 | 16位,使能、触发、报警复位等控制位 |
| 0x2001 | 状态字 | 16位,伺服准备好、定位完成、报警等状态位 |
| 0x2002 | 目标位置低16位 | 32位目标位置的低字 |
| 0x2003 | 目标位置高16位 | 32位目标位置的高字 |
| 0x2004 | 目标速度低16位 | 32位目标速度的低字 |
| 0x2005 | 目标速度高16位 | 32位目标速度的高字 |
0x2000控制字每一位的含义,汇川手册里有一张表。我当时常用的几个位是:bit0伺服使能,bit3位置触发/运行,bit7报警复位。具体每一位的精确含义,一定要按你手上的手册版本确认,我在这里不展开完整表,避免误导。
3.3 三大功能码报文模板
ModBus RTU最常用的三个功能码:03读寄存器,06写单个寄存器,10写多个寄存器。报文格式都是“地址、功能码、数据、CRC”,CRC是两字节,低字节在前。
读一个寄存器,比如读站号H0B-02,从站地址是01:
发送:01 03 0B 02 00 01 CRC- 01:从站地址
- 03:读寄存器功能码
- 0B 02:寄存器起始地址,0x0B02
- 00 01:读取1个寄存器
- CRC:两字节校验
写单个寄存器,比如把站号改成5:
发送:01 06 0B 02 00 05 CRC写多个寄存器,一次写目标位置32位。假设目标位置是123456,十六进制是0x0001E240,低字0xE240,高字0x0001:
发送:01 10 20 02 00 02 04 E2 40 00 01 CRC- 01:从站地址
- 10:写多个寄存器
- 20 02:起始地址0x2002
- 00 02:写2个寄存器
- 04:后面数据字节数,2个寄存器共4字节
- E2 40:低字
- 00 01:高字
这里有个坑:汇川部分固件默认32位数据是“低字在前”,也就是低16位存到低地址;如果写入之后发现位置跑得不对,比如应该走10000结果走了65536倍,很可能是高低字顺序反了,需要切换伺服的字序参数。
3.4 CRC16校验代码
ModBus RTU的CRC校验算法是固定的CRC16-ModBus,初值0xFFFF,多项式0xA001。你要是用PLC编程,很多PLC自带ModBus库,CRC不用自己写;但如果用单片机或者自己写通信调试工具,这段代码直接抄:
uint16_t crc16_modbus(uint8_t *data, uint16_t len) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < len; i++) { crc ^= data[i]; for (uint8_t j = 0; j < 8; j++) { if (crc & 0x0001) { crc = (crc >> 1) ^ 0xA001; } else { crc >>= 1; } } } return crc; }发送报文时CRC的低字节在前,高字节在后,跟上面报文示例里的顺序一样。写程序时可以通过ModBus调试工具先验证CRC函数对不对,卡在这块纯粹浪费时间。
4. 多段位置控制实现:从单段定位到多段切换
4.1 方案一:PLC实时改写目标位置
这是最通用、也最容易理解的做法。每一段位置都先存到PLC的寄存器里,执行到哪一段,就往伺服的目标位置寄存器里写哪一段的值,然后通过控制字触发运动。
流程大概是这样的:
- 读状态字,确认伺服使能、无报警、没有正在运行的动作
- 写目标位置到0x2002和0x2003
- 写目标速度到0x2004和0x2005
- 控制字bit3置1,触发运动
- 轮询状态字,等待定位完成bit置1
- 控制字bit3清零,等待下一次触发
用PLC梯形图或结构化文本都能实现,核心就是这几步。要注意的细节是:位置写入和触发之间必须留出通信处理时间,不要同一轮扫描又写位置又触发,伺服可能还没来得及处理位置更新,触发就落空了。
速度怎么给?SV660P ModBus通信模式下,目标速度单位一般是0.1r/min。想跑300r/min就写3000;具体用哪个单位,记得确认手册。速度给太大会导致加减速过冲,给太小节拍跟不上,结合负载惯量慢慢试,现场我一般从最大速度的50%开始往上调。
4.2 方案二:SV660P内部多段位置
如果PLC通信周期太慢,或者你希望换段动作不依赖通信链路,可以用SV660P自己的内部位置表功能。H07组里有内部位置指令存储区,可以预先把几段目标位置和速度填进去,运行的时候通过DI端子或者ModBus写一个“段号选择”参数,伺服自己跳转执行。
这个方案的好处是响应极快,换段只需要改一个段号,不需要实时写大段的位置数据;坏处是位置值在伺服里,现场修改位置要重新下参数,灵活性差一些。程序调试阶段,我建议先用方案一快速验证机械行程和节拍,稳定后再把位置固化到伺服内部,减少PLC和伺服之间的通信负载。
4.3 多段切换的触发时序与状态判断
多段控制能不能稳定跑,关键看触发时序。我踩过一个很典型的坑:第一段定位完成后,PLC立刻写第二段位置并触发,但机械上还有微小振动,伺服其实还没有真正停稳。结果第二段起点带着残余误差,最终位置偏了零点几毫米。
后来我在每段之间加了一个延时,或者读状态字里的“伺服准备好”位判断机械完全稳定后再给下一段触发。如果设备节拍允许,加50到100ms的稳定延时,定位可靠性会明显提升。
另一点是状态字的读取方式。不要用“发一次读状态字,如果没完成就再发”这种简单轮询,最好做一个超时保护。比如目标位置下发后10秒内定位完成位没有置1,程序要报警停机,不然机械卡死时PLC还在傻傻轮询,电机堵转发热,很容易出事故。
4.4 定位精度与动态性能的几项设置
多段位置控制不是“位置对了就行”,伺服内部还有几个参数直接影响定位质量和机械寿命。
第一是定位完成宽度,伺服判断定位完成是根据当前位置与目标位置的偏差小于某个值来判定的,这个值在H07组里可以设。设太宽,机械还没到位就报完成;设太窄,伺服一直在“到位”和“偏离”之间反复跳动,定位完成信号可能抖动。我习惯按0.1mm折算成脉冲数来设,留一点余量。
第二是加减速时间。SV660P的加减速参数如果保持默认值,在轻载小惯量下问题不大;但转台这种带减速机和大转盘的负载,惯量比高,加减速太猛会在到位时引起振荡。我现场是把加速时间从默认值拉长一倍,定位完成信号明显干净很多,机械冲击也小了。
第三是增益匹配。SV660P有免调或者在线惯量辨识功能,如果你对增益调参不熟,先用自动整定让伺服跑一段往复运动,它会自动识别负载惯量并优化增益。实测下来,自动整定出来的参数虽然偏保守,但稳定性有保障,后续再手动微调速度环就够了。
5. 现场调试踩坑实录与问题排查
5.1 通信完全无响应
这是第一道坎。程序写好了,串口工具一发送,伺服那边完全没反应。排查顺序我从“物理层-数据链路层-应用层”走了一遍,最后发现是最粗心的问题:485的A、B线接反了。
如果接线确认没问题,再看通信参数是否一致。波特率、数据格式、站号三样,PLC和伺服必须完全一样。伺服默认波特率可能是38400,你PLC以为是115200,两边鸡同鸭讲,任何报文都白搭。用电脑调试时,先发一条03功能码读0x0B00,看看能不能读回波特率参数。能读回来,说明物理层通了;读不回来,要么接线错、要么参数错、要么线断。
5.2 使能后电机不动作
通信都通了,控制字也写了,伺服状态字也显示使能了,但电机就是不动,轴用手掰也掰不动,明显处于锁定状态。这种问题十有八九是位置指令来源没设对。
伺服处于位置模式,但位置指令来源还停在“面板”或“端子”,通信写进来的目标位置根本没有被采纳,电机自然不动。把位置指令来源切到“通信”,再触发一次就好了。同理,如果使能都使不上,检查H05组运行指令来源是不是“通信”,以及外部急停、限位、使能端子有没有被强制断开。
5.3 定位完成信号不置位
位置到位了,但状态字里的定位完成位一直不置1。首先看定位完成宽度设置,如果宽度特别小,比如零点几个脉冲,伺服永远觉得自己没到位。
另一种情况是位置寄存器一直在被外部频繁写入,比如PLC在每个扫描周期都在往目标位置寄存器里刷新同一个值,伺服会认为指令一直在更新,定位完成逻辑被反复重置。解决办法是只在需要改变位置时才写入,不要周期性重复写。
5.4 多段切换丢段或过冲
丢段最常见的原因是触发时序太快。位置刚写入,还没等伺服更新完,触发位就来了,这一段根本没执行。排查方法是看实际移动距离,丢段的话,电机基本没走或只走了很少的脉冲。
过冲则多半是速度太快或加减速太短,电机冲到目标位置附近停不住,冲过头之后又倒回来,整个动作看起来“刹不住车”。把目标速度调低一些,或者把加减速时间适当加大。要是机械本身有间隙,比如减速机齿隙、同步带弹性,过冲还会叠加间隙误差,这种问题调伺服参数解决不了,要回到机械侧找原因。
5.5 常见问题速查表
| 现象 | 可能原因 | 解决方向 |
|---|---|---|
| 完全无通信 | 485线序接反、通信参数不一致、站号错误 | 先用调试工具读0x0B00验证物理层 |
| 时通时断 | 485线质量差、干扰大、缺终端电阻 | 换屏蔽双绞线,单端接地,加终端电阻 |
| 使能无效 | 指令来源仍为面板/端子,外部急停/使能端子断开 | 检查H05组指令来源和DI端子状态 |
| 通信正常但不运动 | 位置指令来源不对、触发位没置位 | 确认位置指令来源为通信,按时序写触发 |
| 定位完成一直不置位 | 定位完成宽度太小、位置被周期性重复写 | 调整定位完成宽度,改成条件写入 |
| 位置跑到65536倍 | 32位高低字序反了 | 切换伺服字序参数 |
| 电机到位后振荡 | 增益过高、加减速太短 | 使用自动整定,延长加减速时间 |
最后再分享一个小技巧:做ModBus通信调试时,电脑上装个串口调试工具或者ModBus Poll,先把伺服当独立从站测通了,再上PLC。这样可以把问题边界切得很清楚,是通信层面的问题还是PLC程序的问题,一目了然。现场调试时间紧,这个习惯能帮你节省至少半天。