
在自动化实训室和一线现场里水箱液位控制大概是最经典的综合项目之一——一台S7-200 PLC一根PPI通信线配上组态王上位机就能把PLC编程、模拟量采集、上位机监控和通信调试全部串起来。我做这个系统前后花了三个星期中间踩了不少坑最后把整套流程完整跑通后最大的感受是这类题目看似简单实际上它把工控联调的整套思路都过了一遍。这篇就写一下我自己的实现过程从方案选型到硬件接线从PLC梯形图到组态王画面组态再到联调阶段的故障排查尽量把每一步的来龙去脉和取舍逻辑讲清楚。1. 系统的功能需求与控制方案设计1.1 水箱液位控制到底要解决什么问题先说清楚项目需求。典型的水箱液位系统是一个储水罐进水侧由水泵或者电动阀控制出水侧根据工艺需求持续排水。如果只靠人工盯着水位去开泵、关泵既费人力又容易出事故——水位太高会溢流太低会把水泵抽空烧掉。所以系统的核心目标很简单通过控制器实时读取液位传感器信号自动控制进水执行机构把液位维持在某个安全范围内。这个项目之所以适合拿来做毕业设计或者入门练手是因为它同时覆盖了工控领域最基础也最重要的两块一是开关量逻辑控制泵的启停、报警输出、手自动切换二是模拟量信号处理4-20mA液位信号的采集、量程换算、闭环调节。再加上组态王上位机等于把PLC这一层的“裸逻辑”和SCADA监控层的“人机界面”全部打通了。以后做冷库监控、恒压供水、洁净车间液位控制底子都是这套东西。我做这个系统时的基本配置是一个模拟储水罐一台静压式液位变送器输出4-20mA信号一台小型水泵负责向水箱注水底部有一个出水阀门模拟用户用水控制器采用西门子S7-200。用组态王在电脑上显示实时液位、泵状态、报警信息并且能在画面里直接修改液位设定值。1.2 双位回差控制与PID连续调节怎么选水箱液位的控制方案业内最常见的是两种双位回差控制和PID连续调节。很多人一看到液位控制就直接上PID其实不一定合适。双位回差控制的思路很简单液位低于启动值就开泵高于停止值就关泵中间区域保持原状态。这就好比家用空调压缩机的启停逻辑设定26度到27度启动到25度停机中间那两度就是回差目的就是避免设备频繁启停。双位控制的优点是不需要变频器、不需要PID参数整定成本低、逻辑清晰特别适合液位允许在一定范围内波动的水箱、水池类对象。PID连续调节则适合对液位精度要求高的场合比如恒压供水、锅炉汽包水位这类工艺上要求液位稳定在某个值的系统。它的实现代价要大得多执行机构需要支持连续调节变频器或者调节阀还要花时间整定P、I、D参数。整定不好的PID比双位控制还难用液位会在设定值附近来回震荡画面上的曲线像锯齿一样。我最终选择的是双位回差控制作为主要方案同时把PID作为一个扩展备选写进了系统设计里。对教学演示来说双位回差能让观察者直接理解“回差”这个工程概念在组态王画面上还能通过输入框实时修改启动值和停止值交互感很强。对比项双位回差控制PID连续调节执行机构接触器/继电器启停泵变频器或调节阀液位波动幅度较大约±5%~10%较小可达±1%调试难度低只需设置两个阈值高需整定增益、积分、微分成本低高适用场景水池、水箱、水塔恒压供水、锅炉汽包、工艺精确液位1.3 硬件选型和I/O分配方案硬件选型上S7-200我选了CPU226 CN自带24路数字量输入、16路数字量输出对水箱这种规模的项目来说余量很充足。模拟量采集配了一块EM231模拟量输入模块4路输入12位分辨率支持0-20mA和4-20mA通过模块侧面的DIP拨码开关切换。液位变送器选了常见的两线制静压式量程0-5米输出4-20mA两根线既供电又传信号。这里有个容易忽略的细节EM231的跳线开关必须拨到4-20mA档位而不是0-20mA档位。如果拨在0-20mA4mA对应的不再是零点整个量程换算全部错位液位显示会严重偏高而且低液位时读数不为零。我第一次调试时就吃过这个亏。I/O分配我提前在纸上列好避免写程序时东一个地址西一个地址地址类型用途说明I0.0数字输入现场启动按钮常开触点I0.1数字输入现场停止按钮常闭触点I0.2数字输入手自动切换开关打在自动位置为1AIW0模拟量输入液位变送器4-20mA信号EM231第一通道Q0.0数字输出水泵接触器控制进水Q0.1数字输出排水电磁阀模拟出水Q0.2数字输出报警指示灯/蜂鸣器声光报警硬件接线的供电原则也要注意PLC本体用220V供电EM231模块的24V电源最好单独用开关电源液位变送器和PLC不共用同一路24V电源避免水泵启停瞬间的电压跌落干扰模拟量信号。信号线和动力线分开走线穿金属管或者屏蔽电缆这在后面调试时会省很多麻烦。2. PLC侧S7-200程序的关键实现2.1 模拟量采集与工程量换算S7-200读取EM231的模拟量输入数据存放在AIW0这个地址里。EM231在4-20mA单极性模式下对应的数字量范围是0到32000。也就是说4mA对应020mA对应32000线性关系。很多刚从S7-300/1200转到S7-200上的人会习惯性认为满量程是27648这在S7-200上是不对的。S7-200模拟量满量程就是32000程序里必须按这个数值做换算。另外AIW0是只读寄存器不要往里面写任何数据。要做工程量百分比换算标准步骤是先把AIW0的整数转换成双整数再转成实数然后除以32000.0乘以100.0得到0到100.0之间的液位百分比存到一个浮点变量里。我习惯存到VD100这样组态王直接读VD100就能显示百分比数值。换算这一段的STL语句表写出来是这样的// 模拟量原始值读取 LDW AIW0, 0 // 下限处理防止负值 MOVW 0, VW200 // 整数转实数并换算百分比 LD SM0.0 ITD AIW0, VD210 // 整数转双整数到VD210 DTR VD210, VD210 // 双整数转实数 MOVR VD210, VD100 /R 32000.0, VD100 // 归一化到0.0-1.0 *R 100.0, VD100 // 转换为百分比0.0-100.0梯形图的做法就是在“整数运算→浮点运算”工具箱里依次拖出整数转双整数、双整数转实数、实数除法、实数乘法这些块连接关系和我上面的STL完全一致。需要说明的是VD210只是我的中间运算临时地址实际项目中占用哪个VD区都行只要不和PID向导区、其他变量区冲突即可。这里的关键是浮点数的存储格式S7-200的VD地址存储的是32位实数IEEE 754浮点数和组态王里的“实数”类型一致。很多人组态王读VD100显示乱码问题就出在类型不匹配上后面第3章我会具体讲。2.2 手自动切换的框架设计水箱控制系统必须支持手动和自动两种模式。手动模式用于调试、检修和应急操作操作员在组态王画面上可以直接点“水泵开”“水泵关”自动模式下PLC根据液位自动决策。我在程序里用M0.0作为手自动模式标志位I0.2是现场切换开关组态王也能修改。手自动切换在PLC程序设计里是个基础框架不管以后做什么项目都会用到建议养成好习惯所有输出在手动模式下由人工指令直控自动模式下由逻辑条件控制两条支路并联输出。梯形图的输出网络基本逻辑// 手动控制支路M10.0为手动开启指令M10.1为手动停止指令 LD M10.0 O Q0.0 AN M10.1 AN I0.1 // 现场停止按钮总复位 M20.0 // 手动允许启动中间变量 // 自动控制支路双位回差逻辑见下一节 LD M0.0 // 自动模式 AN M10.1 M20.1 // 总输出 LD M20.0 O M20.1 A I0.1 // 急停/停止按钮串入总回路 Q0.0手动模式做检修时组态王画面上的“手动开泵”按钮实际操作M10.0自动模式下组态王上的启动按钮M0.1只是给自动逻辑一个运行许可真正的决策由液位比较决定。这样分工清晰不容易误操作。2.3 双位回差控制的梯形图逻辑双位回差控制在S7-200里的实现非常简单关键在于用好浮点比较指令。S7-200的浮点数比较必须在“比较指令”里选择实数类型比如浮点数大于等于指令LDR而不是用整数比较指令去比较VD100。这是一个非常典型的初学者错误。我把启动值存到VD104停止值存到VD106。逻辑上液位低于等于VD104时置位泵输出液位高于等于VD106时复位泵输出中间区域保持当前状态。这样即使液位在30%和60%之间波动泵也不会反复启停。STL如下// 液位小于等于启动值(VD104)时启动水泵 LDR VD100, VD104 S Q0.0, 1 // 液位大于等于停止值(VD106)时停止水泵 LDR VD100, VD106 R Q0.0, 1举个例子来说VD104设为30.0VD106设为60.0。如果液位在45%的时候停泵了水被放走降到30%以下泵启动泵启动后水位上涨到60%以上泵停止。在这个区间里泵不会动作这就是回差的意义。如果回差设置得太小比如启动值设45%停止值设55%看起来液位波动小了但泵会在液位稍微一动就启停一次接触器频繁吸合释放电机和接触器寿命都会受很大影响。实际项目中启动值和停止值的差值建议不低于15%-20%。2.4 扩展内容改用PID闭环时怎么配置向导如果工艺要求液位必须稳定在一个值比如恒定在50%那就需要PID连续调节。S7-200本身不带PID硬件模块但指令库里有PID向导用起来比较方便。在编程软件里选择“工具→PID向导”配置一个PID回路。向导会让你指定给定值和过程变量的来源我建议过程变量直接选AIW0输出选数字量因为在S7-200里PID向导输出的0.0-1.0可以用PWM方式控制水泵或者经过换算送给模拟量输出模块控制变频器。向导会生成两个子程序PID0_INT和PID0_CTRL必须在主程序里用SM0.0无条件调用PID0_INIT中断初始化在主程序末尾调用PID0_CTRL回路控制。这一步忘掉的话PID是完全不执行的。PID向导会占用一批VB存储器默认好像是VB8到VB23这段区域。如果程序里手工定义的变量地址刚好落在这个区域里运行起来数据会互相覆盖液位值会莫名其妙跳变。解决方案是先运行PID向导记住它占用的VB区间再给其他变量安排地址时绕开。这是S7-200项目里一个很隐蔽的坑我见过不少人在液位突然变成几百、PID输出乱跳这类问题上卡很久。PID参数默认值都是0这意味着默认情况下输出也是0或者直接根据你的初始值来必须手动设置。常用的整定起手式先设增益为1积分时间和微分时间设为0跑起来观察液位曲线再逐步调整。关于整定的现场过程我在第4章联调实录里详细讲。2.5 报警与设备保护逻辑报警逻辑是PLC程序里不能省的部分。水箱液位控制的报警分两层一层是工艺报警提醒操作人员液位偏高或偏低另一层是设备保护防止泵在缺水状态下干转烧毁。工艺报警我用四个阈值高高报90%、高报80%、低报20%、低低报5%。液位超过80%时置位报警中间变量M1.1输出Q0.2报警灯超过90%时除了报警还要直接停泵因为再继续进水就可能溢流了。液位低于20%也报警提醒出水侧用户注意余量低于5%时强制停泵这个就是干转保护——水泵在缺水状态下运行机械密封和叶轮都会因为摩擦高温损坏几秒钟内可能就报废了。报警逻辑用浮点比较和置位复位指令就能实现还要加一个报警复位按钮M1.2操作员确认故障处理完毕后才能手动消除报警状态。报警状态在组态王画面上既要有灯光显示也要进报警窗口做历史记录这部分我在第3章讲组态王配置时一起说。3. 组态王侧画面上位机怎么搭起来3.1 通信配置PPI驱动别卡在这步组态王连接S7-200的物理链路是PPI协议在组态王设备驱动里选择“PLC→西门子→S7-200→PPI电缆”。通信硬件最常见的是原装PC/PPI电缆或者USB-PPI兼容线。原装线稳定兼容线上的USB转串口芯片如果是CH340或者PL2303装好驱动后会在设备管理器里虚拟出一个COM口组态王就连接这个COM口。配置设备时需要注意几个关键参数任何一个不对通信都建立不起来参数推荐设置说明串口COM1或虚拟COM口以设备管理器实际占用为准波特率9600必须和PLC系统块设置一致数据位8PPI标准停止位1默认校验偶校验PPI默认PLC站地址2S7-200默认站地址第一次配置完一定要用组态王里的“设备测试”功能验证通信。设备测试窗口里能看到发送计数和接收计数如果发送在涨、接收不动说明物理链路还没通如果接收也在涨说明通信已经建立了可以直接读PLC的某个变量看当前值。这里有个很实在的经验组态王运行时会把串口占住如果在同一个电脑上还要用STEP 7 Micro/WIN下载程序必须先关闭组态王的运行系统让出串口Micro/WIN才能连接PLC下载程序。反之Micro/WIN连接PLC时会占用PPI口这时候再开组态王通信当然是失败的。正确操作顺序是先用Micro/WIN把程序下载完关掉Micro/WIN的通信再启动组态王。3.2 数据词典变量类型与寄存器地址对应关系组态王的数据词典是整个上位机的心脏。很多人在这一步翻车——界面画好了按钮也写了命令语言结果运行起来数值全部乱码或者通信报错八九不离十就是变量类型或者寄存器地址配置得不对。S7-200的PLC变量要按存储区对应到组态王变量。下表是我这个系统的数据词典定义变量名数据类型寄存器地址寄存器格式说明液位百分比I/O实数VD10032位浮点液位百分比0-100启动值I/O实数VD10432位浮点双位控制启动阈值停止值I/O实数VD10632位浮点双位控制停止阈值手自动模式I/O离散M0.0Bit1自动0手动自动启动指令I/O离散M0.1Bit自动逻辑运行许可自动停止指令I/O离散M0.2Bit自动逻辑停止水泵运行状态I/O离散Q0.0Bit泵接触器反馈报警状态I/O离散M1.1Bit声光报警激活核心点在于S7-200的VD寄存器是32位浮点数组态王这边的类型必须选“I/O实数”绝对不能选“I/O整数”然后自己脑补换算。反过来如果只对模拟量原始值AIW0感兴趣那才定义成I/O整数。我的做法是PLC程序里已经做了完整的模拟量换算所以组态王直接读VD100就是液位百分比画面上不需要写任何转换脚本。新建变量时还要注意组态王的“寄存器格式”选项里选“VD”或者“VB”“VW”同一个地址不同的格式访问的数据宽度完全不同。VD100读的是32位浮点VW100读的是16位整数VB100读的是8位字节。选错了轻则数值不对重则直接通信报错。3.3 画面组态与动画连接实操组态王画面设计的核心是“动画连接”也就是把图形元素和变量绑定起来让画面上的东西跟着PLC数据变化。我画水箱液位画面的顺序是这样的先用矩形工具画一个水箱外形在里面叠一个稍小一点的矩形作为水体。双击水体矩形选择“填充”动画连接关联“液位百分比”变量最小为0对应空箱最大为100对应满箱填充方向选“自下而上”。运行起来就能看到水体高度跟着液位实时变化这是整个画面里最有视觉效果的部分组态王已经把这个功能封装好了不用自己写命令语言。进出水管道我用几条粗线条表示颜色变化做介质流动提示进水管道的水泵在运行时变成绿色停止时灰色。做法是在管线上加一个“线颜色”动画连接关联水泵运行状态变量值为1时绿色0时灰色。如果想让管道看起来有流动效果可以用几个连续的小色块组成管线再定义一个每秒加1的内存变量做轮播切换用隐藏/显示动画来实现“跑马灯”的效果。这个技巧比较讨巧但演示效果很好组态王里叫“隐含”动画连接。泵的图元可以直接用组态王自带的图库选一个水泵的图形做一个“隐含”动画关联Q0.0变量。值为1时显示0时隐藏这样运行画面里能看到泵是不是在转。液位数值显示用“模拟值输出”动画连接关联液位百分比变量显示字体调大一点现场看不清数值是最常见的问题之一。按钮部分启动按钮和停止按钮都是先放一个矩形或者椭圆双击后选“按下/弹起”动画连接在“弹起时”写一段命令语言\\本站点\\自动启动指令 1; \\本站点\\自动停止指令 0;停止按钮反过来\\本站点\\自动停止指令 1; \\本站点\\自动启动指令 0;“本站点”三个字是组态王的固定前缀刚上手的人经常漏写命令语言执行不了就报错变量名前要带完整路径。3.4 报警、趋势曲线和报表的配置报警功能是组态王的强项。数据词典里双击“液位百分比”变量进入报警属性页勾选“允许报警分析”然后设置四种报警条件高高限90%、高限80%、低限20%、低低限5%。报警等级可以设轻重缓急比如高高报和低低报设为“紧急”高报低报设为“一般”对应的报警提示颜色也可以区分红色表示紧急黄色表示一般。画面里放一个“报警窗口”控件组件里提供的报警窗可以实时显示当前所有报警包括报警时间、变量名、报警值、报警类型、确认状态。历史报警会保存在组态王自带的历史库里运行一段时间后可以按时间查询这个数据留下来后面做故障分析很有用。趋势曲线我放了两个一个实时趋势曲线显示过去一分钟内液位的变化用来观察泵启动后液位的上升斜率一个历史趋势曲线显示一个班次以上的液位走势。趋势曲线控件需要绑定数据词典变量曲线颜色分别设置为蓝色代表液位、红色代表设定值横轴时间刻度根据观察时长调整。PID调试的时候盯着趋势曲线看比看数值要直观得多超调、振荡、静差一目了然。报表方面我做了定时班报组态王里可以用内嵌的报表控件通过命令语言在每个整点写入当前液位值。不过这个水箱项目报表不是刚需我更多是把报表控件当作一个数据留痕手段方便验收时对比运行记录。如果不想做复杂报表组态王自带的运行日志也能满足基本需求。4. 联调实录我踩过的坑和排查方法4.1 组态王连不上PLC怎么办通信问题占掉了整个联调周期的一半时间这里把最常遇到的几种情况列出来。第一种是设备测试时接收计数完全不动。先从物理链路排查串口选对了没有USB转串口的驱动装好没有PPI电缆的波特率档位拨对了没有有些兼容PPI电缆上还有波特率选择拨码9600和187.5两档组态王这边设了9600电缆却拨在187.5当然是连不上的。第二种是通信时好时坏尤其是一打开STEP 7 Micro/WIN就断线。前面说过Micro/WIN和组态王抢同一个串口这是S7-200调试最常见的冲突。解决办法就是调程序时关掉组态王运行系统调完程序再开组态王两个软件不要同时在线。第三种是波特率不匹配。S7-200出厂默认PPI通信波特率是9.6kbps但有些二手PLC或者别人用过的主板系统块里被改成了187.5。这时候不知道的人怎么设置组态王都连不上。处理办法是用Micro/WIN才能正常连上PLC查看系统块里的通信参数把它改回9.6kbps重新下载或者在组态王里把波特率改成一致。顺带提一个环境兼容性问题安装老版本S7-200编程软件和组态王的电脑偶尔会出现关机变慢甚至无法关机的情况一般是老版本串口驱动或加密狗服务和系统冲突导致。如果遇到这种问题建议先退掉所有工控软件再关机或者把软件升级到新版补丁。这个不是PLC本身的故障但经常被误判为硬件问题。4.2 液位数值跳变、比例不对怎么查液位显示不对大概率不在通信而在信号链路和变量定义。先看传感器信号本身。最常见的现象是液位显示一直是0或者一直是满量程。用万用表串在变送器回路里量电流这招最直接。如果实际液位一半时电流应该有12mA左右但万用表量出来是0mA说明变送器没供电或者接线断了量出来一直是4mA不变说明变送器坏了或者导压管堵了量出来电流正常波动可PLC里数值不变那就要检查EM231模块的通道拨码和接线端子有没有松动。信号正常了再看PLC内部换算。AIW0的原始值可以通过组态王临时定义一个I/O整数变量读取先确认原始值在0到32000之间按液位变化。如果原始值对VD100显示不对那就是换算程序的问题重点检查是不是用了整数除法——在S7-200里整数除法的结果还是整数32000除以32000等于1再乘100液位值永远都是100这种低级错误我确实见过人犯过。变量定义这块再提醒一次组态王里访问VD100必须选I/O实数类型。如果定义成I/O整数看到的就是VD100低16位的数据数值完全是乱的而且随着地址偏移一位变化就跳变一次。这种问题有个明显特征液位上升时数值不是平滑变化而是一跳一跳的。4.3 PID参数整定的现场过程和波形评估我虽然主方案用的双位回差但还是把PID通道完整调了一遍。PID整定讲究“先比例、后积分、再微分”顺序不能乱。第一次把增益设为1积分微分都设0切换到自动模式。这时候液位会在设定值附近做等幅振荡振幅和增益成正比。增益太小液位爬升慢、到达设定值后稳住但是有静差增益太大液位像过山车一样来回冲超调明显。我现场的做法是每次把增益改变50%左右观察趋势曲线上的振荡情况找到那个“振荡剧烈但还在收敛”的边界值再取它的一半作为起步值。然后加积分。积分时间设置的数值越小积分作用越强。积分太强会加剧振荡太弱又消除不了静差。我在1分钟到2分钟之间尝试观察到液位最后能稳定在设定值附近就算合格。微分主要用来抑制超调但微分对噪声特别敏感液位信号如果有轻微波动微分输出会放大噪声。我最后选择的参数是增益1.8、积分时间50秒、微分时间0液位稳定在±1.5%以内对这个系统来说已经够用了。有一点心得PID参数整定这事教科书上给的是理论计算方法现场方便的还是“看曲线试凑”。组态王的趋势曲线在整定过程中价值很大每次改参数后跑三到五分钟看曲线形态再做下一步调整比盯着数字猜靠谱得多。4.4 现场干扰与设备保护的其他细节联调后期遇到一个很闹心的问题水泵一启动组态王上的液位数值就开始跳动。排查到最后是动力线对模拟量信号的电磁干扰。水泵接触器吸合和电机启动瞬间电流突变会在周围空间产生电磁干扰信号线如果没屏蔽或者和动力线走在同一个线槽里就会把干扰耦合进4-20mA信号回路。解决办法是三重防护一是信号线必须用屏蔽电缆屏蔽层单端接到PLC侧的接地端子不要两端都接地二是信号线单独走线槽和动力线保持20厘米以上的距离必须交叉的地方走90度垂直交叉三是给PLC和变送器分别用独立的24V开关电源。做完这三步之后液位数值纹丝不动干扰问题彻底解决。设备保护方面还有一个容易被忽略的点水泵在低液位停泵后不要立即允许再次启动否则泵在缺水状态下反复重启会造成机械损坏。我在程序里加了一个3分钟的延时模块低液位停泵后要等延时结束才能再次启动。这个保护逻辑后来在演示时被人为把水放空泵也确实没有出现干转的情况算是设计里值得保留的一笔。5. 项目复现的一些经验参考这项目做到最后我最大的体会是真正花时间的不是写梯形图而是联调和排障。硬件接线、通信参数、变量类型、量程换算、干扰处理每一个环节都是一个独立的“坑位”单独看都不难串在一起就考验综合能力了。给准备复现这个项目的朋友几条具体建议第一先画好I/O表和变量地址表再动手接线、写程序不要边写边想后面改地址很折磨人第二程序下载进PLC后先用Micro/WIN的监视功能看变量值确认PLC内部逻辑正确再让组态王介入通信这样调试时问题范围小一半第三整个工程PLC程序组态王工程文件接线图变量表一定要保留备份尤其是组态王的数据词典导出备份比重新配置省太多时间第四如果条件允许多在真实设备上跑一段时间再验收液位控制的长期稳定性比短时间跑通更能说明问题。整套系统我现在还会偶尔把液位启动值、停止值改成不同的组合来看泵动作的频率变化在组态王画面上同时开趋势曲线观察。双位回差和PID的区别、回差大小的工程意义在这套十几平米的小系统上体现得非常直观。以后要升级的话把泵换成变频器、给S7-200加一个以太网模块或者直接换成S7-200 SMART组态王侧改成S7-200 TCP驱动水泵转速就能连续调节液位可以控得更稳。这套底子打好了扩展方向很多。