ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

S7-1500模拟量处理全解析:NORM_X与SCALE_X指令详解

S7-1500模拟量处理全解析:NORM_X与SCALE_X指令详解 1. 模拟量信号处理到底在解决什么问题做自动化项目的人十有八九都要跟模拟量打交道。温度、压力、流量、液位这些物理量在PLC眼里不是“100摄氏度”或者“0.5兆帕”而是一个光秃秃的整数——比如12876或者5420。这个整数跟实际工程值之间差了十万八千里必须做一次数学换算才能让上位机、HMI、PID回路看懂它。S7-1500里负责这个换算的核心指令就是NORM_X和SCALE_X今天这篇就把它们从头到尾掰开揉碎讲清楚。我最早接触模拟量的时候用的是老式S7-300加FC105。后来换到S7-1500发现博途里给了NORM_X和SCALE_X这两条更灵活的指令很多新手照着教材抄了一遍程序却发现数值怎么调都不对或者量程一换就得改整个程序。这篇文章适合刚接触S7-1500的电气工程师、调试人员以及那些已经在用但没搞清楚内部换算逻辑的人。看完之后你能独立完成一路模拟量从硬件配置、软件编程到HMI显示的全流程也能明白为什么有时读数为负数、为什么量程会超限。1.1 一个现场案例压力变送器读数是乱的去年我调试过一条产线现场用的压力变送器输出4~20mA信号范围对应0~1.6MPa。PLC侧用的是S7-1500的数字量模块配合AI模块读取。第一次上电触摸屏上显示的压力值忽高忽低甚至偶尔跳到负值。排查了半天问题不在硬件而在程序里没有做标准化处理——直接把AI模块的原始值当成工程量送到了HMI。模拟量模块读回来的原始值是0~27648的整数1.6MPa对应的原始值理论上应该是27648但程序里没换算HMI直接把这个“27648”当作压力值显示当然就是天文数字。这个案例很典型。模拟量处理的核心工作就是两件事第一把0~27648的原始整数变成0~1之间的浮点数第二把0~1之间的浮点数按线性关系映射到工程量的实际量程。S7-1500里的NORM_X负责第一步SCALE_X负责第二步。两条指令一起用才能完成从原始信号到工程量的完整转换。1.2 从硬件到软件的完整信号链路要真正理解NORM_X和SCALE_X得先清楚信号从现场到PLC内部经过了什么。整个过程可以分成几段传感器变送器把物理量转换成标准电信号通常是4~20mA电流或0~10V电压模拟量输入模块接收这个电信号同时内部有量程卡或软件配置来决定电流和原始值之间的映射关系ADC转换器把模拟值变成16位有符号整数S7-1500的AI模块在4~20mA量程下默认映射为0~27648PLC中央处理器中的用户程序拿到这个原始整数通过NORM_X和SCALE_X换算成浮点工程量最后这个工程量被传输给HMI、上位机或PID回路使用。这里常被忽略的是模拟量模块本身已经做了一次标定它把4mA对应0、20mA对应27648。这个0~27648不是随便定的而是西门子模拟量标准的“归一化满量程”很多第三方仪表也遵循这个标准。如果你用0~10V输入同样也是0~27648。所以到程序层面我们只需要处理这个固定范围的整数即可。好消息是无论你接的是压力、温度还是流量只要输出信号是标准的4~20mAPLC内部的原始值范围都一样。省去了不同仪表之间标定不一致的麻烦。2. 核心指令拆解NORM_X与SCALE_XNORM_X和SCALE_X是博途TIA Portal中用于模拟量换算的标准指令。NORM_X的全称是Normalize意思是归一化SCALE_X的全称是Scale意思是标定缩放。两者通常成对出现先归一化再缩放。我第一次见到这两条指令时一度以为它们是同一个功能块的两种写法后来仔细一用才发现它们的定位完全不同。NORM_X解决的是“把不同范围的原始值压缩到0~1”SCALE_X解决的是“把0~1展开成任意工程量范围”。前者是压缩后者是展开。理解了这个思路哪怕以后遇到传感器量程是0~1000还是-40~150都能照葫芦画瓢。2.1 NORM_X指令把原始值拉回0到1NORM_X的输入输出结构很简洁MIN、VALUE、MAX是输入OUT是输出。MIN和MAX表示输入值VALUE所在的理论最小值和最大值OUT则是归一化后的结果。如果VALUE等于MINOUT为0.0如果VALUE等于MAXOUT为1.0中间的数值按线性比例计算。计算公式为( OUT (VALUE - MIN) / (MAX - MIN) )。在S7-1500中NORM_X指令支持多种数据类型常见的是INT和REAL。如果你直接拿AI模块的原始值INT类型来接一般会把MIN设成0MAX设成27648VALUE接AI原始值OUT接到一个REAL变量。这样输出就是0.0到1.0的一个小数。比如原始值为13824那么OUT就是0.5刚好对应4~20mA的中间值12mA。使用NORM_X有个容易忽略的细节MIN、VALUE、MAX这三个参数的数据类型必须一致。如果MIN和MAX是INTVALUE也必须是INT否则编译不过。我习惯先把原始值强制转换成REAL再用REAL类型的MIN和MAX。这样后面的SCALE_X接起来更方便精度也不会丢失。特别是当你的工程量量程带小数时REAL类型是必须的。注意NORM_X的MIN和MAX不是传感器量程而是原始值范围。很多新手把MIN设成0、MAX设成1.6这是完全错误的结果会乱成一锅粥。2.2 SCALE_X指令把0到1变成工程量SCALE_X的作用跟NORM_X正好相反输入是0.0~1.0之间的值输出是对应工程量的实际值。参数有VALUE、MIN、MAX、OUT其中MIN和MAX分别代表工程量下限和上限VALUE是归一化输入OUT是缩放后的工程量。计算公式为( OUT (VALUE \times (MAX - MIN)) MIN )。举例来说如果压力变送器量程是0~1.6MPa那么MIN设成0.0MAX设成1.6。NORM_X输出的0.5作为SCALE_X的输入SCALE_X算出来的OUT就是0.8MPa。这一前一后两条指令就把原始值13824变成了0.8这个有物理意义的浮点数。SCALE_X内部是线性运算所以它的输入VALUE理论上不受限于0.0~1.0。NORM_X会主动限制输出范围但如果你用别的变量直接接到SCALE_X上比如误操作传入了2.0输出会跑到量程之外。这一点在写程序时要特别小心尽量保证VALUE来自NORM_X而不是随意中间变量。调用SCALE_X时同样要注意MIN和MAX的数据类型。如果工程量是REAL那么MIN、MAX和OUT都要用REALVALUE也必须是REAL。如果VALUE是INT建议先做一次转换避免精度丢失。实测下来用REAL全程参与计算最终HMI显示的值更平滑PID控制也更稳定。2.3 为什么用NORM_X和SCALE_X而不是FC105用过老款S7-300的人都知道FC105这个模拟量缩放功能块。它直接把原始值换算成工程量输入输出一目了然。很多刚转S7-1500的工程师会问为什么还要学NORM_X和SCALE_X直接用FC105不香吗FC105确实还存在在博途的标准库中也能找到但它的灵活性远不如NORM_X和SCALE_X。FC105是固定写法输入一个原始值输出一个工程量量程参数固定写死程序一旦下载想改量程就得重新下载。而NORM_X和SCALE_X可以做成动态参数MIN和MAX可以通过DB块变量传入程序这样触摸屏上就能直接改量程无需修改程序。对于需要频繁调整量程的设备这种灵活性非常实用。另一个原因是NORM_X和SCALE_X更贴近信号处理的本质便于后续扩展。比如你想在归一化之后做非线性校正、温度补偿、滤波处理都可以在两条指令之间插入逻辑。FC105则是“一条路走到黑”中间加什么都别扭。从维护角度讲新项目统一用NORM_X和SCALE_X团队里的其他人接手也更容易看懂。3. TIA Portal完整配置实操这一节我会按照实际调试顺序从硬件组态开始一步一步带你把一路模拟量完整跑通。整个过程我都用博途TIA Portal V17配合S7-1500CPU 1511-1 PN演示AI模块用常见的AI 8xU/I模块。你手头的硬件型号可能不同但配置思路完全一样。3.1 硬件组态AI模块的测量类型与量程选择新建项目后在设备组态中添加CPU和AI模块。双击AI模块打开属性在“AI模块”的通道设置里可以看到每个通道的“测量类型”和“测量范围”。这里的选择直接决定模块内部把电信号换算成什么范围的原始值。如果你用的是两线制变送器输出4~20mA测量类型选择“电流”测量范围选择“4..20 mA”。注意不要选“0..20 mA”虽然变送器也能输出20mA但0~20mA和4~20mA的原始值映射完全不同。选错之后即使程序写对了数值也会有较大偏差。为了避免这种低级错误我每次组态完都会对着通道表看一遍确认每个通道的测量范围与现场变送器一致。AI模块属性里还有一个“积分时间”参数单位是毫秒。默认是20ms对应50Hz工频干扰的抑制。如果现场电网频率是60Hz改成16.6ms更合理。这个参数影响采样速度与抗干扰性能之间需要取个平衡。一般的工业现场20ms足够除非是做快速响应的系统可以适当调小但可能引入更多噪声。3.2 建立DB块与变量规划硬件组态完了先别急着写程序。我习惯先在PLC变量表里规划好每一路AI的原始值地址、工程量地址和量程参数地址。这样做的好处是程序写起来不乱以后调试改数据也方便。在设备树中打开“PLC数据类型”或直接在全局DB里建立变量。我常用的做法是建立一个全局DB名字叫“AI_Processing”里面按通道分组每组包含以下变量AI_RawInt来自IW地址、Norm_ValueReal归一化结果、Eng_ValueReal工程量结果、Scale_MinReal工程量下限、Scale_MaxReal工程量上限、Alarm_EnableBool量程超限报警使能。给变量选合适的数据类型很重要。AI_Raw用Int因为模拟量输入模块的地址是I字默认是Int。Norm_Value和Eng_Value用Real因为后续计算和HMI显示都依赖浮点数。Scale_Min和Scale_Max用Real让触摸屏可以修改。这个DB块就像项目的“模拟量数据中心”程序读它、写它HMI也读写它。如果有多路AI复制粘贴几行再改个名就行比在FC里反复定义形参省事得多。3.3 编写FC程序用SCL搭建可复用的模拟量处理函数我喜欢用SCL语言来写模拟量处理逻辑因为它逻辑清晰还能一次性处理多路通道。先新建一个FC定义为“FC_AI_Scale”接口参数可以设置成静态变量也可以直接操作全局DB。为了通用性我把这个FC设计成只读输入、只写输出不引入额外复杂逻辑。在FC中使用两条指令的代码示例如下#Temp_Norm_Value : NORM_X(MIN : 0, VALUE : AI_Processing.AI_Raw, MAX : 27648); AI_Processing.Eng_Value : SCALE_X(VALUE : #Temp_Norm_Value, MIN : AI_Processing.Scale_Min, MAX : AI_Processing.Scale_Max);实际项目中我不会让NORM_X直接裸奔而是先判断AI_Raw是否超出有效范围。比如当AI_Raw小于0或大于27648时说明信号断了或超量程此时直接触发报警工程值保持上一周期或置为0避免把垃圾数据送进PID。在LAD或FBD里调用NORM_X和SCALE_X也是一样的思路直接在指令列表里搜索即可。博途对这两条指令支持拖拽输入引脚可以连接常量、变量或者表达式。不过SCL写起来更紧凑适合一次性处理多通道。我个人的习惯是把多路通道写成一个FOR循环结构前提是量程参数用了数组。比如温度、压力、流量各接入一个通道量程各不相同但循环体内的处理逻辑完全一致。这样程序不仅短后期加通道时只要改循环次数和DB数组长度省了复制粘贴一大片的力气。3.4 HMI显示与DB变量连接程序写好之后建立一个HMI画面添加一个IO域或文本显示控件。把“AI_Processing”.Eng_Value关联到IO域格式选择浮点数小数位数根据实际需求设置。压力显示通常一位小数就够温度可能需要一位或没有流量可能需要两位。不要随手填4位小数现场操作员看着刷屏反而烦。另外很多HMI项目要求既有实时值又有报警提示。报警的判断逻辑我放在PLC里直接置位DB中的Bool变量HMI读取该变量弹出报警条或改变颜色。这样HMI和PLC之间传递的信息量最小响应也快。把报警逻辑放在HMI里也不是不行但每次修改报警阈值都要下载画面比改PLCDB块麻烦多了。3.5 模块滤波与采样参数设置模拟量信号在实际现场往往带有各种噪声尤其是变频器附近。S7-1500的AI模块自带滤波功能在通道属性里有“滤波”选项通常可设置为“无滤波”、“弱滤波”、“中等滤波”或“强滤波”。滤波越强信号越平滑但响应越迟钝。一般情况下用“中等”或“弱”就够。如果信号波动大可以先在模块层面做平滑再把处理后的值传送到程序里这样比在SCL里写滑动平均简单得多。有的项目需要多级滤波模块做一个程序里再做一次。我建议程序里的滤波不要用太复杂的算法取最近几次采样的平均值或一阶惯性滤波就够。一阶惯性滤波的系数可以根据时间常数调整既抑制高频噪声又不至于让响应太慢。这个系数在PID整定时特别有用调得好能让控制稳定不少。4. 常见问题与排查技巧到这里一条完整的模拟量链路已经跑通了。但实际调试中总会碰到各种奇怪现象。我把这几年的经验整理成一份速查表方便你按照现象去排查。4.1 读数跳动或干扰大模拟量信号在工业现场非常容易受到变频器、大功率电机、接触器的影响。如果你发现HMI上的数值来回跳先别怀疑模拟量模块坏了多半是干扰问题。优先检查信号电缆的屏蔽层是否单端接地是否与大电流电缆分槽敷设。如果现场条件不允许可以在模块输入侧并联一个滤波电容容量一般在0.1uF到1uF之间具体看信号频率。另外4~20mA电流环比0~10V电压信号抗干扰能力强得多。远程传输尽量用电流信号本地短距离才考虑电压信号。要是项目初期选错了信号类型后面会很被动。我在一个项目里吃过亏现场电缆走了30米用了0~10V结果DCS侧一直有数Hz的波动后来全部换成电流信号才解决。模块侧滤波参数也别忘了。把滤波强度从“无”改成“弱”或“中等”很多周期性跳动就能压下去。不过要提醒一句滤波会让信号产生滞后对控制回路影响较大。如果控制精度要求高建议滤波强度低一点把更多的处理交给程序里的滤波函数。4.2 数值超限与断线检测如果传感器断线AI模块读回的原始值通常会变得很极端。有的是0有的是超出27648有的甚至出现负值。如果不做判断SCALE_X会把超出量程的值直接算出来显示在HMI上操作员看到负压力可能会吓一跳。所以程序里务必加上限幅判断当AI_Raw小于某个下限阈值或者大于上限阈值时置位报警工程值输出0或保持上周期值。我习惯把4mA对应的原始值设成一个区间比如300~2000都视为断线或信号异常而不是只判断等于0。因为零漂和干扰会造成读数在断线附近抖动区间判断比单点判断更可靠。同理超过27000也不一定是真实超量程也有可能模块故障。我的做法是正常范围02764801000和2700027648都作为异常区间只有中间段才参与正常换算。4.3 数据类型与编译错误新手最常见的问题是NORM_X或SCALE_X编译报错提示“操作数类型冲突”。这通常是因为MIN、VALUE、MAX三者的数据类型不一致。比如MIN写的是整数0VALUE接的是REAL变量MAX写的是常量27648编译器会直接报错。解决方法是把常量都写成浮点数形式0.0、27648.0或者先把变量统一转换成REAL。如果你用的是LAD遇到类型问题可以右键引脚选择“输入常量”博途会自动做类型转换提示。我建议在写代码时直接把所有参与运算的变量都声明成REAL省去一堆转换。唯一保留INT的是从IW地址读取的原始值这个可以在读取后立即用REAL函数转成浮点。这样后面的NORM_X和SCALE_X写起来畅通无阻。4.4 量程改动的灵活做法设备交付后用户经常要求改量程。比如原来压力量程是0~1.6MPa后来换了变送器量程变成0~2.5MPa。传统做法是改程序里的MIN/MAX常量然后重新下载。但如果你把MIN/MAX放到了DB块变量里并且HMI能修改这些变量那就简单了。在触摸屏上做一个参数设置页面让操作员直接输入量程上下限PLC程序完全不用改动重启即生效。当然开放量程修改也得有限制。我一般会在程序里做一次合理性判断下限必须小于上限差值不能太小否则会触发保护性报警并拒绝写入。这样做可以防止操作员误操作把系统参数改乱。量程参数最好存储在掉电保持的DB变量里或者通过保持性设置保证重启后不丢数据。否则现场一断电参数恢复默认又得重新输入。4.5 多通道批量处理的封装思路说完单路再说说多路。一套设备上不可能只有一路模拟量。温度、压力、流量、液位少则几路多则几十路。如果每一路都复制粘贴一遍NORM_X和SCALE_X代码程序会变得又臭又长改一个参数要找好几处。我建议把模拟量处理封装成一个FC输入参数是原始值和量程上下限输出是工程值和报警状态。通过全局DB保存所有通道的配置和结果在OB1里循环调用这个FC。如果通道数量特别多可以用FOR循环配合数组索引来实现。这样新增通道时只要在DB里增加几行数据修改循环次数程序体完全不用动。后期维护非常省心别人接手看代码也一目了然。我们实际项目里最多的一次处理了32路模拟量程序体几乎没怎么变长。每一路都单独拥有自己的滤波参数、量程参数和报警阈值灵活性和可维护性都非常高。调试的时候只需要打开DB监控表可以直接在线修改测试值比翻梯形图找节点效率高太多。最后说一个我自己的小习惯模拟量处理这个FC我会把“调试模式”做成一个布尔变量。当它置1时SCALE_X的输入直接取内部手输值而不是AI_Raw。这样在试车的时候不需要去现场给信号也能在HMI上模拟各种液位和温度验证PID逻辑和报警逻辑是否正常。这个功能在项目验收阶段特别有用客户看着画面说这个值应该是多少我直接手输一个数画面立刻变省了一堆现场跑腿的功夫。做模拟量这行最重要的就是搞清楚信号从哪来、经过哪些环节、最后去哪。NORM_X和SCALE_X只是工具真正值钱的是对整个链路的理解和调试经验。希望这篇文章能把你的模拟量处理基本功打扎实少走几年弯路。
返回列表