把一台西门子S7-300请进洗衣机控制柜,懂行的人第一反应可能是"杀鸡用牛刀"。但恰恰是这个看似大材小用的组合,把工业控制里最核心的几件事全串起来了:I/O规划、状态机编程、模拟量采集、电机互锁逻辑,再到HMI组态和模拟调试。整套流程跑通之后,你收获的不只是一台"能洗衣服的PLC",而是一套可以直接迁移到搅拌站、包装线、小型水处理站的控制系统设计思路。
这篇文章我按自己做项目时的习惯来写:先拆动作流程和I/O点,再讲硬件选型和STEP7组态,然后是核心程序的状态机实现,最后是WinCC flexible画面组态和调试排错。全程不会绕弯子,只讲真刀真枪能落地的内容。无论你是刚接触PLC的电气小白,还是想系统梳理S7-300项目流程的工控人,都能在里面找到有用的东西。
1. 洗衣机动作流程拆解:先把"洗衣服"翻译成I/O信号
1.1 全自动洗衣机的标准运行流程
写PLC程序最忌讳的一件事,就是一上来就铺梯形图。S7-300再聪明,它也不知道什么叫"洗得干净",它只认0和1、认模拟量数值。所以第一步必须把洗衣服的物理过程拆成一个可以顺序执行的流程图。
家用全自动洗衣机一般走这样一套流程:
- 待机状态:门锁闭合,程序选择完毕,按下启动按钮。
- 进水阶段:进水电磁阀打开,水位从低到高。洗涤水位到达后关闭进水阀。
- 洗涤阶段:波轮或滚筒电机交替正转、暂停、反转,持续设定时间。洗涤过程中若水位偏低,自动补水。
- 排水阶段:排水阀打开,水位降到低位,排水泵或排水阀保持工作一段时间,确保水排空。
- 脱水阶段:门锁保持锁死,电机高速单向旋转,持续设定时间。脱水过程中若震动或门锁异常,立即停止。
- 漂洗阶段:重复进水、搅动、排水,一般两到三次。
- 最终脱水:高速脱水,时间比中间脱水长。
- 结束阶段:断开输出,蜂鸣器鸣叫若干声,门锁解锁。
这看起来很简单,但对PLC来说,每一步都对应着明确的I/O状态变化和时序约束。比如进水阶段,PLC要不停地检测水位开关;洗涤阶段要判断"正转时间到没到""停止时间到没到",这些全要落到定时器上。
1.2 输入点与输出点的完整清单
我见过很多初学者在画梯形图之前完全没列过I/O表,最后接线和程序对不上,查错查到怀疑人生。所以先把I/O点老老实实列出来,这是整个项目的骨架。
输入信号:
| 序号 | 信号名称 | 地址 | 信号类型 | 说明 |
|---|---|---|---|---|
| 1 | 启动按钮 | I0.0 | 数字量 | 常开点,按下时闭合 |
| 2 | 停止按钮 | I0.1 | 数字量 | 常闭点,急停场景时断开 |
| 3 | 门开关 | I0.2 | 数字量 | 门到位后闭合 |
| 4 | 门锁反馈 | I0.3 | 数字量 | 门锁吸合后闭合 |
| 5 | 低水位开关 | I0.4 | 数字量 | 水位低于低水位时闭合 |
| 6 | 高水位开关 | I0.5 | 数字量 | 水位到达洗涤水位时闭合 |
| 7 | 程序选择旋钮 | I1.0-I1.2 | 数字量 | 3位拨码,选择标准/快洗/单脱水 |
| 8 | 水温传感器 | IW8 | 模拟量 | PT100经SM331接入 |
输出信号:
| 序号 | 信号名称 | 地址 | 信号类型 | 说明 |
|---|---|---|---|---|
| 1 | 进水电磁阀 | Q0.0 | 数字量 | 得电开阀 |
| 2 | 排水电磁阀 | Q0.1 | 数字量 | 得电排水 |
| 3 | 洗涤电机正转接触器 | Q0.2 | 数字量 | 驱动KM1 |
| 4 | 洗涤电机反转接触器 | Q0.3 | 数字量 | 驱动KM2 |
| 5 | 脱水接触器 | Q0.4 | 数字量 | 驱动KM3,高速运转 |
| 6 | 门锁电磁铁 | Q0.5 | 数字量 | 得电锁门 |
| 7 | 蜂鸣器 | Q0.6 | 数字量 | 报警/结束提示 |
| 8 | 加热器 | Q0.7 | 数字量 | 加热洗涤用水 |
这里有个容易被忽略的细节:水位开关和门开关的常开常闭逻辑。实际设备中,水位开关多数是干簧管或压力开关,安装位置决定了它是"水位到达时闭合"还是"水位到达时断开"。我建议在I/O表里就把逻辑状态写死,后面编程时全部按"当前状态为1代表已到达"来统一处理,否则程序里到处取反,调试时自己都能绕晕。
1.3 模拟量那块:水温采集如何接入S7-300
如果洗衣机带加热洗涤功能,就要用到模拟量。S7-300本身不带模拟量通道,需要扩展一块SM331模拟量输入模块。这里选PT100热电阻配上SM331的AI模块比较常规,量程直接组态成-50℃到150℃即可。
组态时要注意SM331的模块地址。很多老手习惯把SM331放在机架的第三个槽位,地址默认从IW8开始。接PT100时,模块上需要做相应的接线配置,2线制、3线制、4线制都要按端子图来。测温精度要求不高,用3线制最稳妥,既便宜又能抵消导线电阻。
程序里读取温度,Step7自带库函数可以直接把IW8的原始值转换为浮点数温度值,也可以用FC105(SCALE)配合FC106(UNSCALE)。不过对洗衣机这种场景,我更推荐直接读原始值然后做线性换算:
温度值 = 原始值 × 0.1(℃)
因为SM331在PT100模式下默认的分辨率就是0.1℃/bit,不需要绕一圈做工程量转换。但要注意,模拟量模块的通道诊断要打开。万一探头断线,模块会报错,程序里要能识别出"温度异常",直接停止加热,否则干烧就出大事故了。
2. 硬件选型与STEP7组态:S7-300在这套项目里的正确定位
2.1 为什么选S7-300而不是200 SMART或者1200
我知道肯定有人会说,现在这个项目用200 SMART或者1200更香,性价比高、体积小、博途编程也方便。这话没毛病。但如果你现在的目标是"系统性学习工控项目的完整设计方法",S7-300搭配STEP7 V5.5依然是很多老产线、旧设备的真实环境。我在维护过的工厂里,S7-300的存量设备少说还有个几千台,学会它绝对不是学了个寂寞。
具体到配置,我推荐CPU 313C-2 DP:
- 自带16DI/16DO,洗衣机这点I/O点绰绰有余,不需要再扩数字量模块。
- 集成MPI接口,连接HMI和编程器都方便。
- 也支持DP总线,以后想扩展远程IO或者挂变频器,都不用换CPU。
- 程序容量足够,状态机加上注释,写满也就用掉一小半。
电源用PS307 5A,机架用DIN导轨,不需要扩展机架。整个配置非常紧凑,对学习项目也友好——搬运方便,教室、家里的实验台都放得下。
2.2 STEP7组态的常见坑
组态这东西,看起来就是点几个选项,但实际动手时坑不少。我把经常踩的几个点列出来:
第一,机架槽位不能乱插。S7-300的CPU在槽2,电源不算槽位,槽3插接口模块或者空着,数字量模块从槽4开始放。如果顺序错了,组态校验直接报错。很多人把SM331插到槽3,然后怎么下载都不成功,就是没搞清楚槽位规则。
第二,MPI地址别冲突。编程器、触摸屏、CPU三者的MPI地址要错开。CPU通常设2,HMI设1,编程器设0。如果都是默认地址,在线时就会提示"无法建立连接"。我见过不止一次现场调试调了半天,最后发现是MPI地址撞车了。
第三,模拟量模块的量程卡要对应。SM331的侧边有个小量程卡,组态里选PT100,硬件上的量程卡也要拨到对应的电阻挡位。这个位置很容易被忽略,一旦组态和硬件不一致,模块诊断会闪红灯,读上来的值要么是满量程要么是负数。
组态完成后记得做一次完整的编译保存,然后下载到PLC。这一步没报错,硬件层面的工作就算稳了。
2.3 硬件接线时的防干扰细节
洗衣机的控制柜里,变频器或者电机接触器都是强干扰源,而PLC是弱电器件,两者在柜内布局和接线时需要特别注意。
- 动力线和信号线分开走线槽,至少间隔20厘米。
- 接触器线圈两端并联阻容吸收元件,防止断电瞬间的浪涌电压击穿PLC输出点。
- 开关量输入公共端接DC24V的正极,传感器用三线制接法。
- 所有接近开关、水位开关的屏蔽线单端接地,避免形成地环路。
这几点看着基础,但直接影响到能不能稳定运行。我之前调一套设备,洗衣机一起电机,CPU就报SF红灯,后来查出来就是动力电缆和信号线捆在同一个线槽里,把信号干扰得一塌糊涂。
3. 核心程序实现:状态机驱动,而不是一堆定时器乱飞
3.1 状态机编程思路
洗涤程序最大的特点是"顺序性强、互斥性强"。进水的时候不能排水,正转的时候不能反转,脱水的过程中门锁必须闭合。如果程序用一堆定时器加自锁互锁硬凑,逻辑能画出来,但改一个参数就牵一发动全身。
我采用的方案是经典的状态机模型。把整个洗涤过程拆成独立状态,每个状态对应一组输出和一个转移条件。程序主循环里只做两件事:判断当前处于哪个状态,执行该状态下的输出;判断转移条件是否满足,满足就切到下一状态。
这种做法最大的好处是可读性极强。无论是自己三个月后来维护,还是同事接手,打开程序一眼就能明白现在程序跑到哪一步、为什么停在这里。对工业项目来说,易维护比炫技重要得多。
3.2 状态定义与转移条件设计
针对洗衣机这个项目,我定义了以下状态字和状态编号:
| 状态编号 | 状态名称 | 状态含义 |
|---|---|---|
| 0 | 待机 | 等待启动 |
| 1 | 进水洗涤水位 | 进水到高水位 |
| 2 | 洗涤 | 正反转交替 |
| 3 | 排水 | 排出洗涤水 |
| 4 | 中间脱水 | 低速离心脱水 |
| 5 | 漂洗进水 | 重新进清水 |
| 6 | 漂洗搅动 | 正反转搅动 |
| 7 | 漂洗排水 | 排出漂洗水 |
| 8 | 最终脱水 | 高速脱水 |
| 9 | 结束 | 蜂鸣提示,门锁解锁 |
状态字用M10.0到M10.7这8个位外加一个M11.0来编码。转移条件设计如下:
- 待机切换到进水:启动按钮按下且门锁闭合且水位不在高水位。
- 进水切换到洗涤:高水位开关动作且门锁保持闭合。
- 洗涤切换到排水:洗涤时间到,这里用定时器T1累积正转时间、T2累积反转时间、T3累积总洗涤时间。
- 排水切换到脱水:低水位开关动作,且排水阀继续开3秒确保排空。
- 脱水切换到漂洗进水:脱水时间到,且门锁保持闭合。
- 漂洗进水切换到搅动:高水位到达。
- 搅动切换到排水:漂洗时间到。
- 排水切换到最终脱水:低水位到达且排空延时完成。
- 最终脱水切换到结束:脱水时间到。
- 结束切换到待机:蜂鸣3次后自动复位,或按停止键复位。
这里我特意把"水位开关触发后还要延时"这类细节写进去,是因为实际使用中,水位开关在水面晃动时会有抖动,排水管里也常有残留水。如果水位一到就立刻切状态,脱水时可能带上半罐水,电机过载跳闸。
3.3 关键梯形图逻辑:以进水状态和电机互锁为例
下面是一段进水状态的核心梯形图参考(用指令表形式展示,方便跨平台阅读):
// 状态1:进水 A M0.0 // 当前状态为进水状态 A I0.5 // 高水位未到达 S Q0.0 // 置位进水电磁阀 A M0.0 AN I0.5 // 高水位到达 R Q0.0 // 复位进水电磁阀这里用置位/复位指令而不是简单输出,是为了避免"扫描周期中间状态被覆盖"的问题。如果直接写A M0.0 AN I0.5 = Q0.0,当高水位到达的瞬间,Q0.0会被复位,但如果下一个扫描周期状态已经切换到洗涤,而洗涤状态里没有对Q0.0做处理,Q0.0就保持0,没问题。但用置位复位更明确,谁触发的谁负责复位,逻辑不容易漂移。
电机正反转是洗衣机程序里最关键的互锁逻辑。正转接触器和反转接触器绝对不能同时吸合,否则就是相间短路。梯形图层面,我做了三道防线:
- 第一道:正转启动条件里串联反转接触器的常闭触点,反转同理。
- 第二道:程序里用中间变量M12.0表示正转中,M12.1表示反转中,两个变量不能同时为1。
- 第三道:电机切换方向时,插入2秒停止时间,让电机完全停稳再反向启动。
最后这道防线特别重要。波轮电机直接正反转切换瞬间电流很大,对接触器和电机都是冲击,皮带上还容易打滑。所以洗涤模式都是"正转5秒-停2秒-反转5秒-停2秒"这个节奏,这2秒停止时间就是给反向冲击做的缓冲。
3.4 温度和加热控制逻辑
如果项目带加热功能,温度控制可以用简单的滞回控制。设定目标温度40℃,滞回区间±3℃。程序逻辑:
- 温度低于37℃时,接通加热器输出。
- 温度高于43℃时,断开加热器输出。
- 温度采集异常或超过60℃,无条件断开加热器并报警。
用FC105转换温度值时,要注意输入端的IW地址必须和硬件组态里一致。我记得有一次把IW8写成了IW10,结果程序怎么调,温度值都乱跳,查了半天才发现地址错位了。这个坑我在现场踩过一次之后就长记性了:程序里的模拟量地址必须和STEP7硬件组态页面核对三遍。
3.5 程序块结构规划
洗衣机的程序虽然小,但我也按工程化方式分了块:
- OB1:主循环,调用各功能块。
- FC1:状态机主逻辑,包含状态转移和输出控制。
- FC2:时间控制,统一管理洗涤时间、漂洗次数等参数。
- FC3:报警处理,包括门锁异常、水位异常、温度异常。
- FB1:电机控制,封装正转、反转、停止子逻辑,带互锁。
- DB1:共享数据块,存放洗涤时间、漂洗次数、状态字等变量。
把报警单独做成FC是我个人很坚持的习惯。洗衣机的控制逻辑再简单,报警也不能混在正常流程里东一个西一个。报警FC集中处理的好处是,现场出问题后在程序里搜"ALARM",所有报警点一目了然。
4. HMI组态设计:操作员要的是"看得懂、点得动、报得清"
4.1 页面架构与流程规划
洗衣机配的HMI不需要多复杂,但页面逻辑要清楚。我用WinCC flexible给这台洗衣机做了一个TP700触摸屏的画面,整体分成四个页面:
- 主页:设备总览,包括当前状态、运行模式、启动/停止按钮。
- 参数页:洗涤时间、漂洗次数、目标水温、脱水时间。
- 报警页:当前报警和最近报警记录。
- 手动页:调试用手动操作,每个输出独立按钮,带密码保护。
主页是整个HMI的核心。状态显示我做了两种方式:一是用一个文本域显示当前状态名称,比如"进水""洗涤""脱水";二是用一个状态动画图,画面里画一个洗衣机的剖面简图,进水时蓝色填充区域上升,洗涤时滚筒图标转动,排水时填充区域下降。这种动画看起来高级,其实就是用变量控制的"可见性"和"旋转角度"属性,WinCC flexible里都能直接绑定PLC变量。
4.2 变量连接与画面属性绑定
组态时最容易翻车的环节是变量地址连接。触摸屏里的每个按钮、每个显示控件,都要在"变量表"里绑定PLC地址。我建议变量命名方式和PLC符号名保持一致,比如"Start_Button"对应PLC里的M20.0,"Water_Level_High"对应I0.5。
这里有个重要的细节:如果PLC程序里启用了符号名,变量表里直接选符号名连接,系统会自动把绝对地址填进去。但如果PLC程序里改了符号名对应的位、字节地址,HMI里也要同步更新,否则按钮按了没反应。我在项目里一般是把所有需要HMI访问的变量集中在DB1里,绝对地址固定,这样PLC程序改动不会影响HMI连接。
按钮的"按下"事件和"释放"事件也有讲究。启动按钮我建议用"按下"事件置位M20.0,"释放"事件不复位,由PLC程序在结束状态或停止状态下复位。这样保证操作员按一下按钮,PLC有足够的扫描周期捕捉到这个启动信号。
4.3 参数输入的画面保护
参数页容易被忽略,但它直接关系到设备安全。洗涤时间设成负数、漂洗次数设成0、目标水温设成90℃——操作员误操作都可能让设备异常。我的做法是:
- 输入框的上下限属性里卡死范围:洗涤时间0到30分钟,漂洗次数1到5次,水温20到60℃。
- 控制面板里做二次确认弹窗,写入参数后弹窗提示"确认修改参数?是/否"。
- 手动页设置密码保护,只有权限等级够的技术人员才能进入。
WinCC flexible里这些功能都有现成控件,关键是你要有意识地"层层设防"。很多小项目根本不设限制,最后操作员乱点,设备出故障了又来怪程序写得不行。做HMI一定要记住:操作员也是人,会疲劳、会误触、会有好奇心,你的画面设计要把这些情况都考虑进去。
5. 模拟运行与现场调试:PLCSIM救急,但替代不了真实信号
5.1 用PLCSIM做逻辑验证
写好的程序不能直接往设备上怼。我习惯先用PLCSIM把逻辑跑一遍。STEP7自带的PLCSIM可以在电脑里模拟出一个虚拟CPU,程序下载进去后,你可以手动强制输入信号,模拟水位开关动作、按钮按下等。
针对洗衣机项目,模拟验证我主要做这几件事:
- 验证启动条件:门没关、水位异常时按启动,状态机不应跳转到进水。
- 验证状态转移:逐一强制I0.4、I0.5的值,观察状态字和输出是否按预期切换。
- 验证互锁逻辑:强制输出条件,观察正转和反转接触器是否出现同时为1的时刻。
- 验证报警路径:强制门锁反馈丢失,观察是否进入报警状态并断开全部输出。
PLCSIM好用的地方在于它能变速运行。一个15分钟的洗涤流程,我可以在模拟环境里把定时器时间临时改成几秒钟跑完整个状态流,确认每个转移节点逻辑都对。这里要提醒一下:PLCSIM的定时器是真实速度的,你不能模拟快进,所以偷懒的办法是把时间参数临时改小,跑完再改回来。
5.2 现场调试最容易翻车的三个瞬间
模拟通过只能说明程序逻辑自洽,真实设备上还有很多机械和电气层面的变量。我总结现场调试最常见的三个问题:
第一个,水位开关抖动导致状态乱跳。静止水面的开关很稳,但洗涤时水面震荡起伏,水位开关时通时断。如果程序里不加延时滤波,会出现洗涤进行到一半突然又返回进水状态的情况。解决办法是在水位检测程序里加上500毫秒的稳定延时:信号持续500毫秒才判定有效。
第二个,接触器实吸合和程序状态不同步。程序已经给了正转输出,但实际接触器因为线圈电压不足或者机械卡滞没有吸合。这种问题程序自己发现不了,只能靠电流钳测电流或者在接触器辅助触点上接反馈信号。正规项目里电机电流、接触器反馈都要接回PLC,不能只靠输出点判断设备状态。
第三个,脱水时震动触发门锁保护。洗衣机高速脱水时整机震动,门开关如果安装位置有轻微位移,就会瞬间断开,程序以为是开门直接急停。这在厂里测试不明显,一到现场靠墙摆放或者地面不平时就频繁触发。后来我在门开关检测上增加了2秒的持续断开确认,短于2秒的误触发直接忽略。
5.3 调试时的看表技巧
现场调试不能光靠肉眼看设备转不转,我一般借助STEP7的"变量表"功能,把关键变量实时显示出来。洗衣机项目我会在变量表里放这些变量:
- 当前状态字 MW10
- 进水阀、排水阀、正转、反转、脱水的输出位
- 高水位、低水位、门锁三个输入信号
- 当前水温数值
- 洗涤时间剩余值
变量表可以批量监控和修改,尤其是调试状态机时,强制一个输入位、观察状态字变化,速度远快于在程序里断点。这里有个实用技巧:MW10以十六进制显示,每次状态变化直接看十六进制值就知道跳到哪个状态了,比盯着一排布尔量轻松得多。
调试结束后,别忘了把变量表里强制的信号全部取消,把临时修改的参数恢复到正常值。我给这套程序加了一个"调试模式"接口,调试时置位M99.0,程序允许手动单步跳转状态;调试完复位M99.0,设备回到全自动模式。这样就不怕忘记恢复参数了。
写在最后的小经验
整套S7-300洗衣机项目做下来,最深的体会是:控制逻辑本身并不复杂,复杂的是你怎么把一个物理过程抽象成可靠的状态机,再把状态机落到一个又一个细致的工程细节上。水位开关的抖动、接触器的互锁、HMI地址的对应,这些单独拿出来都不难,合在一起就考验系统性思维了。
如果你也想复刻这个项目,我建议不要直接抄整套程序。先自己把I/O表列一遍,把状态转移图画一遍,然后试着只写进水、洗涤、排水这三个状态。跑通之后再慢慢加漂洗和脱水。这样练出来的手感,比一次性写完整套程序扎实得多。S7-300再"老旧",它背后的编程思维和方法论,放到1200、1500甚至其他品牌PLC上照样通用。