ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

正余弦编码器信号处理全解析:从硬件设计到归一化与角度解算

2026/9/28 12:32:23 拓冰建站 浏览量
正余弦编码器信号处理全解析:从硬件设计到归一化与角度解算 最近调一台伺服设备所有时序逻辑都对电机就是在过零位时抖一下速度环输出有明显毛刺。查了一圈才发现问题出在正余弦编码器的模拟信号处理上两路信号的直流偏置不一致软件里又没做归一化直接拿原始值算反正切在 90 度和 270 度附近误差特别大一过零位就露馅了。正余弦编码器在伺服电机、机床主轴、机器人和高精度转台上用得非常多它的输出不是现成的方波或数字量而是两路正交的模拟正弦波Sin/Cos需要通过硬件处理加软件解算才能得到角度和速度。这套链路说简单也简单说坑也坑硬件的调理电路、ADC 采样、软件的去直流和归一化任何一环没做好都直接影响最终分辨率跟稳定性。这篇文章就把我从硬件设计到软件处理的完整踩坑记录整理出来适合正在做运动控制或伺服驱动开发的工程师参考也适合刚接触正余弦编码器信号处理的新手避雷。1. 先搞清楚正余弦编码器到底在干吗1.1 为什么不能直接读数字码盘很多人刚接触运动控制时最先用的是增量式编码器或绝对式编码器输出是 TTL 电平的 A/B/Z 脉冲或者走 BISS、SSI、BiSS-C 这类数字协议主控端直接计脉冲或接收帧数据就行简单粗暴。正余弦编码器不一样它输出的是两路模拟量本质上是光电或磁电结构产生的周期信号。在光栅编码器里光透过主栅和指示栅的摩尔条纹在光电探测器上照出近似正弦的光强变化于是两路间隔 90 度电角度的信号就出来了。那为什么不干脆做数字输出原因在于分辨率。正余弦编码器不是为了替代数字编码器而是为了在相对紧凑的码盘结构下通过信号的模拟插值把分辨率堆上去。比如一个 1000 线周期的编码器如果拿方波读数一个周期内最多只有 4 倍频也就是 4000 个计数。但如果是正余弦输出就能在一个周期内通过 AD 采样和反正切解算再细分几百倍甚至上千倍相当于在不大幅增加码盘密度的前提下把等效脉冲数拉高了几个数量级。不过这个“插值”不是白来的它建立在两路信号足够干净的基础上。信号偏了、圆扁了插值就插出非线性误差表现在应用上就是某一段角度走得均匀某一段角度明显偏快或偏慢。我见过有人把正余弦编码器直接当普通模拟量接到单片机的两组 ADC然后把原始值送进 atan2 函数结果速度波动非常大调研一下发现根本没有做去直流和归一化这类问题在圈子里其实挺常见。1.2 正余弦信号的本质与 Lissajous 图形两路正余弦信号一路记为 Sin一路记为 Cos。理想状态下Sin A * sin(θ)Cos A * cos(θ)这里 θ 是编码器当前的电角度范围 0 到 360 度对应一个信号周期也就是码盘上的一个栅距。如果把 Cos 作为横轴、Sin 作为纵轴画一张图理想情况是一个半径为 A 的正圆。这张图就叫李萨如Lissajous图形做正余弦编码器调试的人几乎天天跟它打交道。实际信号不会那么完美主要偏差有几类一是直流偏置不为零圆的位置不在原点偏左或偏上原因跟光电探测器的暗电流、后端运放的输入失调、电路里的参考电压不精确都有关系二是两路幅值不一致圆变成椭圆或者叫“压扁了”这跟两路光电管本身的差异、增益电阻的误差相关三是两路信号不是严格 90 度正交圆会倾斜这通常跟光栅的安装、信号通道的延迟不匹配有关四是信号本身有谐波圆被高次谐波搞得不圆虽然是模拟前端的问题但也会影响插值误差。既然已经知道了这些误差会让圆不圆、让角度解算不准确剩下的就是怎么处理。很多资深工程师的做法很简单粗暴硬件上做好采样电路软件上先采集一圈数据把偏置、幅值、相位误差都标定出来然后对实时采样的原始值做校正最后才进角度解算。这套流程就是我们说的“信号归一化处理”是整个正余弦编码器应用里绕不开的核心环节。2. 硬件电路设计模拟前端的每一个坑2.1 差分信号处理才是正确的起点市面上的正余弦编码器输出形式大体分两类单端输出和差分输出。单端的通常在编码器内部把 Sin、Cos、参考地引出来只有三根信号线差分的则是 Sin / Sin-、Cos / Cos- 四路利用两边相减来抑制共模噪声。做伺服和运动控制我一定推荐优先选差分输出原因很简单电机柜里的干扰源太多了变频器、接触器、开关电源哪个起来都是一阵电磁骚扰单端信号离编码器稍远就容易被共模干扰打穿到了 ADC 里就变成随机的角度跳变。差分信号的处理方式也很标准每路差分对进一个仪表放大器或者高速差分运放把差分转成单端同时完成偏置调整和增益调整。如果你用的是带 PGA可编程增益的高精度 ADC也可以直接让差分对进 ADC省掉一级运放但主控侧通常还需要一个低通滤波器和过压保护电路不建议零外围直接连接。我常用的前端结构大概是编码器连接器进来先走一个共模电感或磁珠滤掉高频共模然后进差分转单端电路运放输出端再接一个 RC 低通截止频率放在 1/10 采样率附近既抑制带外噪声又不影响信号本身的带宽。编码器信号频率跟电机转速有关比如一个 2048 线编码器转速 3000 转/分时输出信号频率大概是 102.4kHz如果你采样率放在 1MHzRC 滤波点放到 100kHz 附近会比较稳太高了抗不住噪声太低了又会让信号衰减。2.2 偏置与增益怎么调到 ADC 口ADC 输入范围一般是 0~3.3V 或 0~5V而正余弦信号是交流摆动的不可能全都是正值。所以硬件上必须做两件事一是把信号电压抬高到 ADC 量程中点二是把信号摆幅放大到合适的范围既不要太小浪费分辨率也不要太大顶到电源轨。假设编码器输出单端信号是 0.5V~2.5V中心值 1.5V峰峰值 2V你直接送进 0~3.3V 的 ADC 也不是不能用但中心值离 1.65V 的中点差了一段会减少一些有效范围。更好的做法是接入调理电路通过加法器和放大器把中心抬到 1.65V同时把电压范围映射到 0.2V~3.1V 左右。留出 0.2V 的裕量很重要因为信号在温漂、电源波动下会浮动一点余量都不留的话高增益状态下很容易削顶。差分转单端的经典电路是仪表放大器 INA128 或者全差分运放 THS45xx不过现实中很多驱动板用的是通用运放配合电阻网络搭成差分放大。需要注意运放的选型普通 LM358 这档带宽太窄用在几百 kHz 的信号上增益已经掉得厉害至少要选 GBW增益带宽积在 10MHz 以上的运放比如 OPA2188 零漂移运放偏置电压低、温漂小还有 MCP6V11、AD8628 这类也可以。零漂移运放在正余弦编码器信号处理上真的很重要因为编码器信号频率不高但对直流偏置的稳定性有要求普通运放的失调温漂会让你标定好的偏置在一段时间后偏掉重新引入位置误差。2.3 真正的细节基准电压、滤波与布线有一个细节特别容易被忽略就是 ADC 的参考电压或者说整个电路的偏置基准。如果你的偏置电压是由一个普通的 LDO 提供的而这个 LDO 的精度只有 2%那么在 3.3V 系统里就有 66mV 的误差折算到 16 位 ADC 上大概是 1300 多个 LSB相当于白白丢了两三位的有效精度。正余弦编码器本来就是靠插值吃饭的信号链路里任何一处直流电平发生小偏移反映到角度上都是肉眼可见的位置误差。所以偏置电压源要选择高精度、低噪声的基准源比如 REF3330 这类 3.0V 的电压基准或者至少用精度 0.5% 以内的 LDO。滤波这一块除了前面提的 RC 低通还有一个很容易踩的坑ADC 采样端的去耦电容放太大了。有些人喜欢在 ADC 引脚放一个 100nF 甚至更大的电容想让信号更干净结果电容和信号源内阻形成低通回路高频分量被滤掉信号波形出现畸变角度解算在高转速时误差直接变大。实际上只要保证 ADC 采样保持电路能正常建立去耦电容 nF 级就够10nF 以上就要算一下信号带宽能不能接受。布线方面同样要强调。两路差分信号的正负线要等长、紧耦合走线尽量靠在同一层中间不要穿过其他数字信号编码器信号线要跟电机功率线、电源线保持足够距离如果必须交叉尽量垂直交叉屏蔽线的屏蔽层在接收端单点接地不要两边都接否则会形成地环路。地环路的问题我在现场遇到过很多次表现为编码器信号上叠加了一个 50Hz 或者高次谐波的共模噪声用示波器看 Lissajous 图圆环变成有毛刺的椭圆环位置环低速运行时会有周期性的抖动。硬件这一关过了ADC 采出来的数据才“值得信任”。下一步的工作就是软件层的数据修正和归一化这也是踩坑最多、最需要耐心的环节。3. 软件归一化从原始数据到标准圆3.1 为什么必须归一化经常有朋友问我两路信号都进 ADC 了直接用 atan2(Sin, Cos) 算角度不行吗答案是可以算但精度看天吃饭。如果两路信号的直流偏置不为零、增益不一致你画出来的 Lissajous 图不是一个以原点为中心的正圆而是一个偏心的椭圆。这时候直接 atan2得到的角度跟真实角度之间就是非线性关系在椭圆长轴和短轴方向偏差最大在 45 度附近又会好一些。这个误差不是固定常数是随角度周期性变化的位置环用 PID 调节时很难完全消除速度环更是直接表现为周期性的转速波动。归一化的目标很简单把两路信号变换到“以零点为中心、幅值一致、相位正交”的标准状态也就是让 Sin 和 Cos 的图形变成一个标准的单位圆。做了归一化之后atan2 解出来的角度才是线性的细分插值才有意义。提示这里的“归一化”指把 Sin/Cos 两路模拟量变换成以 0 为中心、峰值均为 1 的信号目的是消除通道增益差和偏置差。没有这一步后面所有角度误差都会被放大细分倍数越高误差越明显。3.2 去直流偏置的思路与实现去直流是归一化的第一步也是最基础的一步。具体做法是先获取信号的直流偏置值。如果静态测量编码器不动拿万用表靠在运放输出端量一下直流电平就能得到偏置如果动态测量可以让电机匀速旋转一整圈或多圈采样大量数据然后计算每个通道的平均值或者用最大值和最小值取平均。实际软件里我的做法是让电机以恒定低速匀速转若干圈采样 Sin 和 Cos 两路数据各 N 个点N 建议覆盖至少一个完整电气周期最好覆盖 5 个以上周期对每个通道分别求最大值 max 和最小值 min直流偏置 offset (max min) / 2信号幅值 peak (max - min) / 2归一化后的值 (原始值 - offset) / peak。这里为什么不直接用平均值当偏置因为如果采样点没有均匀覆盖整个电气周期平均值会偏离真实偏置尤其采样点数过少时会更明显。用最大最小值的平均值来估计偏置前提是信号没有削顶失真而且采集样本里确实包含了完整的波峰和波谷。为了保证这一点采集之前务必确认信号没有“削波”否则峰值被削平算出来的偏置和幅值都不准后边的角度就更不用提了。有些场合还会在运行过程中连续做偏置校正也就是在线归一化。因为温度、电源波动会导致偏置漂移静止时标定好的值可能过一会儿就不准了。在线处理的方法是实时统计信号的最大值和最小值或者用一阶低通估计直流分量。这里要小心最大最小值的窗口长度窗口太短容易跟低速时的信号周期不匹配统计不到极值窗口太长响应过慢漂移已经发生但补偿跟不上。实测下来用指数滑动平均估计直流分量比单纯滑动窗口更稳内存开销也更小。3.3 幅度归一化和正交性修正去完直流之后Sin 和 Cos 通道的峰值幅值可能还是不一样比如 Sin 的 peak 是 1.2VCos 的 peak 是 1.1V。这时候需要分别对两路做等比例缩放让两路幅值都变成 1。归一化后的信号 (原始值 - offset) / peak每个通道用自己的 peak 除一遍就直接把幅度归一化了。如果仅仅用最大最小值法做归一化Sin 和 Cos 之间还存在一个相位误差没有处理。理想情况下两路信号相差 90 度但实际中由于光栅安装或者前级电路延时相位差可能是 89 度或 92 度。这个误差在高精度细分时影响非常明显。一种常见的处理方式是最小二乘椭圆拟合法采集一圈数据把所有数据拟合成一个椭圆方程从椭圆参数里同时解出偏置、幅值比、相位差。这个方法的数学基础是任何两路存在偏置、增益不一致、非正交的 Sin/Cos 信号在 xy 坐标图上都构成一个椭圆椭圆的长短轴和倾角就包含着这些误差信息。我有一段在实践中经常用的最小二乘椭圆拟合思路伪代码层面的import numpy as np # 假设采集到一整圈数据 sin_data np.array([...]) # 原始sin通道 cos_data np.array([...]) # 原始cos通道 # 构造Ax b 的形式求解椭圆参数 # 椭圆一般方程: A*x^2 B*x*y C*y^2 D*x E*y F 0 # 这里变量多系数计算繁琐实际工程中可以直接调用opencv的fitEllipse # 在嵌入式里如果不想引库可以退化为分别求offset和peak的近似方案如果控制器比较小跑不动椭圆拟合也有实用的近似方案只做偏置和幅度归一化把相位误差留到角度解算后进行查表补偿。查表法先在整圈内标定出误差曲线运行时查表修正角度效果也好。关键看你手头的 MCU 算力和存储空间够不够。4. 角度解算流程与实操要点4.1 反正切计算的两种做法信号完成归一化后角度计算的核心就是 atan2。大多数编译器都自带 atan2f但它的计算时间在不同架构上差异很大。跑在带 FPU 的 M4/M7、Cortex-A 上没什么压力如果是一个小资源 MCU比如 M0 或者普通 8 位机想跑浮点 atan2 就有点吃力尤其是让电机的电流环、速度环都跑在这个 MCU 上算力比较紧张。遇到这种情况常用的做法是 CORDIC 算法利用移位和加法迭代逼近三角函数和反正切函数。CORDIC 的好处是只需要整数或定点运算不需要硬件除法器和浮点单元迭代次数可以从 8 次到 20 次之间选精度和速度自己权衡。还有一种是查表法加线性插值把 0 到 360 度细分成 256 或 1024 个区间先查象限再查区间再做一次线性插值。分段越多精度越高但表也越大。实测下来用 512 段查表加线性插值角度误差控制在 0.1 度以内对于大多数运动控制场景足够了。C 语言的常规实现是float normalize_and_get_angle(float sin_raw, float cos_raw) { float sin_norm (sin_raw - sin_offset) * sin_scale; float cos_norm (cos_raw - cos_offset) * cos_scale; // 限制幅值防止除零 if (sin_norm 1.0f) sin_norm 1.0f; if (sin_norm -1.0f) sin_norm -1.0f; if (cos_norm 1.0f) cos_norm 1.0f; if (cos_norm -1.0f) cos_norm -1.0f; return atan2f(sin_norm, cos_norm); }注意这里的 sin_scale 和 cos_scale 是归一化系数的倒数也就是 1.0f / peak乘一次就省掉了编译器的除法操作。4.2 标定流程怎么走一遍说到标定很多人以为是写代码时一次性算好系数烧录完就不用管了。实际上特别是精度要求高的设备标定应该作为出厂流程的一部分。具体的标定步骤我建议这样电机不使能手动或外力让电机匀速转几圈用上位机记录两路 ADC 原始值对记录的数据分别求最大值、最小值估算偏置和幅值检查 Lissajous 图看看是圆还是椭圆、是否偏心、是否带毛刺如果偏心明显确认硬件偏置电路有没有问题如果椭圆明显做幅值归一化如果图形倾斜考虑做相位补偿把计算好的 offset 和 scale 系数保存在片内 Flash 或 EEPROM 中设备每次上电自动加载在整圈内再采一次数据用校正后的信号算角度跟外部基准比如高精度光栅尺或圆光栅比较评估残差。残差呈正弦形状时大概率是偏置或幅值补偿不准残差呈二倍频时往往是相位误差或谐波误差。标定过程要特别注意的是电机转速不能太高。转速太高采样点数如果不足以覆盖一个完整电气周期最大最小值的估算就会失真。一般让编码器信号频率在 1kHz 以下比较稳妥也就是以 2048 线编码器为例转速控制在 30 转/分以内比较合适。做完标定之后Lissajous 图会从偏心椭圆变成近似标准圆这时你再看反正切计算出的角度曲线线性度会明显变好。4.3 实时性与存储开销控制还有一个容易被忽略的设计点归一化和角度解算的实时性。很多项目把角度解算放在中断里但中断的时间预算可能只有几十微秒。如果每个采样点都去做浮点 atan2有可能导致中断执行时间超长影响其它任务。优化思路一般是把偏置和幅值运算合并成一次乘加也就是 y (x - offset) * scale两路信号只做两次乘加非常快atan2 用查表加线性插值或 CORDIC 替代避免浮点库调用角度细分前的象限判断用符号位直接判断比浮点比较快如果是 DSP 或者有协处理器的平台可以把信号滤波、归一化、角度解算分到不同阶段利用流水线提升吞吐。存储方面偏移量和缩放系数一共 4 个浮点数就够查表法的角度表看分段数256 段用 8 位索引1024 段用 16 位索引一般是几十到几百字节的事相比 FOC 和位置环的工程体量可忽略。我之前在一个项目里用国产 M0 内核的单片机做 16 位编码器信号采样系统主频 72MHz中断里完成两路滤波、归一化和查表角度解算整个时长控制在 15 微秒左右完全不影响 16kHz 的电流环运行。核心就是把复杂计算搬到标定阶段在线阶段只做乘加和查表。5. 常见问题与排查技巧实录5.1 常见故障现象速查表这些年处理过不少正余弦编码器相关的现场问题这里整理一个速查表方便大家排查时对照故障现象可能原因排查方向角度在某个点跳变剧烈信号削顶或偏置靠近 ADC 边界检查偏置电压和增益观察 Lissajous 图是否触边低速时位置有周期性波动偏置或幅值未归一化椭圆偏心做整圈标定重算 offset 和 scale高速时角度误差变大低通滤波截止频率太低信号建立不充分检查 RC 滤波参数和采样率匹配Lissajous 图有毛刺或抖动共模干扰、地环路、电源纹波检查屏蔽接地方式加强去耦确认功率地与信号地分离Lissajous 图倾斜两路相位差不是 90 度做正交性修正或查表补偿上电后角度乱跳标定系数未加载或掉电丢失检查 Flash 存储确认加载流程这个表看着简单实际排查时的难点在于现象不等于原因要结合波形判断。比如角度跳变可能是偏置漂移、削顶、噪声也可能是角度解算的除零问题。我不会急着改代码先用示波器同时观察两路 ADC 原始波形和归一化后的波形以及电机的速度或位置环输出往往一次就能定位到大方向。5.2 温漂、噪声与抗干扰的实战经验温漂是正余弦编码器信号处理中最容易被低估的问题之一。编码器本身用光电或磁电原理温度变化会导致光源亮度、光电管灵敏度、磁感应强度都变化进而影响信号幅值。线路板上的运放和基准源也会随着温度产生偏置漂移。如果你只在常温下标定一次系数设备跑到车间里温度升高角度误差会慢慢变大最终表现为机床热机后定位精度下降。针对温漂我一般做三层防护第一层硬件上用零漂移运放和高精度低温漂基准源这是根本第二层软件里如果条件允许加入慢速自适应偏置估计用信号的低频均值或滑动最小值最大值去追踪偏置的缓慢漂移第三层在关键设备上定期重新标定比如维护周期每三个月一次而不是等到精度明显下降才处理。噪声问题也是老生常谈。很多工程师会把所有滤波都堆到软件里用滑动平均、低通滤波去磨平噪声但这种方法对位置环不是很有效。因为你滤波的同时也在延迟信号给角度带来了相位滞后高速工况下轻易就造成振荡。我更推荐的做法是硬件的抗混叠滤波做扎实软件只做轻度的归一化后滤波把主要噪声挡在 ADC 之外这样才能同时保证实时性和信噪比。另外有一点很实用检查布线时不要只量通断要用示波器量差分信号的共模噪声。编码器线比较长时我习惯把示波器探头的地夹子夹在接收端的地上测一下 Sin 对地的波形和 (Sin)-(Sin-) 的差分波形对比一下就能看出多少噪声是共模、多少是差模。差模噪声往往来自电源或串扰共模噪声大部分来自地电位差或辐射耦合。这两种噪声的处理方式完全不同差模靠滤波和布局共模靠屏蔽和接地。5.3 用 Lissajous 图指导调试的心法最后分享一个对我帮助特别大的习惯调试正余弦编码器时第一件事不急着看角度波形而是看 Lissajous 图。在示波器上用 XY 模式把 Cos 接到 X 通道Sin 接到 Y 通道观察整个圆的质量。如果是标准圆角度解算基本不会出大问题如果是偏心椭圆说明偏置或增益有问题如果圆环粗、有毛刺说明噪声或者采样时序有问题如果圆环扭曲不闭合说明有谐波失真或者信号周期不完整。这个图比任何分析都直观几乎能一眼定位大部分问题。而且这个判断方法不仅适用于调试阶段在新设备上电、更换编码器、更换线缆之后都可以快速用来验证信号质量。软件里也可以做个简化版的“数字李萨如”把采样到的最新的几百个点投到二维数组里借助屏幕或上位机显示出来。我在自己的调试上位机里做了这个功能设备量产前都会让产测人员跑一圈信号质量检测把图形偏离标准圆的量化指标作为合格判据之一。正余弦编码器信号处理的链路不长但从硬件到软件、从静态标定到动态补偿每一环都得较真。最近几次踩坑之后我的体会是先花半小时把 Lissajous 图看清楚比盲目调 PID 参数有效得多。如果是新设计尽量从一开始就用差分信号、精密基准源、低噪声 ADC把信号质量的上限做高如果是已经在跑的老设备优先检查线缆、接地和接插件很多莫名的角度跳变其实就是接触电阻和地环路在捣鬼。归一化和角度解算是软件里最值得优化的部分把标定系数做精确把在线运算做轻系统跑起来才能真正稳定。希望这篇记录对你有用也欢迎在实际调试中有啥新坑回头一起交流。