ARTICLE DETAIL

资讯详情

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

汇川PLC水温控制实战:PID结合PWM开关量输出与梯形图实现

汇川PLC水温控制实战:PID结合PWM开关量输出与梯形图实现 做水温控制这种活最烦的不是设备不转而是温度像坐过山车加热器一开就冲过头一关就掉下来半天稳不住。我接过不少用汇川PLC做加热项目的咨询很多人都抱着“上了PID就能一劳永逸”的想法结果一调试发现全是坑。这里有个很关键的认知要先摆正工业现场大部分加热管是电阻性的没法像变频器调速那样直接把功率拉满打半你能用的往往就是一个开关量输出——要么全功率加热要么彻底断电。所以PID算出来的结果必须转换成“开多久、停多久”的开关时间比例才能真正控制住水温。这篇文章我准备用汇川PLC的实战项目来讲清楚这件事核心是PID和开关量输出的配合以及梯形图程序怎么一步步搭。内容会覆盖硬件选型、模拟量采集、PID参数整定、PWM占空比输出还有调试时容易踩的坑。不管你是刚接触PLC的新手还是已经在车间里调过不少设备的老手这套思路都值得收藏一份。1. 项目到底解决一个什么问题1.1 温度控制为什么不是“简单通断”就行很多第一次做加热项目的人会想水温高了就断开加热器低了就合上这不就完了吗这种“纯开关量”的控制方式在某些对精度要求极低、水箱又特别大的场合勉强能用但只要目标温度稍微高一点或者系统惯性稍小一点问题立刻暴露——你看到的温度曲线就是一条不断上下波动的锯齿波设定80度的水实际温度能在75到85度之间来回荡。原因也很好理解加热管一通电水温不会立刻上升温度信号有滞后断电以后加热管上的余热还会继续往水里传递温度也不会马上停。纯逻辑判断根本判断不了“当前该提前关还是提前开”只会等温度过冲了才反应。这时候就需要PID了。PID的本质是“根据偏差的大小、快慢和历史趋势计算出合适的输出量”。但问题来了PID输出的是一个连续值比如“输出功率58%”。加热管不支持连续功率调节怎么办答案就是把连续值变成开关量占空比在一个固定周期内58%的输出就是“通0.58秒断0.42秒”。温度控制因此从“傻通断”进化成“时间比例控制”这就是这个项目最核心的解决方案。1.2 适合哪些场景用PID加开关量控制水温适合的场景非常典型电加热水罐、热水锅炉、模具恒温机、清洗线加热槽等没有模拟量输出模块或者不想给加热管配可控硅调压器的项目传感器用PT100、热电偶加变送器后接到PLC模拟量输入现场希望用一个屏或者按钮就能设定目标温度并要求实时显示偏差和输出比例。这个方案的好处是硬件成本低、接线简单、可靠性高。坏处是加热管工作在“忽通忽断”的状态如果开关频率太高会直接影响接触器或固态继电器寿命。所以真正要花心思的一方面是把PID参数调好另一方面是选一个合理的通断周期。2. 硬件选型与系统架构2.1 核心器件清单我按照一套中规中矩的配置来说这套配置在小型水加热项目里很常见器件你换成手册对应型号即可思路不变。序号器件型号/规格说明用途1PLC汇川Easy320系列本体自带网口主控制器跑PID逻辑2模拟量输入本体AI通道或扩展模块读取温度变送器信号3温度传感器PT100铂电阻三线制检测水温4温度变送器输入PT100输出4-20mA将PT100阻值变化转换为标准电流信号5加热管220V/380V根据功率选加热介质6开关量输出晶体管/继电器输出驱动中间继电器控制加热管通断电7固态继电器(SSR)过零触发型电流按加热管功率选无触点通断频率可以高一些8触摸屏可选走Modbus TCP或以太网设置温度、监控曲线这里有个取舍要说明用普通接触器控制加热管也可以但接触器是机械结构通断寿命有限动作频率不能太高。我们做PID时间比例控制时通断周期一般取0.5到2秒接触器根本扛不住这种频繁动作。所以我做这个项目都会强烈建议换成固态继电器电热负载用单相或三相固态继电器体积小、响应快、过零触发还能减少对电网的冲击。2.2 接线与信号流程信号链路并不复杂画出来就三条线温度变化 → PT100阻值变化 → 变送器输出4-20mA → PLC模拟量输入通道 → PLC内工程量转换得到实际温度 → PID功能块计算输出百分比 → PWM通道/梯形图脉宽输出 → 固态继电器 → 加热管通断电。接线时最容易出错的有几个地方PT100变送器的供电和信号地要与PLC模拟量输入模块的公共端对应好很多模块AI通道共用一个COM端接反了读数要么不准要么直接烧通道;变送器信号线用屏蔽双绞线屏蔽层单端接地不要和动力线捆在一起走线槽否则温度信号会跳得厉害固态继电器要加散热器尤其是连续大电流工作时发热相当可观控制加热管通断的DO输出如果是继电器输出不建议直接驱动大功率交流接触器最好先驱动一个中间继电器再让中间继电器控制接触器或固态继电器。2.3 汇川Easy320平台要注意的事汇川产品线现在分得比较细老款的H系列、新款的Easy系列编程软件和底层逻辑有差异。我用的是Easy320配InoProShop编程软件编程语言遵循IEC 61131-3梯形图只是其中一种这也意味着你可以在同一个工程里混用梯形图、结构化文本和功能块图。有一个容易被忽略的点Easy320本体虽然集成了模拟量输入输出和通讯接口但具体通道数量、量程范围和接线端子定义不同型号差别很大。做设计的时候不要光看“别人用Easy320我也用”要先去官网下载该型号的用户手册和选型样本确认本体AI通道支持的是4-20mA还是0-10V模拟量数字量的原始值范围是0~4000还是0~27648PID运算周期和模拟量刷新周期是否匹配。这些细节直接决定了梯形图里工程量换算的系数后面我会细讲。3. PID三个参数与时间比例输出原理3.1 先把PID输出这件事想明白很多初学PLC的人对PID有两个误区一是以为调用一个PID功能块就能自动控制好二是把PID的输出直接当成一个模拟量接到变频器或调节阀上。实际上PID功能块就是一个“计算器”你给它设定值、反馈值、比例系数、积分时间、微分时间它算出一个数这个数的物理意义完全取决于你定义。在温度控制项目里你可以把它定义成“输出百分比0-100%”。这个百分比在加热控制中代表的是“在控制周期内加热器应该通电的时间比例”。举例说PID算出来输出是60%周期设为1秒那么加热管就通电0.6秒、断电0.4秒。把这0.6秒的“ON时间”按周期循环加热器的平均功率就相当于满功率的60%。这种做法在行业内叫时间比例控制也叫占空比控制。为什么要强调“PID输出不是直接给DO”因为DO只有0或1而PID输出是0到100的连续数值。中间必须有一个“脉宽调制”环节才能把连续值翻译成开关量动作。这个翻译环节你可以用专门的PWM功能块实现也可以用两个定时器在梯形图里自己做。后面我会给出两种方式的做法。3.2 控制周期怎么选时间比例控制的周期是第一个要定的参数。选得太长比如10秒甚至30秒水温会跟着“一浪一浪”地波动实际温度会在设定值附近来回晃动选得太短比如0.1秒虽然温度平稳但固态继电器频繁动作发热器件的寿命会受影响。我的经验是容量比较小的水箱几十升以内、加热管功率占比大、响应快周期可以取0.5秒中等容量水箱取1秒容量大但加热功率相对小、温度惯性大的系统可以取2到5秒。大多数现场水温控制从1秒起步调都问题不大。如果你用接触器而不是固态继电器那么周期最好拉到3秒以上否则接触器线圈和触电撑不住。这里还要顺便说一句“最小开时间”的概念。比如一个周期1秒PID输出算出来是1%那么通电时间只有10毫秒固态继电器可能还没来得及可靠导通就断开了。这种输出对控制没有意义。所以程序里通常要加一个输出下限处理要么让PID输出最小值不低于5%要么在PID输出小于某个值时直接视为0输出。等温度接近设定值后PID稳定在小输出区间时也不要硬去追求极小的占空比那是钢丝上跳舞没有实际意义。3.3 参数整定的基本框架PID的参数Kp、Ti、Td是我觉得整套系统里最玄学的部分。不过只要理解了每个参数的性格就不会太慌Kp比例系数决定“偏差一出现立刻输出多大修正量”。Kp太大系统容易震荡太小升温慢可能到不了设定值。Ti积分时间专门负责消除稳态误差。积分是把历史偏差一点点累积起来持续输出纠偏。Ti越小积分作用越强但太小会引起超调。Td微分时间看到偏差的未来趋势提前刹车。水温是大惯性对象微分用得不好会把传感器噪声放大导致输出像机关枪一样乱跳。所以我做水温控制通常建议先Td0等Kp和Ti调稳了再加微分量。整定顺序有讲究。第一次调试先不给积分和微分只留Kp。把设定值设成一个常用温度比如60度从比较小的Kp开始加观察温度曲线。如果系统出现等幅震荡记下此时的Kp临界比例增益和震荡周期然后用齐格勒-尼科尔斯经验公式算出一组基础参数。不过在水温这种大惯性对象上经验公式给出的参数往往偏激进我会在这个基础参数上再打八折甚至对折给系统留够余量。调试中你大概率会看到这些现象升温太慢压着Kp加不上去到了设定值附近总超调把Ti调大稳态之后还有0.5度的固定误差把Ti减小温度抖动像锯齿先检查是不是传感器滤波不够或周期太长。4. 梯形图实操编写4.1 变量和地址规划在正式写梯形图之前先把变量规划好这一步别偷懒。我在InoProShop里用的是IEC变量风格输入变量名可以自己定义然后再映射到物理地址。下面是这个项目的常用变量表你可直接照搬。VAR bStart : BOOL; (* 启动按钮 *) bStop : BOOL; (* 停止按钮 *) bRun : BOOL; (* 运行标志 *) bModeAuto : BOOL; (* 手动/自动切换 *) bLowLevel : BOOL; (* 低水位保护 *) bHeatOut : BOOL; (* 加热输出 *) bAlarmHigh : BOOL; (* 高温报警 *) iRawAI : INT; (* 模拟量原始值 *) rPvTemp : REAL; (* 实际水温单位℃ *) rSetPoint : REAL; (* 目标水温默认80.0 *) rPidOut : REAL; (* PID输出百分比 0-100 *) rManualOut : REAL; (* 手动模式下的输出百分比 *) rCtrlOut : REAL; (* 最终控制输出百分比 *) rKp : REAL; (* 比例系数 *) rTi : REAL; (* 积分时间单位秒 *) rTd : REAL; (* 微分时间单位秒 *) tonCycle : TON; (* 控制周期定时器 *) tonOnTime : TON; (* 导通时间定时器 *) pwmPeriod : TIME; (* PWM周期如 T#1S *) tonTimeOnMs : TIME; (* 导通时间由rCtrlOut计算 *) END_VAR变量名你可以按自己的习惯缩写但务必把单位写在注释里。尤其是Ti和Td这类时间参数有的库用秒有的库用毫秒写混了系统很难稳定这种问题排查起来最容易让人抓狂。4.2 模拟量采集与工程量转换这里先说一下工程量转换的意义。PLC模拟量模块读到的是一个整数比如0到4000的原始值这个值并不是温度。温度变送器把PT100信号变成4-20mA而4-20mA又对应PLC模块的原始值范围最后要把它还原成0到200℃的真实温度这正是“工程量换算”要做的事。我现在以汇川常见“AC信号在CPU内部显示为0~4000”为例不同模块、不同量程配置会有差异实际以你选的型号手册为准来写梯形图逻辑。第一段梯形图先读模拟量原始值再换算成温度(* 模拟量读取通道实际地址按IO映射配置 *) iRawAI : %IW0; (* 换算0-4000 对应 4-20mA温度量程 0-200℃ *) rPvTemp : INT_TO_REAL(iRawAI) * 200.0 / 4000.0;如果你的模块量程是0-27648就把分母改成27648。需要注意如果原始值里包含“断线检测值”比如断线时报出-32768你需要在程序里加一个判断防止把异常值带入PID计算导致加热失控。常见的做法是当iRawAI小于量程5%时输出传感器故障报警并切断加热输出。这是个很小但非常重要的程序保护。我在实际项目里见过温度信号线松动模块读到满量程PID立刻把加热输出降到0反而没有引发事故但如果读到的是半量程且还在不断漂移PID就会按照错误温度反复调节场面就特别难看。所以模拟量上限、下限的判断要做而且要在联锁里把加热退出。4.3 PID功能块调用打开InoProShop的库管理器找到控制器自带的PID库把PID功能块拖到梯形图里或者直接在LD界面插入功能块实例。不同版本库的PID引脚名称略有差别但核心引脚逃不出下面几个引脚说明SV设定值PV过程反馈值KP比例增益TI积分时间TD微分时间OUTPID输出CYCLEPID运算周期有的库没有直接用任务周期我的梯形图写起来大概是这样的(* 调用PID功能块输出结果保存到rPidOut *) PID_Water( SV : rSetPoint, PV : rPvTemp, KP : rKp, TI : rTi, TD : rTd, OUT rPidOut );有一点必须强调PID功能块每一次扫描都会执行一次计算但它的计算周期应该和系统被控对象匹配不能简单地“PLC扫描多快就跑多快”。水温对象慢PID运算周期放在100ms到500ms都合适。具体做法是将PID程序放在一个周期性任务里或者给PID块一个固定的PID运算周期。如果PID周期太短积分累积得太快参数很难调周期太长又会感觉系统反应迟钝。另外如果PID库支持输出限幅把输出限幅设为0-100%。这一步不做好的话积分饱和会很严重。什么叫积分饱和就是温度还远低于设定值时PID输出一直在100%积分项慢慢堆积到很大等温度到达设定值输出需要往回降但积分项一时半会儿减不下来温度就会大幅超调。限幅不能解决全部问题但能减轻不少。4.4 用PWM把PID输出变成开关量PID算出了rPidOut接下来就是把这个0到100的百分数转成加热管的通断动作。最简洁的办法是用库里的PWM功能块它通常提供周期和脉宽两个输入引脚(* PWM功能块周期1秒脉宽由PID输出换算 *) PWM_Heat( Enable : bHeatReady, CycleTime : T#1S, OnTime : TIME_OUT : ULINT_TO_TIME? 这就需要用上位逻辑换算 );不同厂家的PWM块引脚设计不一样有的需要传“脉冲宽度时间”有的直接传“占空比百分比”写之前一定要看库说明。如果实在没有PWM块或者想彻底搞明白原理我建议你自己用两个TON定时器做这也是现场排查问题时最保底的办法。自己做的思路如下一个TON负责产生基准周期另一个TON负责控制加热ON时间。假设周期固定为1秒第一步控制周期定时器tonCycle到1秒后复位同时把tonOnTime复位重启第二步计算onTimeMs : rCtrlOut / 100.0 * 1000ms第三步比较tonOnTime已经计时的时间是否小于onTimeMs小于就让加热输出为ON否则为OFF。放在梯形图里逻辑长这样(* 周期定时器PT1s到时间自复位 *) tonCycle( IN : bHeatReady AND NOT tonCycle.Q, PT : T#1S ); (* 周期到复位导通定时器 *) tonOnTime( IN : bHeatReady AND NOT tonOnTime.Q, PT : TIME_TO_ULINT? -- 根据ON时间设定 ); (* 导通时间计算公式 *) onTimeMs : REAL_TO_TIME((rCtrlOut / 100.0) * 1000.0);实际LD里你只需要把onTimeMs赋给tonOnTime的PT输入然后在输出比较前取一个判断如果tonOnTime计时未到onTimeMs则bHeatOut为ON否则为OFF。比较指令在梯形图里用“”或“”功能块实现。我把这段逻辑的最终控制变量写在下面bHeatReady : bRun AND bLowLevel AND NOT bAlarmHigh; rCtrlOut : SEL(bModeAuto, rManualOut, rPidOut);这里的SEL是选择函数bModeAuto为FALSE时把手动输出当作最终输出为TRUE时把PID输出当作最终输出。手动模式是用来调试加热器本身好不好用的千万别一上来就跑自动PID。4.5 完整梯形图逻辑串联把前面几个段落串起来就是一个可以下载到PLC里运行的骨架。我通常会把程序分成几个梯级写在同一个POU里Rung 1启动和停止控制(* 启动按钮按下运行标志置位停止按钮按下运行标志复位 *) bRun : (bStart OR bRun) AND NOT bStop;这段是典型自锁电路不过用赋值指令做也行。你果你喜欢传统触点梯形图可以在LD里画成按钮并联自己的常开触点再串联停止按钮的常闭触点。Rung 2安全联锁bAlarmHigh : rPvTemp rAlarmTemp; bHeatReady : bRun AND (NOT bLowLevel) AND (NOT bAlarmHigh);这里的rAlarmTemp是上限报警温度一般取设定值加3到5℃。低水位这个信号我强烈建议接到硬接点输入不要只在触摸屏界面上做一个软开关真实工况下水位过低但加热器还在烧那会出大问题。Rung 3模拟量读取和温度换算iRawAI : %IW0; (* 假设物理通道地址为IW0 *) rPvTemp : INT_TO_REAL(iRawAI) * 200.0 / 4000.0;Rung 4PID输出PID_Water( SV : rSetPoint, PV : rPvTemp, KP : rKp, TI : rTi, TD : rTd, OUT rPidOut );Rung 5手动/自动选择rCtrlOut : SEL(bModeAuto, rManualOut, rPidOut);Rung 6PWM脉宽输出用PWM功能块的直接接用自写TON方案的把rCtrlOut换算成通断时间再输出。Rung 7实际DO地址绑定%QY0 : bHeatOut; (* 加热输出 *) %QY1 : bAlarmHigh; (* 报警输出 *)以上是最基础的逻辑。工程上建议再加一个“手无自动时加热输出显示”把rPidOut和rManualOut都显示在触摸屏上方便调机时观察。5. 调试过程与常见问题5.1 第一次上电千万别直接跑PID我在现场的习惯是“先手动再自动最后精调”。第一次上电先把手动/自动开关拨到手动手动输出给一个10%左右的小占空比确认加热管能正常发热、温度能上去再切到自动设定值设低一点比如30度看看传感器读数是不是稳定、升温方向是否正确。很多新手容易犯的错误是程序一写好就设目标温度80度直接自动跑。结果传感器接反、变送器量程不对、输出接错等基础问题全堆一起温度乱跳你根本分不清是PID的问题还是硬件接线的问题。手动模式就是用来隔离这些故障的。5.2 温度曲线常见的三种病第一种病温度永远到不了设定值稳态误差一直存在。这种问题十有八九是积分作用不够。Kp只负责“有偏差就修正”但偏差小到一定程度以后修正量也变小最后系统停在“加热量和散热量相等”的位置上离设定值差那么一点。此时把Ti调小让积分加速累积就能把这部分误差顶上去。如果你用的是不支持积分抗饱和的老旧PID库还要检查是不是因为饱和限制导致积分根本没法累积。第二种病到设定值附近来回震荡幅度越来越大。原因通常是Kp太大或者积分时间太短。我见过有人一上来把Kp设到几百Ti设成0.1秒结果温度直接变成发散震荡加热管一下全开一下全关。保守的做法是先把Kp减半Ti增一倍观察一两个周期再调。水温对象惯性大一次调整完成后至少等几分钟才看效果别刚看10秒就改参数。第三种病温度震荡很小但有规律比如±0.3度。这种往往不是PID参数问题而是控制周期太长。你设了3秒的PWM周期相当于每3秒才调节一次加热功率对快响应的小水箱来说自然会产生周期性波动。把周期缩短到1秒波动就会明显变小。如果传感器本身噪声大比如热电偶屏蔽没做好还要先解决采样噪声不然PID的微分环节会把噪声放大得更厉害。5.3 常见问题速查表问题现象可能原因处理办法温度显示乱跳屏蔽线没接好、传感器与动力线同槽检查接线传感器远离动力线加滤波升温特别慢Kp太小、Ti太大、输出上限过低增大Kp减小Ti检查输出是否被限幅超调严重Kp太大、Ti太小、系统接近饱和降低Kp增大Ti确认抗积分饱和有效温度稳定但始终低于设定值积分作用不足减小Ti并检查稳态偏差加热输出频繁通断PWM周期太短增加周期到1秒以上自动模式没输出模拟量读数异常、PID输出被限为0查看rPidOut检查传感器和工程量换算手动模式正常切自动后失控设定值或PID参数设置错误从低目标温度重新开始逐步提高5.4 关于微分项和传感器滤波温度控制这种慢对象多数情况下可以不加微分。微分本质上是“对偏差变化的预测”但水温的滞后时间很长偏差变化往往不是立刻反映原因微分很容易被数字采样噪声骗到。我的习惯是Td先设0等纯比例和积分把系统调到基本稳定再看超调趋势。如果超调出现得很突然而且系统有足够时间提前响应我才会尝试加一点微分一般取积分时间的1/8到1/4。传感器滤波也一样可以在模拟量读取后加一阶低通滤波或者均值滤波但不要滤波过度。水温本身是慢变量加1秒以内的时间常数没问题可如果滤波太长反馈值变化太迟钝PID看到的永远是“过去”的温度就容易滞后震荡。6. 最后说点个人经验做了这么多温度控制项目我最深的体会是PID这东西不是什么黑魔法而是一个需要尊重过程机制的工具。你理解了它输出的是比例、积分、微分三股力量的合成理解了加热管只能靠时间比例来等效功率剩下的就是按步骤调试、观察曲线、改参数。再做扩展的时候有两个方向很实用如果现场有变频器或可控硅调压模块可以把PID输出直接接到模拟量输出上实现真正的连续功率调节控制品质会比开关量方式更细腻如果对象是大水箱、滞后特别大可以考虑加前馈控制——比如检测到进水量增加时提前按比例提高输出——避免PID被滞后拖住反应不过来。如果你准备在汇川PLC上跑这套程序我的建议是先在办公室用一个小电热水壶或者小型恒温槽验证逻辑用触摸屏把rPvTemp、rPidOut、rKp、rTi这几个变量显示出来一边看曲线一边调。等把握了PID的脾气再上现场的大设备心里就完全有底了。
返回列表