刚带自动化项目那几年,我最怕听到的一句话就是:“现场编码器的AB脉冲不对。”AB脉冲这名字听着特简单,无非就是两根信号线嘛,可真要把它从编码器一路调通到PLC、再送进上位机界面,里头的坑比通讯协议多得多。相位反了、计数丢脉冲、干扰导致数值漂移、上位机刷新卡顿——这些问题每一个都足以让你在现场待到后半夜。这篇文章我就打算一次把AB脉冲讲透,从编码器输出原理开始,到PLC高速计数器的配置,再到上位机怎么读取和显示,按完整链路一步步来,顺便把我在现场踩过的一些坑也一并交代了。
这文章适合谁看?刚刚接触运动控制、伺服调试的电气工程师,写PLC程序的车间调试人员,做C#或LabVIEW上位机的软件工程师,都会用得上。你先不用管自己懂不懂正交信号,只要设备上带着旋转编码器,或者伺服驱动里能看到“编码器分辨率”这类参数,这篇文章就能帮你把概念和实操串起来。读完你会明白:A相和B相到底怎么产生,为什么靠两路脉冲就能知道方向和位置,PLC里的高速计数器要怎么选模式和配滤波时间,上位机里读到的那个“脉冲数”又该怎么换算成毫米和转速。
1. AB脉冲到底是什么:一根轴上两路相差90度的信号
1.1 编码器内部是怎么“变”出A相和B相的
AB脉冲通常来自增量式旋转编码器。普通电机轴上装一个码盘,码盘上均匀地刻着一圈透光槽,发光管和接收管分居码盘两侧。轴一转,透光和遮光交替出现,接收管就输出一串方波脉冲。这个脉冲数等于码盘槽数乘以转动圈数,所以通过对脉冲计数就能推算出轴转了多少圈,再结合机械传动参数,就能换算出直线位移或角位移。这是增量编码器最核心的工作原理。
实际产品里不只有光电式,还有磁编码器。磁编码器内部是一个充了多对磁极的磁鼓,旁边放磁阻传感器或者霍尔芯片,轴旋转时磁场方向变化被芯片感知,内部电路直接输出方波。比如热词里提到的AS5047P,就是一颗14位磁编码器芯片,内部有CORDIC算法直接解算出角度,同时也能输出增量式的ABZ信号。这类方案因为不怕油污、体积小,现在被大量用在伺服电机尾部,你手上那台汇川伺服MS1H4系列,用的多半就是这类高分辨率编码器。
1.2 为什么A相和B相必须差90度,以及Z相是干什么的
增量编码器最巧妙的地方在于:码盘上不是只有一圈透光槽,而是错位放置了两个读头,输出的两路方波在相位上天然差了90度,这就是所谓的正交信号。假设电机正转时A相脉冲领先B相90度,反转时就会变成B相领先A相90度。控制器只要检测脉冲边沿的先后顺序,就能判断出轴在往哪个方向转。光有一个A相脉冲只能测速度,测不了方向,也无法做位置修正,所以AB两相缺一不可。
除了A相和B相,大多数编码器还会输出一个Z相脉冲,每旋转一圈只出一个,用来做机械原点或零点定位。很多设备调试时“找不到原点”,问题往往就出在Z相没有正确接进PLC或驱动器。单独靠AB脉冲累计的计数值在断电后会丢失,重新上电后必须回一次原点,而原点信号的来源通常是Z相,这个细节在项目方案设计时就要提前想好。
2. 编码器侧关键参数:线数、分辨率与伺服里的262144
2.1 编码器的PPR和线数该怎么理解
编码器包装上标的“1000线”、“2500线”,指的就是码盘一圈输出多少个A相脉冲,行业内叫PPR(Pulse Per Revolution)。这里要特别提醒一句:在4倍频计数模式下,控制器会在A相上升沿、A相下降沿、B相上升沿、B相下降沿各计一次数,也就是说2500线的编码器,一圈能采到10000个计数,分辨率直接提高了4倍。所以当别人跟你说“编码器是多少线的”,你先不要急着拿它当最终分辨率,得看PLC或驱动器用的是一倍频还是四倍频。
在伺服系统里,光靠码盘物理线数还不够。电机屁股后面那颗编码器经过驱动器内部细分处理后,分辨率可以做得非常高。就像你搜到的“汇川伺服MS1H4在驱动器里看到默认编码器线数是262144”,这个数字其实已经超过了普通码盘的物理槽数,它是编码器原始信号经过驱动器内部的电子细分和后级倍频之后得到的总分辨率,262144等于2的18次方,换算成单圈脉冲就是一圈18位,这在绝对值编码器里很常见。
2.2 伺服驱动器里的262144可以改吗
这个问题我经常被问到,你打开汇川伺服调试软件,在电机编码器参数页面看到一个“编码器线数”或者“编码器分辨率”的数值,显示262144。很多人的第一反应是:我的设备只需要10000个脉冲走一圈,这个数字太大了,能不能改成10000?
答案是:不建议改,而且绝大多数驱动器根本不允许你改。这个数值是驱动器固件从编码器通信中自动识别出来的,它代表电机位置闭环的底层分辨率,速度环、电流环、位置环全都基于它来计算。你强行改小,轻则位置不准,重则驱动器直接报编码器故障或者飞车。实际上你处理这类问题不应该去改编码器分辨率,而应该去调电子齿轮比。汇川伺服里有一组电子齿轮比的参数,比如Pn202/Pn203这类,默认分子分母可以自由设定,你真正要改的是这个比例,让上位机发10000个脉冲时电机走一圈,而编码器内部那262144个细分值保持不变。这样既满足你的脉冲数要求,又不破坏伺服内核的运算精度。
2.3 增量编码器与绝对值编码器的区别
AB脉冲是从增量编码器来的,它输出的是“相对位置”。断电再上电后,控制器不知道轴当前在哪里,必须先找原点。而绝对值编码器每个位置都有唯一编码,断电后位置信息不丢,一上电就知道当前坐标。它的输出数据通常是二进制编码或者通过RS485、SSI、BISS等总线上报,不直接出AB脉冲。所以如果你在项目里既要求断电记忆位置,又希望PLC用高速计数器直接收脉冲,那就要考虑是不是该选带断电记忆功能的绝对值编码器,或者用电池后备式的多圈绝对值编码器,再通过总线读取。很多人把这两种编码器混为一谈,买回来才发现PLC高速计数器根本读不了绝对值编码器的数据,这才是真正的坑。
3. PLC侧怎么把AB脉冲变成真实位置和速度
3.1 高速计数器不等于普通计数器
PLC的普通计数器一般只能接收低频开关信号,扫描周期动辄几毫秒甚至十几毫秒,根本追不上编码器输出的高频脉冲。要处理AB脉冲,必须用PLC内置的高速计数器(HSC)模块或者外部高速计数模块。以西门子S7-200 SMART为例,它自带6路高速计数器,HSC0到HSC5,其中HSC0和HSC1支持AB相正交计数,输入点默认分别接到I0.0和I0.1。三菱FX系列用的是C235这类高速计数器,欧姆龙则用CTBL配合高速输入单元。记住一个原则:在你编写梯形图之前,先查清楚这个型号的PLC支持哪些高速计数器通道、哪几个输入端子被占用,因为一旦这些I/O口被普通输入占用了,高速计数器通道就废了。
3.2 S7-200 SMART高速计数器的AB相模式配置
以S7-200 SMART为例,AB脉冲要接进高速计数器,光写梯形图是不够的,还要先在系统块里做硬件组态。打开STEP 7-Micro/WIN SMART,选中CPU,在“系统块”里面找高速计数器配置。S7-200 SMART的高速计数器工作模式里,模式9、模式10、模式11是AB相正交计数,区别在于有无外部复位信号和控制方向的方式。我们最常用的是模式9,即A相输入、B相输入,4倍频计数,由内部方向位判断正反。模式10带外部复位端子,模式11带外部复位和外部方向控制。如果设备要做原点回零,外部复位模式会更方便,因为可以通过一个接近开关或Z相信号随时把当前计数值清零。
模式选好了,还要给高速计数器指定一个当前值存储地址,一般我习惯放在VD100这样的双字地址。接下来是中断事件,S7-200 SMART的高速计数器支持方向改变中断和当前值等于预设值中断。方向改变中断可以用来记录正反向运动状态,当前值等于预设值中断适合做定长切割或定位——当计数值到达设定值那一个扫描周期,程序立刻去执行下一步动作,精度比在主程序里比较VD100要高出很多。
3.3 滤波时间不配,高速计数就是摆设
这是我在现场踩过最深的坑之一。S7-200 SMART的输入点默认带有模拟滤波,对低速开关信号是好事,但放在AB脉冲上就是灾难。如果编码器输出频率很高,而滤波时间设置得太长,高频脉冲会被滤掉,导致计数丢失。正确的做法是在系统块的数字量输入滤波设置里,把接编码器的那几个输入点的滤波时间调到最小,S7-200 SMART可以选择0.2微秒,这样能保证高速正交信号被完整识别。三菱FX系列也有类似输入滤波器设置,默认值经常是10ms,必须改成x1也就是最低档。
另外接线时一定要注意输入类型。很多PLC输入端子是漏型/源型可切换的,如果你的编码器是NPN开集输出,PLC输入点就得接成源型;如果是PNP输出,就得接成漏型,不要接反。更稳妥的做法是选用带差分输出的编码器,用A+、A-、B+、B-四根线接入PLC或驱动器的差分输入口,抗干扰能力会强很多,长距离传输时尤为明显。
3.4 具体算一遍:2500线编码器怎么换算成毫米和转速
假设设备上用了一个2500线的增量编码器,装在伺服电机尾部,电机通过一个10毫米导程的丝杆带动工作台移动。PLC高速计数器按4倍频计数,那么电机转一圈,计数器累加10000。工作台移动10毫米,折合下来每个脉冲对应的位移就是10毫米除以10000,等于0.001毫米,也就是一个微米。你看,这个换算关系非常简单,但非常重要,因为你在上位机里看到的那串“脉冲数”,最终要乘以这个脉冲当量才是用户真正关心的毫米数。
速度换算也是类似的思路。在PLC的高速计数器中断中,每隔固定时间(比如100毫秒)读取一次当前计数值,把两次读数的差除以时间间隔,就可以算出脉冲频率;再除以一圈对应的计数个数,就是每秒多少转;乘以60就是每分钟转速。有人喜欢用运动控制指令里的速度参数直接读,那当然没问题,但如果你是在做老设备改造,PLC和编码器中间没经过伺服,这种自己算速度的方式就非常实用。我在中断里一般还会做一级滤波,取最近几次速度值的平均,避免机械抖动造成速度显示跳变。
4. 上位机侧:脉冲数如何变成界面上的位置和转速
4.1 上位机读数据,前提是先把通讯链路选对
上位机这一层,大家遇到的问题往往是“我PLC里已经看到计数值了,但上位机画面里永远不更新”。这通常不是程序写得不对,而是通讯链路没打通。最常用的做法是PLC通过Modbus TCP或者Modbus RTU把高速计数器VD地址映射到保持寄存器里,然后上位机去读取这个寄存器。S7-200 SMART本身就支持Modbus RTU和Modbus TCP,你只要在程序里用MODBUS_SLAVE指令把VD100映射到对应的保持寄存器地址,例如40001,上位机就能通过Modbus协议读取到当前计数值。三菱PLC则需要用电脑链接命令或者专用的通讯模块,欧姆龙可以走FINS协议,但原理都一样。
如果现场不需要PLC参与,直接把编码器接到电脑上,那就得用专用的USB计数器卡或者基于PC的运动控制卡,比如雷赛的DMC系列,厂家会提供DLL库和C#示例程序。这种方案的实时性更好,适合纯上位机实现高速采集和运动控制的场合。此外还有一种常见做法是接一个带Modbus输出的智能计数器模块,编码器先接模块,模块再通过Modbus把计数值上报给上位机。这种模块比较适合旧设备改造,省去了改PLC硬件的麻烦。
4.2 C#上位机读PLC并显示位置转速的完整思路
我用C#写上位机的次数比较多,这里给一个比较通用的思路。先引用HSLCommunication或者Sharp7这类通讯库,以HSL为例,用ModbusTcpClient连接PLC的IP地址,然后周期性地读取对应保持寄存器。读回来的原始数据是16位或32位的,注意大小端和对齐方式,S7-200 SMART的VD100映射到Modbus保持寄存器后,32位数据是高字在前,读取时要用“高位字左移16位再或上低位字”的方式拼出完整数值。
界面刷新方面,大多数新手喜欢在窗体上加一个Timer,每50毫秒读一次PLC并刷新Label的Text,这样做简单,但有个问题:串口或网络通讯是有延迟的,如果Timer触发的读取还没返回,下一次读取又开始了,很容易造成数据堆积和界面卡顿。我自己的做法是开一个后台线程跑循环读取,把读到的值放入一个共享变量或队列中,UI线程只负责把共享变量的值刷新到界面上。刷新频率通常设置成100毫秒或者200毫秒就够用了,人眼对速度变化的分辨率不会超过这个范围,没必要追求更快的刷新速度。
4.3 VS2019写的C#上位机源码,能用VS2015打开吗
这个问题我看到很多人在问,答案是有前提的能,但也有可能很麻烦。VS2019创建的解决方案文件(.sln)和工程文件(.csproj)在某些版本组合下可以被VS2015打开,但工程文件如果被VS2019改写成了新版格式,VS2015就打不开了。就算工程打开了,如果代码里用了C# 7.0以上的语法,比如switch表达式、可空引用类型等新特性,VS2015也会报语法错误。最稳妥的方法是:新建一个VS2015项目,把源代码文件复制进去,重新添加NuGet包引用,再逐个解决编译错误。说实话,跨大版本迁移源码这种操作,花的时间比重写一遍还长,所以如果项目还处于初期阶段,我建议直接统一到同一个开发环境版本。
此外,如果你用的是LabVIEW做上位机,通讯思路和C#基本一样,只是把TCP或串口读写封装成了VI。LabVIEW的优势是界面开发快,适合快速搭一个测试小工具;但要做复杂的业务逻辑、报表、数据库,C# WPF反而更顺手。WPF做界面可以绑数据,不用像WinForm那样手动刷新每个控件,代码会干净很多,适合稍微正式一点的设备上位机。
4.4 从PLC读出来的数据为什么要做工程换算
上位机从PLC读回来的其实就是一个整数脉冲数,你不换算,用户看到的就只是一串毫无意义的数字。要做的换算有两步:第一步是把脉冲数乘以脉冲当量,得到毫米、度或者相对位置;第二步是设置一个基准零点,以下数据都是相对这个零点的偏移。比如丝杆导程为10毫米、编码器4倍频后一圈10000个脉冲的案例里,上位机界面上应该显示电机转一圈时位置从0.000变到10.000毫米,而不是显示脉冲数从0变到10000。
速度显示也是一样,上位机里显示的是“每分钟多少转”或“每秒多少毫米”,这需要根据PLC或上位机的速度计算逻辑来设定比例。这里还要注意方向问题,如果上位机显示的正负方向和实际运动方向相反,别急着改程序,先看编码器AB两相有没有接反,或者PLC高速计数器的方向判断位是不是反了。很多时候改一行配置比改程序快,也更安全。
5. 现场最常踩的坑与排查实录
5.1 计数乱跳、数值漂移,十有八九是干扰问题
AB脉冲属于高速信号,也是最容易受干扰的信号之一。我碰到过的典型案例是:PLC没接电机时,高速计数器显示数值稳定,电机一启动或者变频器一动,计数值就开始乱跳。这种问题的根源几乎都是编码器线和动力线在同一个线槽里走线,或者屏蔽层接地方式不对。编码器线必须使用屏蔽双绞线,屏蔽层单端接地,最好是在PLC或驱动器那一端接地。如果是伺服电机自带的编码器线,不要自己随便剪断延长,电流环和位置环信号对线缆质量要求很高,延长线可能引发各种奇怪问题。
还可以在编码器电源进线处加磁环,或者用开关电源单独给编码器供电,不要和杂七杂八的继电器共用一个电源。PLC输入端如果滤滤时间已经调到最低仍然乱跳,可以在编码器输出端和PLC输入点之间串一个500欧姆左右的电阻并联小电容,但这个方法会降低脉冲电平,要谨慎使用。
5.2 丢计数和方向反了,是新手翻车率最高的两个点
丢计数很典型:高速转没问题,低速也没问题,偏偏中速运转时计数值偶尔少几十个。这种问题通常来自扫描周期不够快,或者滤波时间设置不合适。所以再次强调,处理高速脉冲时,读计数和判断方向都要放在中断中,不要放在主程序里每隔一个扫描周期轮询一次。另外还要注意PLC高速计数器的计数上限,S7-200 SMART的当前值是32位有符号整数,范围从-2147483648到2147483647。如果设备长时间单向运行,计数值可能溢出,程序里就要考虑“溢出清零”或“绝对值编码器回零”的逻辑。
方向反了的排查相对容易:先看PLC高速计数器模块里有没有“计数方向”的状态位,比如S7-200可以在高速计数器状态字节里读方向位;也可以用监控表强制观察当前值在正转时是增加还是减少来确定。如果方向确实反了,最简单的办法是对调A、B两相接线,或者是改PLC计数模式里的方向控制位,改程序不一定最优。
5.3 常见问题速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 计数值完全不动 | 编码器供电缺失或PLC输入点不够高电平 | 检查编码器电源和接线,用万用表测A/B相电压 |
| 低速正常,高速丢计数 | PLC输入滤波时间太长或扫描周期跟不上 | 把滤波时间调到最小值,改用中断读取 |
| 数值乱跳、无规律变化 | 编码器线受干扰或未共地 | 换屏蔽线,屏蔽层单端接地,与动力线分开布线,加磁环 |
| 正反方向反了 | A/B相接线反或方向位配置错误 | 对调A/B接线,或修改计数模式方向位 |
| 上位机读数一直不变 | 通讯链路不通或寄存器地址映射错误 | 先用调试助手读一遍Modbus寄存器确认地址 |
| 上电后位置丢失 | 用了增量编码器但是没有断点记忆 | 增加断电记忆寄存器或用绝对值编码器 |
| 伺服驱动里修改编码器分辨率导致报警 | 动到了不该改的固件参数 | 恢复默认值,改用电子齿轮比来匹配 |
| VS2019源码在VS2015里编译报语法错误 | 用了新版C#语法或新格式工程文件 | 新建低版本工程,复制源码,检查LangVersion设置 |
5.4 把人手从调试现场解放出来的几个小工具
现场调AB脉冲,我建议常备一台带波形捕获的示波器,至少是能看两路TTL波形的逻辑分析仪。编码器不转时,A、B两相应该都是稳定的高或低电平;手动慢慢转轴时,波形上能看到占空比基本相等的方波,而且A、B两相之间相位差是90度。如果相位差明显不是90度,要么是编码器坏了,要么是它的输出电路和你的接收端不匹配。这一步能帮你排除至少一半的电气类问题。
调试上位机时,可以用Vofa这类串口示波器工具快速查看PLC或单片机发上来的数据曲线,省得每次都在软件界面上反复改代码。如果是运动控制板卡方案,GRBL配套的上位机工具也可以用来做基本的位置测试,确认驱动器能正确响应指令脉冲后再接自己的上位机程序,这样定位问题会更高效。说到底,AB脉冲的调试就是一个信号链路逐级排查的过程:编码器输出是不是对的,接收端配置是不是对的,最终数据显示是不是对的,只要这三层都确认无误,设备就基本不会出离奇故障了。
我在实际调试中还有个习惯:设备第一次上电时,先不接电机负载,只让电机不带负载空转,用上位机或PLC的监控表看看编码器计数值在正转、反转时是否线性递增递减。确认这一层没问题了,再接机械传动,再验证脉冲当量和方向。这样即使后边出了问题,也能快速判断是机械装配问题还是电气信号问题。这套流程看着笨拙,但真的能省下大量盲猜的时间。最后再送一个小技巧:如果你的设备有Z相,务必把它接到PLC或者驱动器上,别嫌多一根线麻烦,等哪天你需要在任意位置重新校准原点,你会感谢这根线的。