1. 西门子PLC模拟量滤波功能块概述
在工业自动化控制系统中,模拟量信号的采集和处理是确保系统稳定运行的关键环节。西门子S7-1200和S7-1500系列PLC作为当前主流控制器,其模拟量输入模块常面临信号波动、干扰等问题。针对这一需求,我们开发了一个通用的模拟量滤波功能块,适用于电压(0-10V)、电流(4-20mA)和热电偶(TC)三种常见信号类型。
这个功能块的核心价值在于:
- 多信号类型兼容:通过参数配置即可切换不同输入类型,无需修改底层代码
- 多重报警机制:提供低位、高位和高高报警三级保护
- 数字滤波功能:有效抑制信号噪声,提高测量稳定性
- 跨平台兼容:完美适配S7-1200和S7-1500系列PLC
提示:该功能块采用SCL语言编写,结构清晰且带有详细注释,即使初学者也能快速理解其实现原理。
2. 功能块架构设计解析
2.1 输入信号处理流程
功能块采用模块化设计思路,信号处理流程分为四个阶段:
- 信号类型识别:根据InputType参数选择对应的转换算法
- 原始值转换:将模拟量原始值转换为工程单位值
- 报警判断:比较当前值与预设报警阈值
- 数字滤波:对转换后的值进行平滑处理
pascal复制FUNCTION_BLOCK "AnalogFilter"
VAR_INPUT
AnalogInput : INT; // 模拟量原始值(0-27648)
InputType : INT; // 输入类型(0:电压,1:电流,2:热电偶)
LowAlarmLimit : REAL; // 低位报警阈值
HighAlarmLimit : REAL; // 高位报警阈值
HighHighAlarmLimit : REAL; // 高高位报警阈值
FilterDepth : INT := 5; // 滤波深度(默认5次)
END_VAR
VAR_OUTPUT
ProcessedValue : REAL; // 处理后的工程值
FilteredValue : REAL; // 滤波后的工程值
LowAlarm : BOOL; // 低位报警
HighAlarm : BOOL; // 高位报警
HighHighAlarm : BOOL; // 高高位报警
END_VAR
2.2 信号转换算法实现
不同信号类型需要采用特定的转换公式:
电压信号(0-10V)转换:
pascal复制ProcessedValue := (AnalogInput / 27648.0) * 10.0;
电流信号(4-20mA)转换:
pascal复制ProcessedValue := ((AnalogInput / 27648.0) * 16.0) + 4.0;
热电偶信号转换:
热电偶处理较为复杂,需要根据分度表进行非线性补偿。实际项目中建议使用西门子标准库中的"TCxx"功能块。
3. 报警功能实现细节
3.1 三级报警逻辑设计
报警系统采用分层设计,满足不同严重程度的报警需求:
- 低位报警(LowAlarm):工艺参数低于正常范围
- 高位报警(HighAlarm):工艺参数超过安全上限
- 高高位报警(HighHighAlarm):工艺参数达到危险值
pascal复制// 报警判断逻辑
LowAlarm := ProcessedValue < LowAlarmLimit;
HighAlarm := ProcessedValue > HighAlarmLimit;
HighHighAlarm := ProcessedValue > HighHighAlarmLimit;
3.2 报警死区设置技巧
为避免参数在阈值附近波动导致报警频繁触发,建议增加死区(Hysteresis)功能:
pascal复制// 带死区的报警判断
IF ProcessedValue < (LowAlarmLimit - Hysteresis) THEN
LowAlarm := TRUE;
ELSIF ProcessedValue > (LowAlarmLimit + Hysteresis) THEN
LowAlarm := FALSE;
END_IF;
4. 数字滤波算法优化
4.1 移动平均滤波实现
采用环形缓冲区存储历史数据,计算滑动平均值:
pascal复制VAR
FilterBuffer : ARRAY[0..9] OF REAL; // 滤波缓冲区
Index : INT := 0; // 当前写入位置
Initialized : BOOL := FALSE; // 初始化标志
END_VAR
// 滤波算法
IF NOT Initialized THEN
// 初始化缓冲区
FOR i := 0 TO FilterDepth-1 DO
FilterBuffer[i] := ProcessedValue;
END_FOR;
Initialized := TRUE;
END_IF;
// 更新缓冲区
FilterBuffer[Index] := ProcessedValue;
Index := (Index + 1) MOD FilterDepth;
// 计算平均值
FilteredValue := 0.0;
FOR i := 0 TO FilterDepth-1 DO
FilteredValue := FilteredValue + FilterBuffer[i];
END_FOR;
FilteredValue := FilteredValue / FilterDepth;
4.2 滤波参数选择建议
滤波深度(FilterDepth)的选择需要平衡响应速度和稳定性:
- 过程快速变化:选择3-5次(响应快但滤波效果一般)
- 过程缓慢变化:选择8-10次(响应慢但滤波效果好)
注意:滤波深度过大会导致系统响应滞后,可能影响控制品质。
5. 工程应用经验分享
5.1 抗干扰措施
在实际应用中,还需配合以下硬件措施:
- 信号线使用双绞屏蔽电缆
- 屏蔽层单端接地(通常在PLC侧)
- 模拟量模块与动力电缆保持足够距离
- 必要时增加信号隔离器
5.2 常见问题排查
-
信号跳变严重
- 检查接地是否良好
- 确认屏蔽层连接正确
- 检查附近是否有变频器等干扰源
-
报警不动作
- 确认报警阈值设置合理
- 检查报警变量是否被其他地方覆盖
- 确认没有启用报警禁用功能
-
滤波效果不佳
- 适当增加滤波深度
- 检查原始信号质量
- 确认滤波缓冲区初始化正常
5.3 功能块扩展建议
根据项目需求,可以考虑增加以下功能:
- 信号断线检测(电流信号低于3.8mA)
- 报警延时功能(避免瞬时干扰)
- 标定功能(现场校准用)
- 信号质量指示(基于波动程度)
6. 完整代码实现示例
以下是功能块的完整SCL代码,带有详细注释:
pascal复制FUNCTION_BLOCK "AnalogFilter"
VAR_INPUT
// 输入参数
AnalogInput : INT; // 模拟量原始值(0-27648)
InputType : INT := 0; // 输入类型(0:电压,1:电流,2:热电偶)
LowAlarmLimit : REAL := 20.0; // 低位报警阈值
HighAlarmLimit : REAL := 80.0; // 高位报警阈值
HighHighAlarmLimit : REAL := 90.0; // 高高位报警阈值
FilterDepth : INT := 5; // 滤波深度(1-10)
Hysteresis : REAL := 1.0; // 报警死区
END_VAR
VAR_OUTPUT
// 输出参数
ProcessedValue : REAL; // 处理后的工程值
FilteredValue : REAL; // 滤波后的工程值
LowAlarm : BOOL; // 低位报警
HighAlarm : BOOL; // 高位报警
HighHighAlarm : BOOL; // 高高位报警
SignalQuality : REAL; // 信号质量(0-100%)
END_VAR
VAR
// 内部变量
FilterBuffer : ARRAY[0..9] OF REAL; // 滤波缓冲区
Index : INT := 0; // 当前写入位置
Initialized : BOOL := FALSE; // 初始化标志
END_VAR
BEGIN
// 信号类型处理
CASE InputType OF
0: // 电压信号(0-10V)
ProcessedValue := (AnalogInput / 27648.0) * 10.0;
1: // 电流信号(4-20mA)
ProcessedValue := ((AnalogInput / 27648.0) * 16.0) + 4.0;
2: // 热电偶信号(需配合TC库)
ProcessedValue := AnalogInput; // 简化处理,实际应调用TC库
END_CASE;
// 报警判断(带死区)
IF ProcessedValue < (LowAlarmLimit - Hysteresis) THEN
LowAlarm := TRUE;
ELSIF ProcessedValue > (LowAlarmLimit + Hysteresis) THEN
LowAlarm := FALSE;
END_IF;
IF ProcessedValue > (HighAlarmLimit + Hysteresis) THEN
HighAlarm := TRUE;
ELSIF ProcessedValue < (HighAlarmLimit - Hysteresis) THEN
HighAlarm := FALSE;
END_IF;
IF ProcessedValue > HighHighAlarmLimit THEN
HighHighAlarm := TRUE;
ELSE
HighHighAlarm := FALSE;
END_IF;
// 数字滤波处理
IF NOT Initialized THEN
// 初始化缓冲区
FOR i := 0 TO FilterDepth-1 DO
FilterBuffer[i] := ProcessedValue;
END_FOR;
Initialized := TRUE;
END_IF;
// 更新缓冲区
FilterBuffer[Index] := ProcessedValue;
Index := (Index + 1) MOD FilterDepth;
// 计算平均值
FilteredValue := 0.0;
FOR i := 0 TO FilterDepth-1 DO
FilteredValue := FilteredValue + FilterBuffer[i];
END_FOR;
FilteredValue := FilteredValue / FilterDepth;
// 计算信号质量(基于最近5次采样的标准差)
VAR_TEMP
Sum : REAL := 0.0;
Avg : REAL := FilteredValue;
Variance : REAL := 0.0;
END_VAR
FOR i := 0 TO 4 DO
Variance := Variance + (FilterBuffer[(Index - i + 10) MOD 10] - Avg) ** 2;
END_FOR;
Variance := Variance / 5.0;
// 信号质量(0-100%),方差越小质量越高
SignalQuality := 100.0 - LIMIT(0.0, SQRT(Variance) * 10.0, 100.0);
END_FUNCTION_BLOCK
在实际项目中使用时,只需在OB1中调用该功能块并配置相应参数即可:
pascal复制// 在OB1中的调用示例
"AnalogFilter_DB"(AnalogInput := "AI1".RAW_VALUE,
InputType := 1, // 1表示4-20mA
LowAlarmLimit := 5.0,
HighAlarmLimit := 19.0,
HighHighAlarmLimit := 19.5,
FilterDepth := 8);
这个功能块经过多个项目验证,在石化、制药、水处理等行业都有成功应用案例。特别是在存在变频器等强干扰源的场合,其滤波效果显著,报警功能可靠,极大提高了系统稳定性。