最近刚完成一个自动售货机控制系统的项目,编号No.848,核心是用Omron PLC(欧姆龙小型PLC)加MCGS组态屏搭了一套完整的售货机控制系统。这个项目从需求分析、硬件选型、I/O分配、梯形图编写到MCGS画面组态和联调,前前后后花了两周左右。做完以后整体跑得很稳,中间也踩了不少坑。这篇文章就把整个设计和实现过程完整拆开讲一遍,包括每一步为什么要这么做、程序怎么写、组态怎么配、调试时哪些地方最容易出问题,给正在做类似课题或者想入门PLC+组态的朋友一份可以直接参考的实操记录。
这套系统针对的是校园、办公区常见的中小型自动售货机,支持的货道数量不多,大概4到8个,商品价格和投币找零逻辑都比较简单。核心功能就是投入硬币后,系统累计金额,用户选择商品,PLC判断金额是否足够,足够就驱动对应货道电机出货,同时处理找零;如果投币后长时间不选品,或者中途想退币,系统还能执行退币操作。这些逻辑全部跑在PLC里,组态屏负责状态显示和操作交互。整个项目非常适合作为PLC课程设计、毕业设计或者工控入门练手项目,成本不高,逻辑清晰,该有的工程环节一个不少。
1. 项目需求与整体设计思路
1.1 这个系统到底要解决什么问题
自动售货机表面上看就是一个铁柜子加几个弹簧,拆开看核心其实是一个典型的工业控制系统。用户投币,系统要识别币值、累计金额;用户选品,系统要判断金额是否足够、对应货道是否有货;条件满足后驱动电机把商品推出来;如果金额多了,还要计算和输出找零。再加上退币、超时未取、故障报警这些边界情况,整个控制逻辑其实比表面看起来复杂不少。
我接到这个项目需求后,第一时间没有急着写程序,而是把功能需求拉成了一张表。这个习惯很重要。自动售货机也好、别的设备也罢,第一步永远是确认输入信号有哪些、输出执行机构有哪些、中间有哪些逻辑状态。输入信号包括投币传感器(脉冲信号)、选品按钮、货道出货检测传感器、找零币是否不足的检测信号;输出动作包括各货道电机、找零电机、运行状态指示灯和蜂鸣器。把这些列清楚以后,PLC的点数、型号、I/O分配自然就有了依据。
还有一点容易被忽略,就是用户操作时序。投币和选择按钮的顺序在真实场景里不是绝对固定的,有人先投币后选品,也有人先按按钮发现没投币再补投。PLC程序必须考虑到这些顺序组合,保证不管用户怎么操作,系统都不会出现误出货或者卡死的状态。这也是为什么我最后决定用状态机的方式来组织梯形图,而不是简单地用一堆互锁条件堆逻辑。
1.2 为什么选Omron PLC + MCGS而不是其他组合
工控圈的PLC品牌很多,西门子、三菱、Omron各有各的生态;组态软件也是五花八门,组态王、力控、MCGS、WinCC都属于常见选择。这个项目最终选了Omron PLC和MCGS,主要基于三点考虑。
第一,成本和控制规模匹配。自动售货机这种设备用不到什么模拟量处理、PID调节、高速计数这些复杂功能,用一台小型机就完全够了。Omron的CP系列小型PLC在2000块钱以内的价位能提供十几到几十个I/O点,运行稳定,编程软件CX-Programmer使用起来比较顺手,指令系统也很规整,非常适合这种中小规模逻辑控制场景。
第二,Omron PLC和MCGS组态屏之间的通讯协议支持非常完整。MCGS的设备窗口里直接内置了Omron HostLink协议驱动,不需要自己写复杂的通讯代码,只需要在设备配置里选好串口参数、把PLC通道和MCGS变量一一对应起来就能工作。这一点对项目交付周期影响很大,至少帮我省了两三天写通讯协议对接的时间。
第三,教学和资料环境成熟。如果用比较冷门的PLC和组态软件组合,遇到问题连查参考的地方都少。Omron和MCGS是很多高校和培训机构都在用的组合,资料多、社区活跃、视频教程一大把。对初学者来说,遇到通讯不通、变量不刷新这类问题,很容易找到解决方案。
从控制系统完整性角度说,PLC负责逻辑控制,组态屏负责人机交互和状态监控,这个分工本身就是工业现场最主流的架构。小型设备用一体机(触摸屏内部集成了PLC功能)也能做,但可扩展性和灵活性差很多。用分立式的PLC+组态屏方案,后期要加货道、加功能都更容易,这也是我推荐这个组合的重要原因。
1.3 系统架构与控制流程
整个系统架构可以分成三层。最底层是输入输出设备,包括投币传感器、选品按钮、光电检测开关、出货电机和找零电机;中间层是Omron PLC,负责采集输入信号、运行控制逻辑、输出执行命令;最上层是MCGS组态屏,通过串口和PLC通讯,实时显示投币金额、商品状态、故障报警等信息,同时把用户的操作指令下发到PLC。
控制主流程我设计成清闲状态等待投币 -> 累计投币金额 -> 等待选品 -> 金额判定 -> 出货执行 -> 找零输出 -> 返回清闲状态。中间穿插退币分支、超时未选分支、缺货状态检测和故障报警。这个流程画成状态转移图会更直观,写梯形图的时候每个状态对应一个中间继电器或W区字,程序结构非常清楚,排查问题时也能一级一级定位。
实际编写程序的时候,状态机并不是用一个ST指令或者高级语言实现的,而是用传统的位软元件加定时器、计数器组合实现的。这样做的好处是每一步都是可见的梯形图逻辑,站内维护人员即使不看注释也能顺着电路把流程捋出来,这恰恰是PLC项目相比单片机方案更有优势的地方。
2. 硬件选型与I/O分配要点
2.1 主机选型与点数估算
硬件选型时首先做I/O点数估算。我这个项目的输入信号按功能分:投币传感器1个点(脉冲输入)、选品按钮按4个货道算就是4个点、货道出货检测光电开关4个点、找零币不足检测1个点、系统启动/急停2个点。输出信号包括4个货道电机、1个找零电机、1个状态指示灯、1个蜂鸣器、1个退币电磁阀,合计7个点。全部加起来输入约12点、输出约7点,再加上15%到20%的余量,大概需要15点输入和9点输出。
Omron的CP1E-N30型号本体提供18点输入和12点输出,正好满足需求不用加扩展模块。如果货道数量要增加,CP1E系列还可以加扩展I/O单元,容量弹性足够。另外CP1E本体自带2路串口,RS-232C接口直接和MCGS组态屏通讯,不需要额外买通讯模块,这个小细节省了一笔钱也少了很多接线麻烦。
我见过不少项目在选型阶段把PLC点数卡得很死,最后一台机器想加个功能都没地方加。合理的做法是在确定I/O清单后至少留出10%到20%备用点,PLC选型宁大勿小。尤其像自动售货机这种以后可能要增加货道、增加扫码支付模块的设备,留余量是给自己留后路。
2.2 I/O分配表与接线注意
下面这是我实际项目的I/O分配表,直接贴出来供参考。不同PLC型号的通道号和地址编号有差异,但分配思路完全通用。
| 类型 | 地址 | 信号说明 | 备注 |
|---|---|---|---|
| 输入 | 0.00 | 投币传感器脉冲 | 每次投币产生一个脉冲 |
| 输入 | 0.01 | 货道A选品按钮 | 对应商品价格10元 |
| 输入 | 0.02 | 货道B选品按钮 | 对应商品价格5元 |
| 输入 | 0.03 | 货道C选品按钮 | 对应商品价格8元 |
| 输入 | 0.04 | 货道D选品按钮 | 对应商品价格3元 |
| 输入 | 0.05 | 货道A出货检测光电 | 检测商品是否掉落 |
| 输入 | 0.06 | 货道B出货检测光电 | 检测商品是否掉落 |
| 输入 | 0.07 | 货道C出货检测光电 | 检测商品是否掉落 |
| 输入 | 0.08 | 货道D出货检测光电 | 检测商品是否掉落 |
| 输入 | 0.09 | 找零币不足检测 | 低电平有效 |
| 输入 | 0.10 | 系统启动开关 | 闭合才允许运行 |
| 输入 | 0.11 | 急停按钮 | 常闭触电,断开即停 |
| 输出 | 100.00 | 货道A出货电机 | 交流电机,需要接触器扩展 |
| 输出 | 100.01 | 货道B出货电机 | 同上 |
| 输出 | 100.02 | 货道C出货电机 | 同上 |
| 输出 | 100.03 | 货道D出货电机 | 同上 |
| 输出 | 100.04 | 找零电机 | 每次输出一个找零硬币 |
| 输出 | 100.05 | 运行指示灯 | 系统运行时点亮 |
| 输出 | 100.06 | 蜂鸣器 | 故障或取货提醒 |
接线方面有几个非常容易踩的坑,我一个个说。
投币传感器在售货机里常见的是脉冲输出型,投一个硬币输出一个短脉冲信号。这个信号接入PLC输入点时要注意电平匹配,传感器如果是NPN型输出,只能接PLC的漏型输入端子,接错了信号永远检测不到。Omron CP系列本体输入是漏型输入(负极公共端),和NPN型三线传感器是绝配,直接棕色接正极、蓝色接负极、黑色接输入点。有些传感器是PNP型的,那就需要额外加转换继电器或者换PLC型号,否则输入永远不导通。
选品按钮我用的普通常开触点按钮,这个比较简单。但要注意按钮和传感器共用一个公共端时,公共端要接对,Omron输入回路是COM端接电源负极,每个输入点接电源正极经触点回到COM端。接线时如果电源选型不当,现场经常会出现按钮按下后PLC输入点指示灯微亮但实际不触发的情况,这大概率是地线回路干扰或者公共端接错,排查时先量COM端电压,再看输入指示灯状态,一步步缩小范围。
2.3 传感器与执行器的接口匹配
执行器部分,货道电机实际是小型交流电机或者直流减速电机。PLC输出点直接驱动电流有限,CP1E输出带载能力在2A左右,如果电机电流超过这个值,必须配合中间继电器或者接触器使用。我这边货道电机是24V直流减速电机,额定电流1.5A,勉强能直接用,但为了延寿和抗浪涌,还是加了中间继电器过渡,电机电源单独用一路24V开关电源供给,PLC输出只控制继电器线圈。这样一个是避免电机启动瞬间大电流冲击PLC输出触点,另一个是便于故障隔离,电机短路时不会烧掉PLC。
找零电机逻辑上比较简单,但动作次数和出货电机不在一个量级。售货机生意好的时候出货电机每天动作也可能就几十次,找零电机一天可能上百次。选型时用额定寿命高的电机,最好带一个计数反馈,在MCGS组态界面里显示找零电机动作次数,方便后期维护判断寿命。这个细节不是必需的,但实际运营时能省不少事。
还注意到一点,机械结构上出货检测光电开关的位置决定了PLC能不能准确知道商品已经掉下来了。光电开关安装在货道出口处,商品掉落的瞬间会遮挡光线产生一个信号,PLC收到这个信号以后才停止电机并认为本次出货完成。如果光电位置装得不好,常见的结果是商品卡在出口或者电机空转很久才停止,影响用户体验。硬件装好后,在程序调试阶段需要反复调整光电传感器的安装角度和灵敏度。
3. 梯形图核心逻辑实现
3.1 状态机思路:把售货流程拆成几大步
PLC程序最忌讳的就是把所有逻辑都堆在一段梯形图里,成千上万条指令挤在一起,改动一个地方牵一发动全身,调试的时候根本无从下手。我采用的方法是先用状态机设计,再把每个状态拆成独立的梯形图段,每个段只负责一个明确的工作。
状态划分如下:S0空闲待机、S1投币累计、S2等待选品、S3选品判定、S4出货执行、S5找零执行、S6退币执行、S7故障报警。每个状态用一个独立的内部继电器表示,例如W0.00表示S0、W0.01表示S1,程序里通过置位和复位实现状态之间的跳转。这样从头到尾只需维护一条状态主线,异常分支依附在状态跳转条件上,逻辑非常清晰。
为什么要用状态机而不用一堆条件互锁?拿自动售货机来说,用户投币后如果一直不选品,系统要在一段时间后自动进入可退币状态,这个超时逻辑如果放在复杂条件组合里,代码会变得非常难以阅读。状态机只需要在S2状态下启动一个定时器,时间到就复位S2置位S6,仅此而已。每一种运行情况都对应明确的当前状态,出了问题看当前状态就知道程序走到哪一步了,这是工程上最高效的调试方式。
3.2 投币计数与金额寄存器
投币识别的难点在于硬币投入是一个物理过程的瞬时脉冲,PLC扫描周期可能只有几毫秒,而硬币掉落后传感器信号的持续时间也不长。程序要保证每一次投币都被且仅被计数一次,同时要把不同币值的硬币金额正确累加。
针对单种币值的情况,我用计数器CNT指令完成脉冲计数,每次投币脉冲上升沿计一次。但实际售货机里通常存在多种硬币投币,比如1元、5元、10元混合投,这就要求分别识别不同币值。常见做法是投币器硬件本身能区分币值并输出不同脉冲个数,比如投入1元输出1个脉冲,投入5元输出5个脉冲,投入10元输出10个脉冲,PLC只需要统计总脉冲数然后按比例换算成金额就行。我的项目里投币器就是这么个逻辑,程序里用一个计数器统计脉冲总数,每累加一个脉冲,金额寄存器D100加1元。
这里需要特别关注的是脉冲信号的滤波和去抖。真实世界的物理开关信号往往带有毛刺抖动,如果不做处理,一个硬币可能被重复计数好几次。Omron PLC输入点自带数字滤波,但滤波时间默认是10ms,对短脉冲信号来说容易漏计。我在程序里对投币输入点做了软件滤波:投币信号接通后先启动一个定时器,定时5ms后再读一次还是接通状态才算有效投币。这样做可以过滤掉大部分开关抖动和电磁干扰产生的假信号。
脉冲累计金额后,D100寄存器里存的就是用户当前已投的总金额。MCGS组态屏上显示的就是这个寄存器的值,每次投币画面上的金额刷新一次,用户能直观看到自己投了多少钱。这里有个细节要提醒:Omron PLC的寄存器数据格式默认是二进制HEX,而MCGS里如果按十进制显示,需要设置正确的数据类型。我在MCGS里把对应通道的数据类型选为无符号整数,数值就正常了,否则容易出现投资10元显示16元的诡异情况。
3.3 选品判定与找零出货程序段
选品判断的核心是比较已投金额和商品价格。我这边用CMP比较指令,把D100金额寄存器和每个商品价格的常量(比如货道A是10元)比较,比较结果通过大于、等于、小于标志位输出。
程序逻辑是这样的:用户按下货道A选品按钮,如果当前状态在S2,就进入选品判定流程。先检查D100里的金额是否大于等于10,如果满足,置位出货状态,把选品结果存到另一个寄存器里标记当前选的是哪个货道;如果不满足,把系统状态切到提示状态,在MCGS组态屏上弹出一个“余额不足”的提示窗口,同时点亮蜂鸣器提醒用户补投或者退币。
出货电机控制我加了一个2秒定时保护。正常出货电机转1秒左右就能把商品推下来,光电开关检测到商品掉落会提前结束动作。但如果出现光电开关故障或者商品卡住的情况,电机不能无限制地转下去,定时器时间到就强制停止电机并置位故障标志。这个保护逻辑在真实设备上非常重要,不然卡货的时候电机会持续转动,轻则烧电机,重则损坏货道结构。
找零逻辑稍微绕一点,但原理不复杂。假设货道A价格10元,用户投了15元,出货完成后系统需要找零5元。我用一个除法指令把(D100 - 价格)除以单枚找零币面值,得到找零枚数,存到D101寄存器,然后驱动找零电机输出,每输出一枚计数减1,减到0停止。找零币不足检测信号在找零前判断一次,如果检测到找零币仓空,则先把故障标志置位、在主界面报警,找零指令不执行,避免驱动电机空转消耗寿命。
程序里有一段梯形图助记符,贴核心部分给参考。完整的程序很长,这里展示选品判定和出货控制这一段的骨架逻辑:
LD 0.01 // 货道A选品按钮按下 AND W0.01 // 处于S2等待选品状态 MOV #10 D110 // 商品A价格送到D110 CMP D100 D110 // 比较已投金额和商品价格 AND P_GT // 已投金额大于等于价格时 SET W0.03 // 进入S3选品判定状态 SET W0.04 // 后续置位出货状态实际项目中,每个货道都有一组类似的逻辑,配合不同的输入点和价格寄存器。价格不是写死在程序里的,而是存在数据寄存器中,后期调整价格只需要通过组态屏直接写寄存器,不需要改PLC程序。这是这种架构的一个很大优势,运营人员不用懂PLC也能改价格。
3.4 初始化和防误操作处理
初始化逻辑放在整个程序的最前面。PLC上电后先将所有状态继电器复位,金额寄存器清零,电机输出全部断开。有些设计者会忽视这一步,觉得反正系统刚上电还没有用户操作,各软元件默认就是0。但危险在于,掉电瞬间如果某个输出继电器还保持着导通状态,重新上电时PLC输出模块会瞬间动作一下,电机就有可能突然转一小段,在检修设备时容易伤到人。所以程序里的第一个扫描周期必须无条件把所有输出和状态位复位。
还有误操作保护。比如出货过程中用户再次按选品按钮,系统必须忽略。我在选品按钮输入回路里加了一个出货状态互锁,只有S2状态下的选品按钮才有效,其他状态下的按钮动作一律不响应。这个细节对用户体验影响很大,否则用户可能在出货过程中误触其他按钮,导致同时出两件货或者程序紊乱。
退币逻辑的防误操作用了延时处理。用户按下退币按钮,系统不会立即执行,而是先闪烁确认提示3秒,如果这3秒内再次确认才执行退币。很多售货机上其实没有这个二次确认,但我在这个项目里特意加了,考虑是防止用户误触退币后懊恼,以及其实这里还能有一个倒计时结束前取消退币的机会。这个逻辑写起来不复杂,使用一个定时器加一个状态位即可实现,用户体验却提升明显。
4. MCGS组态画面设计与通讯配置
4.1 设备组态:串口通讯参数与通道绑定
MCGS组态环境分用户窗口、设备窗口和运行策略三大块。实际配置时先做设备窗口,因为只有PLC和数据通道建立好连接,后面的画面绑定才有意义。
在MCGS的设备窗口里添加“通用串口父设备”和“欧姆龙PLC”子设备。父设备负责串口参数,子设备负责协议转换和通道定义。串口参数必须与PLC侧完全一致,我使用的是9600波特率、7位数据位、偶校验、2位停止位,这是Omron HostLink协议的常用默认参数。PLC侧在CX-Programmer的PLC设定里把串口1设置为HostLink模式,波特率9600,校验方式偶校验。两边参数只要有一个不一致,通讯必然失败,这是组态联调时最基础也最常错的一步。
通讯参数设置好后,接下来就是建立MCGS变量和PLC地址的映射关系。Omron PLC的CIO区、W区、D区地址在MCGS里都有对应的驱动通道。我的项目里金额寄存器D100、找零计数D101、选品结果D102这几个需要在屏上实时显示和修改,就在设备窗口里分别建立通道,通道类型选字,PLC地址填D100、D101、D102,读写属性根据实际需要选择只读或读写。
这里有一个坑必须提醒:MCGS里通道的整数格式和PLC内部的二进制格式之间的对应关系。Omron的直接在线监控程序里看到的是HEX值,MCGS设备通道读到的原始值也是HEX,如果显示窗口里只绑定数值而不做格式处理,可能看到的就是十六进制数。解决方法是把显示构件的数据类型设为十进制无符号整数,而不是默认的十六进制,这样用户界面才显示正常金额数值。
4.2 用户画面设计:显示、按钮和状态灯
MCGS的用户窗口设计决定了设备给人留下的第一印象,也是整个项目里最直观的一部分。我的主画面主要包括三个区域:顶部显示累计投币金额、四组商品货道状态卡片(每组包含商品名称、价格、库存状态、选择按钮)、底部区域显示系统运行状态、找零按钮和故障报警信息。
商品货道状态卡片里的库存状态来自PLC的D区寄存器。出货电机每完成一次出货,PLC对应商品库存寄存器减1,MCGS定期采集这个寄存器的值并显示在画面上。库存为0时卡片背景变成灰色,选择按钮变为不可用。这个联动效果通过MCGS的可见度动画属性实现:绑定一个库存数值变量,当数值为0时让按钮构件隐藏,同时显示“缺货”文字标签。
金额显示使用MCGS的数值显示构件,绑定设备通道D100。找零按钮连接一个输入按钮构件,按下时通过脚本向PLC写入一个常数到指定的中间继电器,触发PLC的退币状态。这里需要注意的是,MCGS按钮写入PLC和普通触摸屏按钮不同,它需要配置脚本代码来操作通道值,否则点击只是界面变化没有实际通信动作。我用的脚本很简单,在按钮的“按下”事件里执行赋值操作给PLC地址写1。
画面整体配色我用了深蓝色背景加白色数字、橙色按钮,风格偏工业风。字型字号要大,考虑到售货机用户操作距离基本在1米开外,小字号根本不实用。此外组态屏的触摸灵敏度一般在工控屏里不算特别高,按钮区域尽量设计大一些,减少用户点错概率。这个细节算是工业设计和用户体验的结合点,实际运行效果反馈很好。
4.3 运行策略与脚本
MCGS的运行策略模块负责周期性的数据处理和逻辑控制,相当于组态屏端的“小程序”。我在这个项目里用到了两类策略。
第一类是循环策略,执行周期设为500毫秒。循环策略里主要做数据采集和显示刷新,把PLC传来的各个寄存器和位状态写到用户窗口对应的变量里。这里有一个性能权衡:采集周期太短会增加串口通讯负担,太长画面刷新不够流畅,500毫秒在中小型项目里是比较合适的值,画面显示基本实时,通讯压力也很小。
第二类是事件策略,用来响应特定事件。比如故障发生时蜂鸣器需要在组态屏上也同步响起,我在事件策略里监听PLC故障位的变化,故障位从0变1时就触发一次报警声音提示,同时在画面上弹出报警窗口。事件触发比循环扫描更及时,也省资源。不过话说回来,MCGS的事件策略触发条件设置有一点隐藏菜单的感觉,新用户容易找不到,我是在某个角落的“策略属性”对话框里设置的,费了点功夫才摸清楚。
脚本语言用的是MCGS自带的基本类似BASIC的语法,功能不强但够用。比如显示金额的格式化、缺货状态的判断、报警记录的写入,都是几行脚本就能搞定的事情。有一点阅历的新手可能觉得学一套脚本语言有门槛,实际上你只需要知道赋值语句、if判断和while循环,就能应付90%以上的组态脚本需求。
4.4 与PLC联调时的数据一致性
联调阶段最容易出现的问题就是PLC和组态屏两边数据不一致。PLC内部实际运行的逻辑和MCGS画面上显示的状态对不上,这种问题通常有三个来源。
第一个来源是通讯丢包。串口通讯在干扰较强或者线缆过长的情况下,偶尔会出现帧丢失。解决办法是调整通讯的重试次数和超时时间,MCGS设备窗口和PLC的HostLink协议都支持重发机制。实时性要求高的数据可以压缩采集周期,不重要的状态显示可以把周期放宽到1秒以上,总体通讯负担降下来后丢包率会显著下降。
第二个来源是地址映射错误。PLC里D100和MCGS通道里的D100虽然名字一样,但存在不同存储区的同名地址。比如Omron有D区、W区、H区,地址都是100开头就很正常,万一在MCGS里选错了存储区,读回来的数据就完全另一个含义了。排查方法是把PLC里的某个寄存器先手动写一个特殊值,然后看MCGS上显示是否一致,逐点测试,效率最高。
第三个来源是数据类型不匹配。PLC里同一个D寄存器可能是BCD码也可能是二进制,显示出来差之千里。我的项目里金额计数如果选二进制格式读出来就是正常的十进制数,但如果选错成BCD格式,MCGS上会显示成完全不对的数值,且越看越怀疑PLC程序有问题。联调数据不一致时,先确认数据类型,别急着改程序。
5. 联调过程与常见问题排查
5.1 空机调试流程
整个系统安装好以后,我没有直接放商品测试,而是先做了一个完整的空机调试流程,确保每一路信号、每一个执行机构都正常工作。这个流程看起来慢,实际上能节省大量后期排查时间。
第一步是PLC单体测试。断开执行电机和传感器接线,用CX-Programmer在线仿真和实体PLC强制功能,逐一点动每个输出点,确认各输出通道动作正常。同时模拟输入信号,检查PLC程序各个状态是否能正确进入和退出。这个阶段程序问题基本都能暴露出来,不用牵扯组态屏。
第二步是组态屏单体测试。不连接PLC,在MCGS工程里用模拟执行功能,检查画面是否正常启动、变量初值是否合理、按钮操作是否有响应。MCGS提供了模拟运行模式,可以直接在没有实体PLC的情况下跑组态画面,这时候把画面逻辑调顺,后面联调就省心很多。
第三步是PLC和组态屏通讯测试。把串口线接好,两边参数核对无误后,MCGS画面上应该能实时显示PLC里的状态变量。我用了一个最笨但最有效的方法:在PLC里手动给D100写一个值,看屏上显示是否一致;然后把PLC上的输入触点一个个短接,看MCGS画面上的对应状态灯是否变化。全部应声而动,这一步才算通过。
第四步才是真实硬件联调。接上电机和传感器,放入少量测试商品,按真实用户操作走流程:投币、选品、出货、找零、退币、故障报警,每一个功能分支都完整跑一遍。这个阶段发现的问题大多是机械配合方面的,比如电机转动时间不足导致商品没有完全推落、光电传感器位置偏移导致检测不到掉落的商品等。硬件问题返回去调整机械和传感器位置,软件问题再回到PLC程序修改。
5.2 常见问题速查表
实际操作中必然遇到的问题,我整理成一个速查表,省去后来人从头排查的时间。
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| PLC程序运行但MCGS无数据 | 串口参数不一致 | 核对波特率、数据位、校验位、停止位 |
| MCGS显示数值全是0 | PLC侧寄存器地址和MCGS通道地址不对应 | 手动写特殊值逐点测试,确认地址映射 |
| 投币后金额不增加 | 投币传感器信号未到PLC | 万用表测传感器输出,检查NPN/PNP接线匹配 |
| 投币一次金额增加多次 | 按键抖动产生多脉冲 | 程序加5ms软件滤波定时器去抖 |
| 选品后电机不转 | 未满足金额判定条件或者状态不在S2 | 监控当前状态继电器和金额寄存器数值 |
| 商品掉落但电机还在转 | 出货检测光电未触发或者被遮挡 | 调整光电位置,检查检测信号反馈 |
| 找零数量不对 | 找零计算寄存器溢出或数据类型错误 | 检查除法计算和数据类型格式设置 |
| 组态屏按钮点了没反应 | 按钮未配置写入PLC的脚本 | 在按钮事件里添加赋值操作 |
| 画面数值闪烁跳动 | 串口通讯干扰 | 检查接地和线缆屏蔽层,降低采集频率 |
| PLC输入指示灯微亮但程序不动作 | 公共端接线错误或电压不足 | 量公共端电压,核对电源接线 |
这个速查表里的问题,我这一个项目基本全踩了一遍。特别是投币抖动和串口参数不一致这两个问题,每一个都花了半天以上才定位到根因。所以写在前面,能帮大家省点时间就省点时间。
5.3 几个容易忽略的细节
最后分享几个在实际项目中特别容易忽略的细节,都是我在联调中吃了亏以后总结出来的。
第一个是电源分区。自动售货机里有PLC、传感器、电机等多个用电部件,如果全部共用同一个开关电源,电机的启停会产生比较大压降和干扰,导致PLC偶尔误动作。我的处理方法是PLC和传感器用一个24V电源,电机驱动单独用一个24V电源,两个电源的0V在一点连接。这样做后干扰问题明显缓解。如果条件限制只能共用一个电源,也要在电机回路加续流二极管和滤波电容,尽量减少反电动势冲击。
第二个是PLC输出点的感性负载处理。电机、继电器线圈都属于感性负载,断电瞬间会产生反向电动势,不处理的话会缩短PLC输出点寿命甚至烧坏触点。我每个输出点都并在负载两端加了一个续流二极管(直流场合)或者RC吸收回路(交流场合)。这个是硬件设计规范里必写的内容,但实际项目里真的有很多人忽略,等烧了触点才知道补上。
第三个是程序版本管理。项目调试期间会反复修改PLC程序,尤其是状态变换的条件经常微调。我每修改一版,就导出一次带日期和版本号的程序文件,比如No848_PLC_v2.0_0520.cxp,同时写清楚这版改了什么。这个习惯看起来不起眼,但当程序调到后期发现某个功能回退的时候,就能快速找回之前的版本对比,能救急。
第四个是机械安全联锁。出货电机在货道有货物卡住时会持续堵转,发热量很大。我在PLC里加了一个电流保护继电器,堵转电流超过阈值就切断电机电源并报警。这个没有做进最初设计,是在看到测试样品卡货后才补上的。安全保护这种东西,永远都是宁可多余也不能缺失,用在售货机上尤其重要。
个人实际做下来的体会是,这种自动售货机项目看起来不大,但麻雀虽小五脏俱全,I/O规划、逻辑状态管理、组态通讯、硬件调试每个环节都要扎扎实实走一遍。PLC程序本身并不复杂,真正的功力体现在对各种异常情况的预判和对实际运行环境的理解上。做完这个No.848项目以后,我最大的收获不是写熟了多少条梯形图指令,而是建立了一套从需求到实现再到验证的完整工程思维,这套方法论放到任何一台工控设备上都通用。
最后再补充一点小经验:这个项目后续还可以往很多方向扩展,比如给MCGS画面加上扫码支付模块,通过串口或者网口接到支付平台,PLC只需要多接收一个“支付成功”的复位信号;或者在PLC里加一个RS-485总线扩展,把售货机的销售数据上传到后台服务器做无人零售大数据分析,这些都是当前自动化设备发展非常快的方向。改到这一步虽然要动不少软硬件,但No.848的成熟架构完全扛得住。先把这个基础版本吃透,后面就都是水到渠成的事了。