ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

PLC编码器测速:中心差分法与自适应滤波算法SCL实现

PLC编码器测速:中心差分法与自适应滤波算法SCL实现 1. 项目概述从脉冲到速度的工业级精确求解在工业自动化现场编码器是获取旋转设备转速、位置信息的“眼睛”。无论是电机的转速监控、传送带的线速度测量还是卷绕机的张力控制其核心都离不开对编码器脉冲信号的精确解读。然而从原始的脉冲序列到稳定、可靠的速度值中间隔着信号噪声、采样误差和计算延迟等多重障碍。一个鲁棒的测速算法是确保整个控制系统稳定、精准的基石。“PLC编码器测速中心差分法测速自适应滤波算法SCL源代码”这个项目正是为了解决这一核心痛点而生。它不是一个简单的脉冲计数程序而是一套融合了先进数值计算方法和智能滤波策略的完整解决方案。其目标是在资源受限的可编程逻辑控制器PLC环境中实现高精度、低延迟且抗干扰能力强的实时速度测量。这套方案尤其适合对速度波动敏感、或现场电磁环境复杂的应用场景如精密涂布、高速分切、伺服同步等。简单来说这个项目提供了两把“利器”一是中心差分法用于从离散的位置采样中高精度地计算出瞬时速度有效减少计算滞后二是自适应滤波算法它能像一位经验丰富的老师傅根据速度信号本身的波动情况动态调整滤波的“力度”在抑制噪声和保持响应速度之间找到最佳平衡点。最终我们将这些复杂的算法用西门子PLC的结构化控制语言SCL实现封装成可即插即用的函数块Function Block让工程师在博途TIA Portal环境中能轻松调用快速构建可靠的测速功能。2. 核心需求与挑战解析为什么简单的计数不够用在深入代码之前我们必须先理解在PLC中实现高质量测速所面临的几个固有挑战。只有明确了问题才能理解后续方案中每一个技术选择的深意。2.1 测速的基本原理与瓶颈最基础的测速方法是M法测频法和T法测周法。M法在固定时间内计数脉冲适合高速T法测量两个脉冲之间的时间适合低速。但在中速或速度变化剧烈的场合两者都有局限。更常见的是M/T法即同时计数脉冲和测量时间但其输出是平均速度存在固有的滞后性。对于高性能控制我们需要的是瞬时速度。这就引出了基于位置采样的微分方法在固定的、很短的时间间隔ΔT内读取编码器位置值的变化量ΔP那么速度v ΔP / ΔT。这听起来简单但魔鬼藏在细节里量化误差ΔP是整数脉冲数ΔT是定时器中断周期。当速度很低时ΔP可能连续多个周期为0导致计算出的速度也是0产生“速度死区”。噪声放大微分运算会放大信号中的高频噪声。编码器信号可能因电磁干扰、机械振动产生毛刺直接微分会导致速度值出现尖峰。计算延迟与相位滞后使用简单的前向差分用当前周期和上一周期的位置差计算速度其结果实际上代表的是上一个采样周期中间时刻的速度存在半个采样周期的固有滞后。这对于闭环控制如速度环的稳定性是不利的。动态适应性设备运行速度范围可能很宽例如从1RPM到3000RPM。固定的滤波参数如固定时间常数的低通滤波器难以兼顾低速时滤波不足噪声大高速时滤波过度响应慢。2.2 伺服电机低速运行时的“幽灵信号”问题相关热词中提到了一个非常具体且经典的行业难题“伺服电机编码器在低速运行时光电开关可能停在码盘刻度线上因灵敏度差异或轻微机械抖动产生单相信号跳变”。这描述的是增量式编码器在极低速或停止时由于光栅盘恰好停在明暗边缘微小的机械振动或电气噪声可能导致A相或B相信号发生一次孤立的跳变。对于依赖四倍频计数同时检测A、B相上升沿和下降沿的系统一次错误的跳变会被误认为是一个有效的计数脉冲。在高速时这种偶然错误微不足道但在低速或启动阶段这会导致计算出的速度出现一个巨大的、不真实的尖峰可能触发错误的报警或导致控制系统震荡。这个问题是硬件层面的物理现象无法完全根除但必须通过软件算法进行有效识别和滤除。这正是自适应滤波算法需要重点应对的场景之一。3. 方案核心中心差分法与自适应滤波算法详解面对上述挑战本项目采用了“中心差分法计算 自适应滤波后处理”的组合拳。下面我们来拆解这两项核心技术的原理与优势。3.1 中心差分法更高精度、更低滞后的速度计算中心差分法是一种数值微分方法。在测速的语境下它的思想是用未来和过去的位置信息共同估算当前时刻的导数速度。传统前向差分V_now (P_now - P_last) / ΔT。这个V_now实际上对应(t_last t_now)/2时刻的速度。中心差分法V_now (P_next - P_last) / (2 * ΔT)。这里P_last是上一采样时刻位置P_next是下一采样时刻位置。计算出的V_now在理论上更接近当前采样时刻t_now的真实瞬时速度。优势分析精度更高从数值分析角度看中心差分法的截断误差是O(ΔT²)而前向差分是O(ΔT)。这意味着当采样周期ΔT固定时中心差分法的计算精度更高。相位滞后小这是最关键的优势。中心差分法估算的是当前时刻的速度其相位滞后远小于前向差分理论上可减少一半的滞后对提升控制系统的动态响应和稳定性有显著好处。对噪声有一定平滑作用因为它利用了三个点的信息过去、现在、未来相当于一个简单的平滑窗。在PLC中的实现考量实现中心差分法需要一个“未来”的位置值P_next。这并非预测而是在程序执行流中通过巧妙的时序安排实现。通常我们在一个高速、固定周期的中断组织块如OB35循环中断中执行以下操作读取当前编码器实际值存入变量P_current。将上一次中断读取的值存在P_last中作为“过去”值。将本次读取的P_current赋值给一个P_next_temp变量但这个P_next_temp是供下一次中断计算时作为“未来”值使用的。本次计算使用的“未来”值实际上是上一次中断中保存的P_next_temp即上一次的当前值。 这样在每次中断中我们都有了一组完整的P_last上次值、P_current本次值用于更新状态、P_next上上次保存的“未来”值从而可以计算V_now (P_next - P_last) / (2*ΔT)。注意这种实现方式会引入一个中断周期的纯延迟但计算得到的速度值的相位滞后仍然小于前向差分。这是工程上为了因果可实现性不能真的用未来的测量值所做的妥协效果依然优于传统方法。3.2 自适应滤波算法智能降噪动态平衡计算出原始速度后我们需要对其进行滤波。固定参数的滤波器如一阶低通的缺点前文已述。自适应滤波的核心思想是滤波器的参数如截止频率、增益能够根据输入信号的特征自动调整。在本项目中自适应策略很可能基于信号的变化率加速度或方差。以下是一种典型且实用的实现思路状态判断实时计算原始速度的差分即加速度或短期内的波动幅度。参数调整逻辑稳态或低速区当速度变化平缓加速度绝对值小或速度值本身很低时系统可能处于稳定运行或启停阶段。此时应加强滤波增大滤波时间常数以最大限度地抑制可能存在的噪声包括前述的“幽灵信号”和量化误差带来的跳动。动态或高速区当检测到速度正在快速变化加速度大或速度值很高时系统处于加速、减速或高速运行状态。此时应减弱滤波减小滤波时间常数以保证控制系统能快速响应速度指令的变化避免因滤波过度引起的响应延迟。滤波算法选择自适应调整的通常是一阶低通滤波器LPF的时间常数τ。一阶LPF算法简单计算量小非常适合PLC环境。其公式为Y(n) α * X(n) (1 - α) * Y(n-1)其中X(n)是当前输入原始速度Y(n)是当前输出滤波后速度Y(n-1)是上一次输出α ΔT / (τ ΔT)是滤波系数。α越大滤波效果越弱响应越快α越小滤波效果越强响应越慢。 自适应算法就是根据当前运行状态动态计算出一个合适的α值。针对“幽灵信号”的特殊处理在自适应逻辑中可以加入一个特殊的“极低速/零速锁定区”。当绝对速度值低于一个非常低的阈值如对应每秒几个脉冲时强制将滤波系数设为极低即强滤波甚至可以结合逻辑判断如果检测到孤立的、不符合运动方向的脉冲跳变则直接将其忽略不参与速度计算。这需要算法同时处理编码器的方向信息。4. SCL源代码实现与关键代码解析下面我们将把上述理论转化为西门子SCL语言的具体实现。我们将创建一个名为FB_EncoderSpeedAdv的函数块。4.1 数据结构与接口定义静态变量首先在函数块的静态Static变量区定义算法所需的所有内部状态和中间变量。FUNCTION_BLOCK FB_EncoderSpeedAdv VAR // 输入参数 i_EncoderRawValue : DINT; // 输入编码器原始计数值有符号支持正反转 i_SampleTimeMs : REAL : 10.0; // 输入采样周期单位毫秒通常与中断OB周期一致 i_MinSpeedThreshold : REAL : 0.5; // 输入最小速度阈值低于此值进入强滤波模式单位用户自定义 i_AdaptationGain : REAL : 0.1; // 输入自适应调节增益影响参数变化速度 i_FilterAlpha_Min : REAL : 0.02; // 输入滤波系数α最小值最强滤波 i_FilterAlpha_Max : REAL : 0.8; // 输入滤波系数α最大值最弱滤波 // 输出参数 o_FilteredSpeed : REAL; // 输出滤波后的速度值 o_RawSpeed : REAL; // 输出中心差分法计算出的原始速度值可选用于诊断 o_CurrentAlpha : REAL; // 输出当前自适应滤波系数用于监控 // 静态变量内部状态 pv_PositionLast : DINT : 0; pv_PositionCurrent : DINT : 0; pv_PositionNext : DINT : 0; // 用于中心差分的“未来”值缓存 pv_FirstCycle : BOOL : TRUE; // 首次循环标志 pv_SpeedRaw : REAL : 0.0; // 原始速度计算值 pv_SpeedFiltered : REAL : 0.0; // 滤波后速度值 pv_Acceleration : REAL : 0.0; // 估算的加速度原始速度的差分 pv_SpeedRawLast : REAL : 0.0; // 上一周期的原始速度用于计算加速度 pv_AdaptiveAlpha : REAL : 0.5; // 当前的自适应α系数 END_VAR4.2 主算法执行逻辑在函数块的主体中我们实现一个CalcSpeed方法它应在每个采样周期被调用。METHOD CalcSpeed : VOID VAR_TEMP deltaPosition : DINT; deltaTimeSec : REAL; speedMagnitude : REAL; accelerationTemp : REAL; alphaTarget : REAL; END_VAR // 步骤1时间单位转换毫秒到秒 deltaTimeSec : i_SampleTimeMs / 1000.0; // 步骤2更新位置值队列实现中心差分法的“未来值”获取 pv_PositionCurrent : i_EncoderRawValue; IF pv_FirstCycle THEN // 首次执行初始化所有位置值为当前值避免初始跳变 pv_PositionLast : pv_PositionCurrent; pv_PositionNext : pv_PositionCurrent; pv_FirstCycle : FALSE; RETURN; // 首次循环不计算速度 END_IF; // 步骤3应用中心差分法计算原始瞬时速度 // 注意此时 pv_PositionNext 保存的是“上一个周期”的当前值作为本周期的“未来”值 // pv_PositionLast 是上上个周期的值作为“过去”值 deltaPosition : pv_PositionNext - pv_PositionLast; pv_SpeedRaw : REAL(deltaPosition) / (2.0 * deltaTimeSec); // 中心差分公式 o_RawSpeed : pv_SpeedRaw; // 输出原始速度 // 步骤4为下一个周期更新位置队列 pv_PositionLast : pv_PositionCurrent; // 当前值变为下一个周期的“过去”值 // 注意pv_PositionNext 的更新需要谨慎。我们选择用当前值更新它 // 这样在下个周期它就成为“未来”值。但为了严格的时间对齐 // 更常见的做法是在方法结束时将 pv_PositionCurrent 赋值给一个临时变量 // 在下一个周期开始时再将这个临时变量赋给 pv_PositionNext。 // 这里为清晰起见我们先直接赋值实际可能需要双缓冲技术避免冲突。 pv_PositionNext : pv_PositionCurrent; // 当前值作为下一个周期的“未来”值缓存 // 步骤5计算加速度用于自适应逻辑 accelerationTemp : (pv_SpeedRaw - pv_SpeedRawLast) / deltaTimeSec; pv_Acceleration : accelerationTemp; pv_SpeedRawLast : pv_SpeedRaw; // 更新供下个周期使用 // 步骤6自适应滤波系数计算 speedMagnitude : ABS(pv_SpeedRaw); // 核心自适应逻辑基于速度大小和加速度动态调整目标α IF speedMagnitude i_MinSpeedThreshold THEN // 场景极低速或停止状态重点抑制噪声和“幽灵信号” alphaTarget : i_FilterAlpha_Min; // 采用最小α最强滤波 ELSE // 场景正常速度运行区 // 基础α基于速度可选速度越大α可越大响应越快 // 这里简化处理使用一个中间值作为基础再根据加速度调整 alphaTarget : (i_FilterAlpha_Min i_FilterAlpha_Max) / 2.0; // 根据加速度幅度调整变化越快需要响应越快α应增大 // 使用加速度的绝对值来调节并通过增益限制调节幅度 alphaTarget : alphaTarget (i_AdaptationGain * ABS(pv_Acceleration)); // 将alphaTarget钳制在允许的范围内 alphaTarget : LIMIT(MN : i_FilterAlpha_Min, IN : alphaTarget, MX : i_FilterAlpha_Max); END_IF; // 步骤7平滑过渡到目标滤波系数避免系数突变引起输出抖动 pv_AdaptiveAlpha : pv_AdaptiveAlpha 0.2 * (alphaTarget - pv_AdaptiveAlpha); // 一阶惯性环节平滑 // 步骤8应用一阶低通滤波 pv_SpeedFiltered : pv_AdaptiveAlpha * pv_SpeedRaw (1.0 - pv_AdaptiveAlpha) * pv_SpeedFiltered; // 步骤9更新输出 o_FilteredSpeed : pv_SpeedFiltered; o_CurrentAlpha : pv_AdaptiveAlpha; END_METHOD4.3 关键代码段解析与实操要点中心差分的时序实现代码中的pv_PositionNext变量是关键。它在本周期被用作“未来”值参与计算计算完成后立即用pv_PositionCurrent更新。这意味着这个“未来”值实际上是上一个采样时刻的位置。这种一个周期的延迟是因果系统必须接受的但其计算出的速度的相位特性仍优于前向差分。务必确保CalcSpeed方法在严格恒定的周期内被调用否则deltaTimeSec不准确会引入计算误差。自适应逻辑的工程化示例中的自适应逻辑相对简单。在实际应用中你可能需要更复杂的策略死区处理在i_MinSpeedThreshold附近设置一个死区防止系数在阈值附近频繁切换。加速度滤波对计算出的原始加速度pv_Acceleration也进行低通滤波防止噪声干扰自适应逻辑。方向敏感性对于正反转应用速度pv_SpeedRaw是带符号的。自适应逻辑应基于速度的绝对值speedMagnitude。滤波系数平滑直接让pv_AdaptiveAlpha跳变到alphaTarget会导致滤波后的速度曲线出现拐点。通过pv_AdaptiveAlpha : pv_AdaptiveAlpha 0.2 * (alphaTarget - pv_AdaptiveAlpha)这行代码我们让滤波系数的变化本身也是平滑的。其中的0.2是一个平滑因子可以根据需要调整。单位与标定代码中速度的单位取决于i_EncoderRawValue的单位和i_SampleTimeMs。如果i_EncoderRawValue是脉冲数那么速度单位就是脉冲数/秒。你需要根据编码器线数每转脉冲数和机械传动比将其转换为工程单位如RPM或m/s。这个转换建议放在函数块外部进行保持函数块算法的通用性。5. 在博途TIA Portal中的集成与调试指南5.1 硬件组态与编码器输入配置选择高速计数器在PLC设备组态中例如S7-1200/1500为连接编码器的DI点配置“高速计数器HSC”功能。根据编码器类型单相、AB相、AB相四倍频选择工作模式。设置计数范围与复位根据机械行程设置计数器的上下限。对于旋转编码器通常设置为“模数”模式到达上限后归零。如果需要绝对位置则使用“连续”模式并注意处理DINT变量的溢出。映射过程映像确保HSC的当前计数值被映射到PLC的输入地址如ID1000并设置合适的更新周期。在OB1中直接读取这个地址可能会错过脉冲最佳实践是在一个循环中断OB如OB35周期设置为采样时间i_SampleTimeMs中读取。5.2 软件编程与调用创建函数块与背景数据块将上述SCL代码创建为函数块FB_EncoderSpeedAdv。在循环中断OB中为该FB创建一个背景数据块如DB_SpeedCalc_Motor1。初始化与周期调用// 在OB35中 #Encoder1.i_EncoderRawValue : “HSC”.CurrentValue; // 从HSC模块读取值 #Encoder1.i_SampleTimeMs : 10.0; // 与OB35周期一致 #Encoder1.i_MinSpeedThreshold : 5.0; // 示例5脉冲/秒以下为低速区 #Encoder1.i_FilterAlpha_Min : 0.05; #Encoder1.i_FilterAlpha_Max : 0.7; #Encoder1.i_AdaptationGain : 0.05; #Encoder1.CalcSpeed(); // 调用计算方法 // 获取结果 #ActualSpeed_RPM : #Encoder1.o_FilteredSpeed * (60.0 / (EncoderPulsesPerRev * GearRatio)); // 转换为RPM采样周期同步务必保证i_SampleTimeMs参数与调用该FB的中断OB的实际周期严格一致。可以在OB的启动事件中读取OB35_Period对于OB35并传入实现自动同步。5.3 调试与优化技巧监视与趋势图使用TIA Portal的轨迹功能同时监视o_RawSpeed和o_FilteredSpeed。观察在启动、停止、匀速、变速阶段滤波效果是否达到预期。o_CurrentAlpha的变化曲线是理解自适应逻辑工作的关键。参数整定步骤第一步确定采样时间根据奈奎斯特采样定理采样频率至少是信号最高频率的2倍。对于速度环通常速度环带宽在10-100Hz。采样时间一般取1-10ms。先从5ms或10ms开始。第二步整定静态滤波参数先将i_AdaptationGain设为0i_FilterAlpha_Min和i_FilterAlpha_Max设为同一个值手动调整这个值在信号平滑度和响应速度间取得一个折中。记录下这个值作为基准。第三步设置速度阈值让电机在极低速运行观察o_RawSpeed的波动情况。设定i_MinSpeedThreshold略高于这个波动幅值确保低速时能进入强滤波模式。第四步启用自适应设置i_FilterAlpha_Min为刚才找到的强滤波值如0.05i_FilterAlpha_Max为一个响应较快的值如0.5-0.8。然后逐渐增大i_AdaptationGain从0.01开始观察在速度变化时o_CurrentAlpha能否平滑、及时地跟随并且o_FilteredSpeed曲线既平滑又无显著滞后。处理方向反转如果编码器可反转i_EncoderRawValue应为有符号双整数DINT。中心差分法计算出的pv_SpeedRaw自带符号。在计算速度绝对值speedMagnitude时使用ABS函数但在最终输出和后续控制中应保留符号。6. 常见问题排查与实战心得即使算法再精妙在实际部署中也难免遇到问题。下面是一些典型问题的排查思路和我个人积累的经验。6.1 速度值出现周期性跳变或归零现象速度曲线规律性地出现尖峰或瞬间归零。排查检查编码器计数溢出如果使用“连续”计数模式DINT变量范围约±21亿可能会溢出。确保在读取i_EncoderRawValue时处理了溢出情况。一个稳健的做法是在中断中计算本次与上次的差值这个差值在合理速度下会在一个较小范围内然后基于这个差值进行累积得到“虚拟位置”用于速度计算从而避免直接处理巨大的绝对位置值。检查采样周期稳定性确认调用CalcSpeed的OB周期是否恒定。在OB属性中查看并确保“循环中断”选项被正确设置且没有被更高优先级的OB长时间中断。检查HSC配置确认高速计数器的工作模式如四倍频与实际编码器类型匹配。AB相信号接反可能导致计数异常。6.2 低速时滤波效果不佳仍有毛刺现象电机低速运行时滤波后的速度仍有明显的高频抖动。排查与解决确认“幽灵信号”首先观察o_RawSpeed。如果原始速度在低速时就有孤立的、大幅度的尖峰那很可能是“幽灵信号”。此时应降低i_MinSpeedThreshold并减小i_FilterAlpha_Min如从0.05降到0.02加强低速滤波。增加低速特殊处理可以在自适应逻辑中当speedMagnitude极低如小于1个脉冲/秒时不仅采用最小α还可以引入一个“速度死区”或“变化率限制”直接忽略微小的、孤立的脉冲变化。检查电源与接地编码器的供电电源是否稳定信号线是否采用双绞屏蔽线并且屏蔽层在PLC侧单点接地强烈的电磁干扰如变频器附近可能耦合进信号线。6.3 高速动态响应时感觉“发闷”跟不上设定值变化现象电机加速时实测速度曲线相比指令值有明显滞后。排查与解决检查i_FilterAlpha_Max值这个值决定了滤波器的最大带宽。尝试逐步增大它例如从0.5到0.8观察滞后是否改善。但要注意过大的α会降低滤波效果。调整i_AdaptationGain增大此增益可以让算法在检测到加速度变大时更快地将α推向i_FilterAlpha_Max。审视采样时间采样时间i_SampleTimeMs是系统响应的基础。如果动态要求极高尝试将采样时间从10ms缩短到5ms甚至2ms。但要注意这会增加PLC的CPU负载。区分算法滞后与机械滞后算法的滞后通常在几十毫秒级。如果滞后达到几百毫秒或秒级可能是机械系统惯性大或驱动器响应慢这不是测速算法能解决的。6.4 从停止状态启动时第一个速度值异常大现象电机从静止启动第一个计算出的速度值是一个巨大的异常值。原因与解决这是初始化问题。在函数块的首次扫描pv_FirstCycle为TRUE时我们初始化了所有位置值为当前值并直接返回没有计算速度。但第二个周期pv_PositionLast和pv_PositionNext都是第一个周期的位置值两者相等导致deltaPosition为0速度计算为0这是正确的。异常可能出现在第三次调用时如果位置发生了正常变化。确保pv_FirstCycle逻辑正确执行。此外可以在函数块中增加一个b_Enable输入在系统准备就绪后再使能计算。个人实战心得参数不是魔法数字所有参数阈值、增益、α范围都必须有物理意义或明确的调整目标。调整时一次只改变一个参数并观察趋势图的变化。监控是关键一定要将o_RawSpeed、o_FilteredSpeed和o_CurrentAlpha这三个关键变量放到趋势图中进行在线监控。这是理解和调试算法行为的“眼睛”。理解你的噪声在设备静止时记录下o_RawSpeed的波动范围。这个范围就是你需要用滤波算法去对抗的“噪声底”。你的i_MinSpeedThreshold最好大于这个噪声幅值的2-3倍。SCL的效率SCL执行效率很高但对于超高速采样如1ms以下仍需关注函数块的执行时间。避免在速度计算函数块中进行复杂的数学运算如三角函数、指数运算或动态内存分配。备份与版本在找到一组稳定工作的参数后立即在项目注释或单独的文档中记录下来。设备维护或程序更新后这些参数是你的黄金标准。
返回列表