接这个项目的时候,我第一反应是"用S7-300做全自动洗衣机,是不是有点大题小做"。真做完一遍才发现,市面上大多数简单洗衣机控制方案用的都是单片机或者继电器逻辑,而用S7-300这种工业级PLC来做,恰恰能把"顺序控制""步进状态机""组态监控"这些核心方法论从头到尾跑通一次。这篇就完整复盘一下我当时从硬件选型、I/O分配、梯形图编写到WinCC组态、现场调试的整个过程,以及踩过的那几个坑,适合正在做西门子S7-300课程设计、毕业设计,或者刚入门PLC想完整走一遍"程序+组态"项目的朋友参考。
1. 项目从哪来:S7-300做洗衣机控制台的需求与选型考量
先说这个项目到底要解决什么问题。全自动洗衣机听起来是个家用电器,但从自动化视角看,它本质上是一个典型的顺序控制对象:进水、洗涤、排水、脱水、漂洗、再脱水,整个流程是固定的工序序列,每个工序之间有明确的转移条件(水位到了没有、时间到了没有、门锁好了没有)。这不就是教科书级的"状态机"应用案例吗?
1.1 一条全自动洗衣机的工艺流程到底有多"典型"
全自动洗衣机的标准流程可以拆成下面这几个工序,你对照一下你家洗衣机就知道:
- 待机:检测门锁是否闭合、选择洗涤模式、按下启动。
- 进水:打开进水电磁阀,水流入桶内,直到水位达到设定高度(高/中/低三档可选),关闭进水阀。
- 洗涤:电机正转20秒、停5秒、反转20秒、停5秒,循环执行,同时累计洗涤总时间(比如标准洗15分钟,轻柔洗8分钟)。
- 排水:打开排水阀,桶内水位下降,低水位开关断开后,再继续排水30秒左右,确保排干。
- 脱水:关闭排水阀(或保持开启排残余水),电机高速单向旋转,利用离心力甩干衣物,持续60~120秒。
- 漂洗判断:脱水结束后,如果漂洗次数还没达到设定值(通常1~3次),就再次进入进水阶段,进行下一轮漂洗;全部漂洗完成后进入最终脱水。
- 结束:最终脱水完毕,所有执行器断电,蜂鸣器鸣叫提示用户取出衣物。
这个流程有两个特点,决定了它特别适合用PLC来做:第一是强顺序性,前一个工序不结束,后一个工序绝对不能开始;第二是有分支和循环,漂洗次数不同,流程路径完全不同。如果全用继电器互锁搭,线路会非常复杂,改一次流程就要改一堆物理接线。PLC的优势就在于把"逻辑"和"接线"解耦,流程调整只需要改程序,不用动一根线。
1.2 为什么不用S7-200 SMART或S7-1200,偏偏选S7-300
我知道很多人会问这个问题。S7-200 SMART便宜、小巧,S7-1200是新一代产品、博途平台也很好用,为什么还选S7-300这种"老将"?
我的看法是这样:S7-200 SMART的指令系统和编程习惯偏"迷你型",面向的是简单单机设备;S7-1200虽然强,但很多学校、培训机构、老的工业现场还在大量使用STEP 7平台维护S7-300产线。更关键的是,S7-300的模块化结构——电源模块、CPU模块、DI/DO模块分开选型、自由组合——能让你真正理解一个工业控制柜的构成逻辑,而不是买个一体化CPU插上就完事。S7-300在STEP 7里支持LAD、STL、FBD、SCL四种编程语言,特别是STL(语句表),对理解指令执行机制非常有帮助,这是S7-200 SMART和S7-1200(仅博途支持、无STL)给不了的。
当然,从性价比角度说,真实工业项目里没人会拿S7-300去控制一台洗衣机,这个项目更适合作为"教学方法"和"技能训练载体"。我在做这个项目时,就明确把它定位成"用工业级PLC实现一个完整的顺序控制系统,并配套上位机组态",而不是单纯追求"最便宜能洗衣服的方案"。明白了这一点,后面所有的设计决策就都顺理成章了。
2. 硬件清单与I/O地址表:先把洗衣机的"手脚口鼻"分配清楚
硬件选型是很多新手容易忽略的一步,总觉得"先写程序再说"。但实际项目里,I/O规划不清,程序写到一半发现少了一个输入点、输出点不够用,返工成本非常高。
2.1 硬件订货清单与冗余预留
我当时用的是一套比较典型的S7-300小系统配置,你可以直接照抄:
| 模块 | 型号参考 | 说明 |
|---|---|---|
| 电源模块 | PS 307 5A | 给CPU和模块供电,220V AC进,24V DC出 |
| CPU模块 | CPU 314C-2PN/DP | 自带14DI/10DO,集成了以太网和DP口,够用 |
| 数字量输入 | 使用CPU自带 + 扩展SM 321 DI16xDC24V(可选) | 如果输入点超过14个,加一块输入模块 |
| 数字量输出 | 使用CPU自带 | 10路DO,本案例约需6~8路,充足 |
| 组态触摸屏 | Siemens MP 277 或 KTP系列 | 10寸左右,跑WinCC flexible组态 |
需要强调一个原则:I/O点预留冗余。我实际规划了输入7点、输出7点,但CPU自带的14DI/10DO明显留了大量余量。为什么?因为现场调试时你总会遇到"哎呀,还得加一个紧急停止按钮""需要加一个门未关好的检测"这类需求。有一次我在现场就临时加了一个"溢水保护开关",因为用户担心进水阀卡死导致水漫金山。如果当初点数扣得太死,这种追加需求根本没法满足。
2.2 I/O地址表:一张表理清输入输出
完整的I/O地址分配表如下,这里就是全自动洗衣机的"手脚口鼻":
| 信号名称 | PLC地址 | 类型 | 信号来源/去向 | 说明 |
|---|---|---|---|---|
| 启动按钮 | I0.0 | 数字量输入 | 面板按钮,常开 | 按下有效 |
| 停止按钮 | I0.1 | 数字量输入 | 面板按钮,常闭 | 断开有效,优先最高 |
| 门锁到位开关 | I0.2 | 数字量输入 | 门锁微动开关 | 门关闭并锁紧后闭合 |
| 低水位开关 | I0.3 | 数字量输入 | 水位传感器 | 有水(达到低水位)时闭合 |
| 中水位开关 | I0.4 | 数字量输入 | 水位传感器 | 达到中水位时闭合 |
| 高水位开关 | I0.5 | 数字量输入 | 水位传感器 | 达到高水位时闭合 |
| 洗涤模式选择 | I0.6 | 数字量输入 | 面板旋钮开关 | 0=标准洗涤,1=轻柔洗涤 |
| 进水电磁阀 | Q0.0 | 数字量输出 | 经中间继电器KA1接入 | 闭合阀门开 |
| 排水电磁阀 | Q0.1 | 数字量输出 | 经中间继电器KA2接入 | 闭合阀门开 |
| 电机正转接触器 | Q0.2 | 数字量输出 | 接触器KM1控制电机正转 | 必须与Q0.3互锁 |
| 电机反转接触器 | Q0.3 | 数字量输出 | 接触器KM2控制电机反转 | 必须与Q0.2互锁 |
| 脱水高速接触器 | Q0.4 | 数字量输出 | 接触器KM3控制电机高速 | 与正反转互锁 |
| 蜂鸣器 | Q0.5 | 数字量输出 | 外接蜂鸣器 | 洗涤结束时鸣叫 |
| 运行指示灯 | Q0.6 | 数字量输出 | 面板指示灯 | 运行中常亮 |
这里有个细节值得新手注意:PLC的输出端子绝对不允许直接带220V的电磁阀和接触器线圈。S7-300的DO模块输出能力通常只有0.5A/点,而且直接驱动感性负载对模块冲击很大。正确做法是PLC DO点输出24V直流信号给中间继电器(线圈24V),中间继电器触点再去控制220V接触器线圈和电磁阀。实际上这是"弱电控制强电"的经典隔离逻辑,既有安全意义也有电气保护意义,我后面现场调试就是没注意这个烧过一只DO模块,教训深刻。
2.3 传感器选型与接线避坑
水位检测方式我比较推荐浮球式液位开关,原理简单、成本低、故障容易排查,缺点是只能给出"到/没到"的开关量,不能测连续液位。在这个项目里我们只需要低/中/高三个水位点,用三个浮球开关分别安装在不同的高度位置即可。电极式水位检测虽然也能用,但自来水导电性不稳定,电极长期浸泡容易结垢,误触发率明显高于浮球式。
接线方面有一个典型坑:浮球开关输出的是干接点(一组常开/常闭触点),PLC的DI模块需要一个24V DC信号。正确接法是:将24V正极接到浮球开关公共端,开关信号端接到PLC输入点,PLC输入点内部已经做了共地处理。千万不能用220V AC串进浮球开关再接PLC,轻则模块损坏,重则危险。PLC外部接线做之前,最好用万用表通断档逐个确认开关在"有水/无水"两种状态下的通断情况,因为浮球开关分常开型和常闭型,搞反了程序逻辑再怎么调都不对。
3. 梯形图核心逻辑:用步进控制把洗涤流程串成状态机
程序是整个项目的灵魂。我在编写时选择了步进顺序控制法(M位轮询),这是S7-300做流程类控制最经典、最稳健的写法,没有之一。
3.1 顺序控制的基本套路:M位轮询为什么好用
如果不用步进法,你会怎么写?大多数人第一反应是:用定时器T1控制进水,T2控制洗涤,T3控制排水……一堆定时器串联,再加互锁条件。这种写法在流程只有两三个工序时勉强能跑,一旦工序超过五六个,问题就全出来了:
- 一个定时器动作后,后续状态的保持条件很混乱;
- 中途按下停止再启动,状态没法恢复到正确位置;
- 排查故障时,你不知道洗衣机现在"卡在"哪个环节;
- 加一个工序或调整顺序,几乎要重写一遍逻辑。
步进法的核心思想是:把整个流程拆成若干独立步骤,每个步骤用一个内部位M来表示状态。比如M0.1=待机,M0.2=进水,M0.3=洗涤,M0.4=排水,M0.5=脱水,M0.6=漂洗……任何时刻只有一个M位为ON,就像一个接力棒永远握在一个人手里。某个步骤的"动作"只在该步M位为ON时执行;该步的"结束条件"满足后,复位当前M位、置位下一步M位。
为什么这样写最稳?因为每个状态都是独立的,状态之间的耦合被完全解耦了。调试时只要看哪个M位是1,就知道程序走到哪一步,这在工业现场排查故障时效率极高。这也是PLC顺序控制比继电器控制更能"结构化"的根本原因。
3.2 程序段逐段拆解:从待机到结束的完整流程
我用STL写了程序的核心段(STEP 7中也可以用LAD,看个人习惯),下面给一个简化但能说明逻辑的骨架:
// 状态初始化:按下停止或一上电,所有状态复位 A "停止按钮" // I0.1 常闭,断开时停止 O M0.0 // 或者用初始化脉冲 R M0.2 // 复位进水步 R M0.3 // 复位洗涤步 ... R M1.5 // 复位结束步 S M0.1 // 设置待机步 // 第1步:待机 -> 进水 A M0.1 // 当前在待机状态 A "启动按钮" // I0.0 按下 A "门锁到位开关" // I0.2 门已关好 = M2.0 // 启动有效标志 A M2.0 S M0.2 // 进入进水步 R M0.1 // 退出待机步 // 第2步:进水 A M0.2 // 当前在进水状态 = "进水电磁阀" // Q0.0 打开阀门 A "高水位开关" // I0.5 水位到达 S M0.3 // 进入洗涤步 R M0.2 // 退出进水步 ...这里有个小技巧,用M2.x做"瞬态辅助标志"而不是直接把条件写到S/R里,是为了让转移条件更容易复用和排查。
洗涤步的核心就是电机的正反转交替。我当时是用两个定时器配合自复位来实现20秒正转、5秒停、20秒反转的循环。在STEP 7里可以用一个脉冲定时器TP,也可以用经典的T1/T2互相触发:
// 洗涤循环:正转20s -> 停5s -> 反转20s -> 停5s -> 循环 A M0.3 // 洗涤状态下 A T2 // T2计时到(停止等待时间到) L SST#20S SE T1 // T1开始正转计时20秒 A T1 // T1计时未到(进行中) A "电机正转接触器" // Q0.2 = "电机正转接触器" // 当T1计时到,停止正转,开始5秒暂停 AN T1 A M0.3 L SST#5S SE T2注意:T1和T2在实际梯形图里要处理成互相置位/复位的关系,防止两个定时器同时计时导致正转反转同时输出。
至于洗涤总时间控制,不能直接用单个定时器从流程开始计时到流程结束,正确做法是用累加计时——洗涤状态M0.3每次进入时,累计一个"洗涤运行总时间",用计数器或累加寄存器实现。实际我用的是M0.3的上升沿触发一个秒脉冲,配合计数器C0累加,当累计值达到设定秒数时触发结束条件。
3.3 定时器与计数器的配合:漂洗次数怎么计数
漂洗流程是整个程序里最能体现"状态机价值"的部分。你设定漂洗2次,那么流程应该是:进水洗涤→排水→脱水→再进水洗涤→排水→脱水→最终脱水。如果单纯用"顺序下来",程序写起来会非常啰嗦,而用计数器+循环回跳就非常优雅。
我在程序里用一个计数器C1来记录已完成的漂洗次数。每完成一次"排水+脱水",就对C1加1;然后判断C1的当前值是否小于设定的目标漂洗次数。小于则跳回转去置位"进水步",否则进入"最终脱水步"。
// 漂洗计数逻辑 A M0.5 // 当前在脱水步已结束 CU C1 // 漂洗次数加1 // 取计数当前值,与设定值比较 A( L C1 L "漂洗次数设定" // 可以来自组态画面写入MW10 <I ) S M0.2 // 未达到目标,回到进水步 R M0.5 // 达到目标次数,进入最终脱水 A( L C1 L "漂洗次数设定" >=I ) S M0.6 R M0.5这一步的好处是,用户想改漂洗次数,根本不用改程序,只要在组态画面里把MW10的值改掉就行。这就是"参数与逻辑分离"的设计思想,也是PLC工程和简单单片机程序最大的区别。
3.4 互锁与安全保护逻辑:程序比硬件多一道防线
安全保护这块是洗衣机项目里最"工业"的地方,也是很多人写课程设计时最容易忽略的。我的建议是:程序里至少写四类保护。
第一,电机正反转硬互锁加软互锁。正转Q0.2和反转Q0.3在梯形图里必须用互锁触点串联,防止误操作同时输出。别以为现场有接触器机械互锁就万事大吉,程序层面的互锁是最后一道逻辑屏障,两个方面的保护都要有。
第二,脱水时必须强制要求门锁到位。脱水时电机高速运转,门锁不到位绝对不能启动脱水接触器。我在脱水步M0.5的启动条件里串联了I0.2门锁到位信号,同时加了一个逻辑:如果脱水过程中门锁信号消失,立即复位脱水输出并转入"安全停止"状态。
第三,进水超时保护。这是一个非常容易被忽略但极其重要的保护。如果进水阀打开后水位一直没到——可能是自来水龙头没开、水压不足、浮球开关故障——程序会一直停在进水步永远等下去。我在进水步加了一个超时定时器T10(比如5分钟),超时后不进入下一步,而是直接跳到"故障报警"分支,关闭进水阀,打开蜂鸣器,并在组态画面显示"进水超时"。排水超时同理,排水阀打开后低水位开关必须在3分钟内断开,否则说明排水管堵塞。
第四,排水完全性判断。我在排水步最后的"排干确认"里,设置了低水位I0.3断开后还要再排水30秒,这个时间去冗余处理能避免排水不彻底导致脱水时负载不均匀、洗衣机晃动严重。
这些保护逻辑单独每个都不难写,但组合起来,整个程序就从"会走流程"进化为"有安全意识地走流程"。这恰恰是工程程序和课本示例之间最大的分水岭。
4. 组态界面设计:从WinCC画面到变量通讯的落地细节
全自动洗衣机项目要做到"探秘"级,组态是另一半重点。没有上位机画面的PLC程序就像没有仪表盘的汽车——能跑,但你不知道它现在什么状态。
4.1 组态软件选择与通讯链路
S7-300的组态软件方案有两条路:如果只做触摸屏,用WinCC flexible 2008;如果要做到PC上,用WinCC V7.x。我做这个项目时用了WinCC flexible配合MP277触摸屏,原因很简单:画面组态方便、和STEP 7的变量对接直接、下载调试快。如果你用的是博途环境+S7-1200/1500,那就直接用WinCC Unified或者TIA WinCC,原理类似。
通讯链路方面,S7-300和触摸屏之间可以通过MPI、DP或以太网连接。我优先用了以太网PN口,理由非常现实:下载组态快、抗干扰能力强、布线简单。但要注意,S7-300在STEP 7硬件组态里必须给CPU分配好IP地址(比如192.168.0.1),触摸屏的IP设成同一网段(比如192.168.0.2),并且必须在WinCC flexible里正确设置PLC的通讯参数,包括机架号、槽号。很多初学者通讯不上,十有八九是槽号填错了。
4.2 画面结构与功能:一个能用的洗衣机监控界面长什么样
我的组态画面分了四页,每页解决一类问题:
第一页是主监控画面,也是最核心的画面。构图是洗衣机桶的剖面示意图,用"变色填充"方式表示当前水位,水位动态条根据高/中/低三个开关信号显示不同的填充高度;用"旋转动画"表示电机正在旋转,正转顺时针、反转逆时针;当前所处的工序(待机/进水/洗涤/排水/脱水/结束)用一组指示灯点亮,哪个工序进行中,对应灯就闪。这一步不是花哨,而是让操作员一眼就知道设备现在在干什么。
第二页是参数设置画面,放置洗涤时间、漂洗次数、脱水时间三个输入域。组态时我给每个I/O域设置了上下限(比如洗涤时间10~30分钟,漂洗次数0~5次),防止操作员误输入。为什么限制这么重要?因为如果漂洗次数填了50,洗衣机会洗一天一夜,用户可能以为是设备故障。
第三页是运行操作画面,放启动按钮、停止按钮、模式选择旋钮(标准/轻柔)、紧急停止按钮,并显示当前报警状态。启动按钮在组态里关联的是M20.0这个内部位,当操作员点击时,触摸屏置位M20.0,PLC检测到这个位上升沿后执行启动逻辑。这样做的目的是让触摸屏按钮和面板物理按钮可以并行控制,逻辑统一在一个入口。
第四页是报警画面,列出当前报警和最近的历史报警。报警组态在WinCC flexible里和PLC变量绑定,当PLC某个保护位(比如M3.0进水超时)为1时就触发对应报警文本。
4.3 变量连接、脚本与动画的踩坑细节
组态最繁琐、最容易出错的就是变量对应关系。我总结这几点经验:
- **位变量(I/Q/M)**直接映射,一一对应,最简单。
- 字变量要注意高低字节顺序。S7-300对16位字的存储是高位在前、低位在后(big-endian),WinCC组态变量时选"字"类型需要勾选正确的字节顺序,否则读出来的数字完全是乱的。
- DB块变量在WinCC里要指定"DB块号+偏移地址",偏移地址必须以字节为单位计算,别把位偏移和字节偏移搞混。
- 动画脚本用"变量状态"做旋转效果:比如电机旋转画面,可以用C脚本里按时间交替设置一个临时变量的值,让画面切到不同帧位图。也可以更简单:给动画加"可见性"变化,分别做三个状态帧轮流显示。
这里我要提一个常见的通讯冷启动问题:WinCC flexible组态完成下载后,触摸屏和PLC的通讯有时不能一开始就建立,尤其在PLC断电重启或程序停止时。解决方法是组态通讯参数里打开"重新建立连接"选项,并在PLC侧保证CPU处于RUN状态。如果触摸屏显示"连接中断",先检查网线物理连接,再查IP和子网掩码,最后查组态里的槽号,这三步顺序不能乱。
5. 仿真调试与现场踩坑实录:那些程序里看不见的坑
这个部分我放在最后,因为只有前面程序写完了、组态也连上了,才开始真正遇到"见真章"的问题。
5.1 用PLCSIM做离线仿真容易忽略的事
S7-300可以用STEP 7自带的PLCSIM仿真器做程序逻辑验证,不用真硬件就能跑。仿真能力很强,但有两个"看不见的坑":
第一,仿真时硬件的物理特性完全不存在。你没法真实模拟"进水阀漏电""接触器触点打火""浮球开关抖动",这些故障在现场才会暴露。PLCSIM只能验证逻辑正确性,验证不了"电气可靠性"。
第二,仿真变量强制容易掩盖逻辑错误。很多学生习惯用"变量强制表"直接把I0.0强制为1来模拟启动按钮按下,这样跑通了不代表真实接线也通。真实世界里,PLC读取的I点状态由外部开关决定,除非你程序里写了去抖滤波,否则开关抖动会直接传进PLC。我建议仿真时用定时器+随机干扰模拟开关抖动,看看你的程序会不会因为一个毛刺就从进水状态跳飞掉。相信我,大多数第一次写的程序都扛不住这个测试。
5.2 现场调试几个真实遭遇
第一个坑是正反转切换瞬间的电弧。我第一次上电测试,洗涤步在正转结束准备反转时,接触器KM1还没完全断开,KM2就吸合了,电柜里"噼啪"一声响,接触器触点都有熏黑痕迹。原因就是程序里正转定时器到点立即置位反转,完全没有预留接触器动作时间。修正方法很简单:正转停止后加一个2~3秒的"安全间隔区",这个时间段内两路输出都保持断开,然后再启动反转。那2~3秒其实是留给接触器的机械释放时间,不能省。这也是为什么我前面说"程序里的互锁只是逻辑保护,物理上还需要时间缓冲"。
第二个坑是浮球开关信号抖动。洗衣机进水时水花四溅,浮球开关在接近动作点时频繁通断,导致PLC信号在0和1之间快速跳变。我程序里的进水步条件是"高水位I0.5闭合后转入洗涤",结果水位还没真正到高水位,浮球因为水波抖了一下,PLC误以为到了,直接关进水阀开始洗涤。解决方案是在程序里给水位信号加了延时确认——连续500毫秒检测到闭合才认为有效。这个去抖时间不能太长,否则水位真的到了灵敏度又不够。
第三个坑是低水位开关的常开/常闭搞反。排水步的结束条件是"低水位开关断开表示排干"。我在设计图表里写了"达到低水位闭合",接线的师傅按这个逻辑接的。可实际调试时发现排水排了半天程序就是不往下走。拿万用表一量,发现那个型号的浮球开关在"无水"状态反而是闭合的,它标注的常开/常闭和你想的正好相反。所以任何传感器接线前都要自己量一遍,别太相信铭牌。
第四个坑是组态画面连不上PLC。我在实验室调试时WinCC一直提示"连接中断",查了IP没问题、PLC在RUN、网线也通,最后发现是STEP 7硬件组态里CPU的PN口的IP地址没有真正分配,只在组态界面显示了,没下载到CPU。在S7-300里,硬件组态修改后必须"下载到模块",否则CPU里的实际地址还是出厂值或者之前的老地址。这个步骤很多人漏掉。
5.3 这类项目的通用经验沉淀与调试顺序
做完这个"洗衣机项目",最大的收获不是学会洗衣服,而是把一套可复用的调试方法论沉淀了下来。我最后分享一个自己的调试习惯,顺序走完基本能把问题排查掉大半:
第一步,空载逻辑验证。不接任何电机和电磁阀,把PLC输出空着,用强制表逐个模拟传感器信号,走一遍完整流程。这一步的目的是确认程序逻辑链路没有短路或死锁。
第二步,带载点动测试。接上执行器,但不用全自动流程,用点动按钮单独测试每个输出通道:点一下正转按钮,电机转;点一下反转按钮,电机转;点一下进水阀输出,阀门打开。这一步确认接线正确、方向正确、电源等级正确。
第三步,低速空桶自动运行。桶里不放衣物,不脱水,只用轻柔模式跑短流程。这一步会暴露很多"逻辑与物理世界不匹配"的问题,比如切换时间不足、信号抖动、安全门锁误判。
第四步,重载全流程测试。放入衣物,标准水位,漂洗2次,完整跑一遍流程,时长、能耗、噪音、保护动作逐一记录。
按这个顺序,绝大多数问题会在前两步就暴露,不会把"逻辑错误"和"接线错误"两个因素混在一起,排查起来轻松得多。我见过太多人一上来就全自动跑,结果程序问题+接线问题+组态问题一起爆发,一个下午都找不出原因。
最后说一句实在的:PLC这门手艺,程序能看懂是一回事,能稳定跑起来是另一回事。S7-300这个平台虽然老,但它要求你养成模块化、结构化、严谨验证的习惯,这些东西放到任何一代PLC上都不过时。希望这篇复盘对你正在做的洗衣机控制项目有帮助,哪怕只避开我踩过的某一个坑,也算值了。