立体车库这类题目,是自动化控制系统里特别“练人”的一种:硬件不多,逻辑不少,既要管传感器信号,又要做上位机监控,最后还得让动作序列一次不差地跑完。我手头这套九车位双两层立体车库的仿真工程,上位机用的是组态王6.55,下位机控制由S7-300 PLC承担,系统跑起来以后,9个车位的存取动作、状态监控、动画演示都能在同一套环境里完成。这篇文章从方案设定、控制逻辑、画面设计、仿真联调四个部分完整拆开,如果你正好在做类似的课程设计、实训课题,或者想自己搭一套两层车库的控制模型,可以直接照着这个思路复现。
1. 方案设定:九车位的“双两层”怎么排,通信架构又怎么搭
1.1 为什么采用“下5上4”的升降横移式
很多人拿到“九车位双两层”第一反应是:九辆车到底怎么摆?是两列并排,还是一列到底?我在这套工程里的落地方式是升降横移式里最经典的“下5上4”:上层4块载车板,底层5块载车板,总共9块板位。上层载车板在侧视图中正好落在底层几个位置的上方,上下投影基本对齐,这样每个上层车位到底能不能下降、该往哪个方向腾挪,逻辑就非常直接。
必须说明的是,升降横移式车库不能把9块板全部占满。底层5块板中始终要保留一个动态空位,这个空位不是固定车位,而是一块可移动的空载车板。上层载车板要降到地面,它的正下方必须腾空;底层某个车位要让位时,也是把车板横移到这个空位上。所以系统实际可同时存放的车辆数是8辆,但控制对象、检测点位、组态王画面都按9块板位来设计。工程上叫它“九车位”没问题,你自己清楚这个空位机制就行。
我把“双两层”理解为两层车架加两套核心执行机构——升降动作和横移动作。这也是升降横移式车库的关键特征:上层板只升降,底层板只横移,各司其职。这样拆解以后,控制任务就非常清晰:任何时候都只有一个动作在发生,要么横移,要么升降。
1.2 从车位到信号:硬件拓扑与角色分工
系统的硬件拓扑分三层:
| 层级 | 主要设备 | 职责 |
|---|---|---|
| 监控层 | 组态王6.55运行系统,工控机/PC | 画面监控、按钮下发、状态显示、报警记录 |
| 控制层 | S7-300 PLC,CPU 315-2DP,配数字量输入输出模块 | 逻辑运算、顺序控制、互锁保护、与上位机通信 |
| 执行与检测层 | 底层横移电机、上层升降电机、限位开关、光电传感器、指示灯 | 移动载车板、检测车位状态、反馈到位信号 |
S7-300不是新机型了,但存量项目非常多,用它做立体车库逻辑非常适合教学和实训。我常用CPU 315-2DP加一块SM321数字量输入模块、一块SM322数字量输出模块,点位数量对9车位来说刚好够用。执行层我采用“每个板位配备独立电机”的模型:底层5台横移电机,上层4台升降电机,每台电机都需要正反转控制点。这样点位清楚,逻辑写起来不会绕。
传感器方面,每个板位都装一个光电检测开关,用来判断该板位有没有车;每个动作方向装限位开关,作为横移/升降到位反馈;再加急停按钮、超时保护。这些信号全部进PLC的数字量输入端,组态王不直接读传感器,只和PLC交换变量。这个分层设计是整套系统的根本:上位机不越权处理现场信号,所有联锁判断都在PLC侧完成。
1.3 仿真环境的定位:先想清楚“仿真”到哪一层
做这类课题最容易踩的第一个坑,是没搞明白自己到底在仿真什么。这套工程里实际包含三层仿真:
- PLC逻辑仿真:用Step7把程序下载到PLCSIM,验证S7-300的梯形图和状态机是否正确;
- 上位机画面仿真:组态王运行系统里跑画面,用变量变化演示车库动作;
- 数据联调仿真:让组态王和PLC仿真器真正交换数据,这层最麻烦,我在后面专门讲。
我的做法是先把第一层做到完全可靠,再逐步往上加联调。如果你一上来就指望PLCSIM和组态王自动连上,多半会卡在通信问题上半天。先把“哪个传感器到位了”“下一步该启动哪台电机”这种核心逻辑在PLC侧验证完,后面的画面和通信问题都有了排查基础。
2. S7-300控制逻辑:I/O分配、互锁与空位腾挪算法
2.1 I/O分配表:每块载车板一个电机的思路
这版工程的I/O分配大致如下,实际接线时点位可以微调,但结构保持一致:
| 地址范围 | 类型 | 用途 |
|---|---|---|
| I0.0 ~ I0.4 | 输入 | 底层5个板位“有车检测”光电信号 |
| I0.5 ~ I1.0 | 输入 | 上层4个板位“有车检测”光电信号 |
| I1.1 ~ I1.5 | 输入 | 底层5台横移电机“左到位”限位反馈 |
| I1.6 ~ I2.0 | 输入 | 底层5台横移电机“右到位”限位反馈 |
| I2.1 ~ I2.4 | 输入 | 上层4台升降电机“上升到位”反馈 |
| I2.5 ~ I3.0 | 输入 | 上层4台升降电机“下降到位”反馈 |
| I3.1 | 输入 | 急停按钮 |
| I3.2 | 输入 | 存车请求按钮(冗余操作) |
| I3.3 | 输入 | 取车请求按钮(冗余操作) |
| Q4.0 ~ Q4.4 | 输出 | 底层横移电机正转 |
| Q4.5 ~ Q4.9 | 输出 | 底层横移电机反转 |
| Q5.0 ~ Q5.3 | 输出 | 上层升降电机正转(下降) |
| Q5.4 ~ Q5.7 | 输出 | 上层升降电机反转(上升) |
| Q6.0 | 输出 | 运行指示灯 |
| Q6.1 | 输出 | 故障蜂鸣器 |
电机正反转分开控制的好处是互锁点非常明确:Q4.0和Q4.5是一对,不能同时为1;Q5.0和Q5.4是一对,同样不能同时为1。如果采用单输出点控制方向,反而要在程序里做大量方向判断。
2.2 存取车动作的步进状态机
S7-300的梯形图程序如果全部用起保停电路堆,一旦动作分支多了就会乱成一团。我建议把整个存取车过程写成步进状态机,用“当前步号”作为核心变量。比如定义一个字变量STEP,取值范围0~5:
| STEP | 含义 | 进入下一步的条件 |
|---|---|---|
| 0 | 空闲待机 | 收到存车或取车指令 |
| 1 | 横移腾空 | 目标底层位已变成空位,且横移电机全部停止 |
| 2 | 升降下降 | 上层板下降到位信号有效 |
| 3 | 等待车辆进出 | 存车时检测到有车;取车时检测到无车 |
| 4 | 升降上升复位 | 上层板上升到位信号有效 |
| 5 | 数据记录与复位 | 组态王读取完成,手动或自动回STEP 0 |
这里最关键的一点是:每个状态的转移条件必须以上一步的真实反馈为准,不能靠延时拍脑袋。我在实际调试中见过很多程序用几个定时器串起来,看起来能跑,但一旦电机卡一下、传感器抖动,整个序列就错位。步进状态机配合到位传感器,才能保证“上一步没完成,下一步绝不动作”。
2.3 空位腾挪:把“车板搬家”变成有序的横移序列
这是整个PLC程序里最有技术含量的一块。场景是这样的:假设底层5个板位编号P1到P5,当前空位在P5,而上层3号车位的正下方是P2。如果P2上有车,你必须把P2腾空。问题来了,你不能直接让P2上的车横移到P5——中间隔着P3和P4,路径被堵住了。
正确做法是:让空位逐步向目标位置移动。过程如下:
- P4板横移到P5空位,此时P4变成空位;
- P3板横移到P4空位,此时P3变成空位;
- P2板横移到P3空位,此时P2变成空位。
三步之后,目标位置P2空出,上层板才能下降。整个操作规律可以总结为一句伪代码:
WHILE 目标位置下方 != 空位: 从空位位置向目标位置方向,找到相邻的第一个有车位 令该车板横移到空位 更新空位编号 ENDWHILE把这个循环用梯形图实现时,不需要写得很复杂。因为底层只有5个位置,你可以用一组M线圈记录空位在哪,然后用比较指令判断目标位和空位的关系,逐级触发对应的横移电机。比如空位在P5、目标在P2时,直接按“P4到P5、P3到P4、P2到P3”的顺序依次发动作指令,每个动作都等待到位反馈后再发下一个。
这里特别需要注意的是横移方向。P4移到P5,其实只需要把P4的横移电机向P5方向启动;P2移到P3,同样按照左右位置关系决定正转还是反转。程序里我给每块板定义了一个“当前位置”寄存器,用0和1表示左右相邻位置,横移方向通过当前位置与目标位置的比较自动判断。
2.4 防故障的互锁细节:双电机同时动作的隐患
立体车库控制里,“互锁”比“动作”更重要。第一个坑是正反转互锁。Q4.0(M1正转)和Q4.5(M1反转)如果在程序里条件差不多,很容易因为扫描顺序问题同时输出,导致电机短路或机械卡死。我习惯在每个输出网络前面固定串联对方常闭触点,也就是梯形图里最简单可靠的硬件式软互锁。
第二个坑是升降和横移的互斥。从空位腾挪到升降下降之间,必须保证所有横移电机已经断电。我的做法是定义两个中间继电器线圈:一个“横移运行中”,一个“升降运行中”。升降动作启动前,必须检查“横移运行中”为0;反过来,横移动作启动前,必须检查“升降运行中”为0。
第三个坑是双线圈。同一个Q点如果在多个网络里被反复赋值,PLC扫描时会以最后一个网络的结果为准,极易引发诡异故障。我的原则是:每个输出点只在一个网络里赋值,其他逻辑网络只控制中间变量。排查故障时也可以先检查程序里有没有重复输出,这能省下一大半时间。
3. 组态王6.55上位机:画面、变量绑定与通信配置
3.1 画面怎么画才能一眼看清上下两层
组态王6.55的画面设计不需要多花哨,关键是让操作员一眼看懂当前车库状态。我采用的是侧视布局:画面上方一排是上层4个车位,下方一排是底层5个板位,上下对齐。每个板位用一个矩形表示,矩形内再放一个类似汽车轮廓的图元,没车时汽车图元隐藏,有车时显示并变为指定颜色。
重点要表达两件事:车位空不空、当前动作在哪个板位。我单独划出一块“运行状态区”,显示当前步骤文字(空闲、腾空、下降、等待进出、上升复位),再放一个“当前动作板位”文本框,这样操作员在远处也能看清系统在干什么。
操作区放在画面右侧:9个车位选择按钮、存车按钮、取车按钮、急停按钮。按钮用组态王图库里的标准按钮即可,不需要自己做复杂的命令语言。直观点说,上位机的作用是“把PLC内部的状态翻译成人能看懂的画面”,不是让你在现场再搞一套控制逻辑。
3.2 变量定义与动画连接:从“有车/无车”到“动作步骤”
组态王里的变量必须和PLC地址严格对应。下面是我在这套工程里常用的变量定义示例:
| 变量名 | 数据类型 | 连接设备 | 寄存器 | 读写属性 |
|---|---|---|---|---|
| 车位1有车 | I/O离散 | S7_300 | M10.0 | 只读 |
| 车位2有车 | I/O离散 | S7_300 | M10.1 | 只读 |
| 当前步骤 | I/O整数 | S7_300 | MW20 | 只读 |
| 横移M1正转 | I/O离散 | S7_300 | Q4.0 | 只写 |
| 横移M1反转 | I/O离散 | S7_300 | Q4.1 | 只写 |
| 目标车位号 | I/O整数 | S7_300 | MW22 | 只读 |
| 存车请求 | I/O离散 | S7_300 | M30.0 | 只写 |
| 取车请求 | I/O离散 | S7_300 | M30.1 | 只写 |
动画连接时,车位矩形的“填充颜色”属性连接对应的“有车”变量;底层的板位矩形用“水平移动”属性连接一个板位置变量,最小值和最大值对应板位左右两个位置的像素差。按钮的命令语言也简单,比如存车按钮:
\\本站点\存车请求 = 1; \\本站点\目标车位 = 6;组态王命令语言里的变量名必须带\\本站点\前缀,这个初学者最容易漏。写完之后点击“编译”,如果变量名找不到,基本就是前缀或变量类型的问题。
3.3 通信通道配置:MPI/TCP的地址、机架槽位与注意事项
组态王6.55与S7-300通信,我主要用两种方式。第一种是MPI:在组态王设备配置里选择“PLC”里的“西门子S7-300(MPI)”,然后设置PLC站地址。默认站地址为2,PG/PC接口要选对应的PC Adapter。如果你用的是USB MPI编程电缆,组态王里设备和电脑的驱动设置必须一致,否则表现为“设备连接失败”。
第二种是TCP:如果S7-300带有以太网模块或者集成PN口,组态王里选“S7-300(TCP)”,地址要填IP地址、机架号和槽号,常见格式是192.168.0.10:0:2。IP后面的“0:2”分别代表机架0、槽号2,具体以CPU的安装位置为准。TCP方式在仿真阶段更容易被模拟程序支持,所以我偏向推荐TCP。
无论用哪种方式,检活步骤都是先检查物理链路,再检查通信参数,最后在PLC侧监控表里手动给变量置值,看组态王能不能读到。我是先给M20赋一个固定值,然后刷新组态王画面看“当前步骤”有没有变化。如果画面纹丝不动,就先别折腾画面,去查通信。
4. 仿真联调实测:几处让我多花了半天时间的坑
4.1 PLCSIM和组态王“连不上”的真相
第一次做这个工程时,我以为把Step7程序下载到PLCSIM,组态王再配一个“S7-300(MPI)”设备就能直接通信,结果卡了整整一个下午。后来才想明白:PLCSIM仿真的是PLC内部逻辑,它没有真实硬件接口,组态王自带的S7驱动走的是硬件链路的抽象层,两边根本不在同一个总线上。简单说,PLCSIM不是一张能直接被组态王访问的网卡。
我的实际解决流程分三步:
- 先用PLCSIM把S7-300程序里的动作序列全部验证正确,这一步可以完全离开组态王;
- 组态王画面先用内存变量和仿真数据,把动画、按钮、报警逻辑调通;
- 条件允许时,再通过OPC桥接或者接真实PLC做完整联调。
如果你的实验环境里没有真实PLC,最务实的做法就是第一步加第二步,把它们配合好,这就是一个合格的仿真工程。别在“PLCSIM必须连上组态王”这件事上死磕,它本身就不属于同一种通信机制。
4.2 数据格式不一致:布尔、字节、字串位读错一锅粥
组态王和S7-300之间的变量类型不匹配,是第二高频的问题。我遇到过最典型的场景:PLC侧M20.0是“1号车位有车”的布尔点,组态王里却把数据类型定义成了“整数”,寄存器填了M20。结果组态王读的是整个字节M20,数值显示忽大忽小,车位状态跟实际完全对不上。
另一个案例是数据块读写。S7-300里用DB1.DBD20存放一个32位浮点数据,组态王里如果按“整数”去读一个16位字,只能看到半个数,而且数值明显不对。排查这类问题的通用办法是:在PLC侧监控表里手动给寄存器写几个已知值,比如M20.0写1、MW20写5,再刷新组态王画面,看哪个变量显示异常。这一步能快速锁定是地址错位还是类型错位。
组态王里的寄存器命名有自己的格式:M区、I区、Q区、DB区要分开写,位变量和字节、字变量也必须在数据类型里选准。我习惯先把变量表在组态王里列好,再回到Step7对照程序里的M区分配,两边一起看,基本不会错。
4.3 动画刷新跟不上PLC步进
程序逻辑跑通以后,组态王画面又出现了一个新问题:PLC侧已经执行到STEP 4,组态王画面还停在STEP 2,看起来整个系统慢半拍。这个现象的本质是刷新周期不匹配。组态王里变量的数据刷新周期默认在250毫秒左右,而PLC的步进切换如果极快,画面根本来不及捕捉。
我的处理办法是两类:第一,把画面中需要高频刷新的变量(比如当前步骤、板位位置)的刷新周期调小,我实际用到50毫秒,显示立刻跟上;第二,在PLC侧设计步进状态时,确保每个STEP维持足够时间。其实立体车库本身是机械动作,横移和升降都要几秒才能完成,根本不需要担心状态切换太快,反而要注意别把刷新周期设得过低拖垮上位机CPU。
另一个小坑是动画移动的“跳变感”。如果板位位置变量直接用了“当前位置编号”,画面从P1移到P5会瞬间跨越整幅画面。我后来在组态王里把移动动画拆成几段,通过中间变量逐步过渡,视觉上更接近真实运行,也方便观察动作顺序。
4.4 互锁脚本的时序问题:指令发出不等于动作完成
最后这个坑最有隐蔽性。有一段时间程序偶尔会出现“两台横移电机同时转动”的现象,查梯形图半天没看出问题,后来发现是步进状态机的转移条件写错了。我当时把“发出横移指令”当成“横移完成”用了:前一步刚启动电机,下一步的转移条件立刻满足,PLC扫描到下个周期又发出新的横移指令,结果两个动作叠在一起。
正确条件必须以到位传感器反馈为准。比如“P4板横移到P5”这个动作,只有P4的右到位传感器(或P5位置的检测信号)有效且电机停止反馈为0时,才允许转移下一步。我还加了一个动作超时保护:横移动作启动后15秒内收不到到位信号,就判定故障并停机报警,蜂鸣器响起。这样即使机械卡死,系统也不会一直输出。
组态王侧也要做一层互锁。我规定:只有当“当前步骤”变量等于0(空闲)时,存车、取车按钮才允许下发指令;否则按钮置灰。这样操作员在系统动作中误点按钮,也不会干扰PLC状态机。上位机的互锁逻辑不要写得太复杂,只做操作层面的保护,真正决定动作顺序的权限始终在PLC侧。
如果你也准备拿组态王6.55配S7-300做立体车库仿真,我建议先把空位腾挪和这套互锁逻辑写好,再慢慢调画面。动作顺序不乱,后面的监控和通信问题都好解决;顺序一旦乱了,画面再漂亮也是白搭。