
刚带自动化项目那几年我最怕听到的一句话就是“现场编码器的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. 编码器侧关键参数线数、分辨率与伺服里的2621442.1 编码器的PPR和线数该怎么理解编码器包装上标的“1000线”、“2500线”指的就是码盘一圈输出多少个A相脉冲行业内叫PPRPulse 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或者驱动器上别嫌多一根线麻烦等哪天你需要在任意位置重新校准原点你会感谢这根线的。