
1. 项目到底在做什么把自动售货机的控制需求拆开看1.1 核心功能与场景拆解一提“基于PLC的自动售货机控制系统设计”很多人第一反应是“这不是学生毕设标配吗”。确实这个题目在学校里很常见但它不是那种抄来抄去的纯纸面设计——自动售货机是典型的顺序控制场景而且它把PLC控制里的“输入信号采集、计数器、定时器、多路输出、故障处理、人机交互”全串起来了。一个项目跑通等于把PLC大部分基础功能都过了一遍这也是为什么它适合作为入门到进阶的实战课题。我在实际做过类似项目控制对象是一台模拟自动售货机8条货道带投币器、找零器、出货检测光电、取货门开关和一块触摸屏。先理清楚这台机器到底要干什么识别用户投了多少钱判断钱够不够让用户选择货道控制对应货道的电机转动把货物推出货道通过光电检测货物确实掉到了取货口最后计算找零金额控制找零器吐出硬币同时还要把库存、故障信息显示到触摸屏上。这个需求拆开之后系统的输入输出就非常清晰了。输入基本是六类投币脉冲、选货按钮或用触摸屏选货、出货检测光电信号、取货门开关、复位按钮、急停按钮。输出也基本是四类各货道的直流电机、找零器脉冲信号、运行指示灯、报警蜂鸣器。真正动手设计的时候把这些点全部列出来做成I/O表整个项目的地基就稳了。1.2 为什么选PLC而不是单片机或继电器电路这是做方案论证时被问得最多的一个问题。自动售货机这种设备用单片机比如51或STM32完全能做成本更低网上甚至有现成的开源方案用纯继电器电路也能实现最简单的“投币—选货—出货”逻辑。那为什么大多数工业级产品和课程设计最终都落在PLC上我的理解有三层。第一是可靠性。售货机是无人值守设备要7×24小时运行现场的电源波动、电机启停带来的干扰、投币器脉冲的抖动这些在单片机方案里都得自己写复杂的滤波和抗干扰程序而PLC在硬件层面和扫描机制上就做了针对性设计尤其对现场恶劣的电网环境抗干扰能力不是一个级别的。第二是调试效率。PLC程序可以用梯形图在线监控哪一点有信号、哪个定时器有没有计时在电脑上看得一清二楚现场改逻辑也方便不用重新烧录芯片。第三是扩展性。今天做8个货道明天要加到32个货道PLC加个扩展模块改一段程序就行单片机的硬件改动就麻烦多了。当然PLC方案的缺点是成本高同功能至少比单片机方案贵出两到三倍。但如果是工业应用、毕设展示或者初学者练手这个成本是值得的因为你能把精力放在控制逻辑本身而不是花大把时间调传感器、写底层驱动被一堆电子电路细节淹没。1.3 控制系统整体架构怎么画这套系统的架构并不复杂但分层清楚我通常这样划分。最底层是电源系统。PLC电源、传感器电源、执行机构电源虽然都来自同一个24V开关电源但在布线时要分开走开关电源容量建议留30%的余量。比如所有负载加起来大概需要4A那我就会选6A的电源。中间层是控制器也就是PLC本体。它负责接收输入信号按用户程序执行逻辑运算再输出控制信号。控制器的选型直接决定整个系统的扩展能力这个我在下一节详细说。上行是人机交互层触摸屏通过通信口和PLC连接显示金额、库存、故障信息也能下发参数比如商品价格。再往上如果要做联网运营还可以通过通信模块把数据上传到后台服务器这就是现在很流行的智能售货机方案了。2. 硬件选型与I/O布局动手前先把家底盘清楚2.1 PLC选型的三个硬指标选PLC我一直坚持三个原则点数够用、资料够多、软件顺手。点数这块一个8货道的自动售货机输入输出各十几个点选个16点或32点的小型机就完全够我用的是三菱FX3U-32MR16点输入16点输出。为什么选三菱FX3U而不是其他品牌主要还是资料和软件。GX Works2的仿真功能对初学者很友好写梯形图的时候自带检查网上关于FX系列的教程和案例也最丰富遇到问题好查。如果你想用国产PLC信捷XC系列、汇川H5U都行信捷的编程软件里对功能块FB的支持也比较直接如果以后要往大型项目走西门子S7-200 SMART跟博途环境是绕不开的。选型跟个人熟悉程度关系很大没有绝对的“最佳”关键是别选一个自己连软件都装不利索的牌子。选完型号还有一个细节要注意输出类型。FX3U-32MR的R代表继电器输出MT的T代表晶体管输出。继电器输出便宜、能通交直流但响应慢触点寿命有限晶体管输出响应快能输出高速脉冲。自动售货机的货道电机是直流减速电机继电器输出足够但如果我计划让电机采用闭环控制或者想用步进电机驱动货道转轴就必须上晶体管输出的型号。另一个细节是如果要用高速计数器接收投币器脉冲建议把输入点接到X0到X5这些支持高速输入的端子上。2.2 I/O点表规划一页纸定乾坤硬件设计里我强烈建议大家第一步就先把I/O点表做出来不要边画图边想。点表列出来硬件接线、程序地址就全都确定了后面做起来会非常顺。我以8货道的配置为例给出参考点表。地址信号名称类型说明X0投币器脉冲输入每投一枚硬币给一个低电平脉冲接高速计数器X1出货检测光电输入货物通过货道出口掉落到取货口时触发X2取货门开关输入门打开时为1门关闭时为0X3复位按钮输入系统复位X4急停按钮输入常闭触点断开即急停X5选货按钮A输入配合触摸屏使用也可以做实体选货X6选货按钮B输入同上X7扩展备用输入-Y0~Y71~8号货道电机输出继电器输出控制电机通断电Y10找零器脉冲输出每输出一个脉冲找零器吐一枚硬币Y11运行指示灯输出待机时常亮出货时闪烁Y12报警蜂鸣器输出故障时鸣响这个点表的思路是实体按钮只保留必要的——复位、急停、选货其他交互尽量放到触摸屏上一方面减少现场布线另一方面PLC点数也更省。如果以后货道从8路扩到16路加一块FX3U-16EYR输出扩展模块就行点表末端留好备用点位即可。2.3 接线里那些容易被忽略的坑硬件接线是整个项目最容易翻车的地方但很多教程都把它轻轻带过了。我挑几个实实在在踩过的坑讲。第一个是传感器信号极性和PLC公共端的关系。自动售货机里用的光电传感器大多是NPN型输出信号是低电平有效也就是遮挡时信号线对地导通。接三菱FX系列的时候通常把输入公共端COM接到电源0V端传感器信号线接X端子。如果你用的是PNP型传感器输出高电平有效那公共端接法就得反过来。西门子200 SMART的输入回路是源型还是漏型和具体CPU型号有关公共端1M怎么接要查手册。接线前一定要先确认三件事传感器型号是NPN还是PNP、PLC输入回路是源型还是漏型、公共端应该接电源正极还是负极。别图省事直接照搬网上的图我见过太多因为公共端接反导致输入点失灵的例子。第二个是输出端感性负载的保护。货道电机、继电器线圈都是电感负载断电瞬间会产生反向感应电动势轻则干扰其他信号重则把输出触点打坏。正规做法是在电机两端反向并联一个续流二极管或者在继电器线圈上并联RC吸收回路。这个细节别省省了后面会付出十倍的时间排查干扰问题。第三个是电源和布线的隔离。强电和弱电分开走线信号线用屏蔽线屏蔽层单端接地24V开关电源的容量要留余量。这些虽然是常识但实际项目里越急越容易忘等干扰问题出来了再回头改线工程量翻倍。3. 程序与调试把售货逻辑变成梯形图3.1 控制流程一个有限状态机自动售货机的控制逻辑本质上是一个有限状态机。我把整个流程拆成六个状态写程序之前先在纸上把状态和跳转条件列清楚。状态0待机。系统上电初始化显示待机画面等待投币。用户投币后高速计数器累加金额跳转到状态1。状态1接收投币。金额实时刷新显示投到指定金额后可以选货。这个状态会持续到用户按下选货按钮或超过投币超时时间。状态2选货判定。用户按下货道选择按钮后PLC把目标货道号存入数据寄存器。先判断金额是否大于等于该货道商品价格满足条件跳转到状态3否则提示金额不足退回状态1。状态3执行出货。对应货道的电机得电运行同时启动出货检测窗口定时器。如果在规定时间内检测到光电信号说明货物已经掉出跳转到状态4如果一直没检测到电机堵死输出故障报警。状态4找零。计算应找金额总投币额减去商品价格按每个脉冲对应固定面额的思路输出N个找零脉冲给找零器。这个状态结束时整个交易流程完成跳回状态0。状态5故障处理。这是作为保护分支存在的任何状态遇到急停、电机过流等异常都跳到这里停机并报警人工复位后才恢复。3.2 核心程序段怎么实现状态规划好之后写梯形图就比较顺了。我挑三个核心逻辑说。投币计数是第一个重点。投币器输出的是脉冲信号一个脉冲对应一枚硬币的面额。如果用普通计数器PLC扫描周期内的信号抖动可能造成漏记或多记所以这里用高速计数器更稳。三菱FX3U的单相高速计数器C235接在X0上计数脉冲频率最大能到几十千赫兹完全够用。实际编程时按硬币面额区分不同通道比如1元硬币接X0对应计数器C2355角硬币接X1对应C236然后用加法指令把两个计数器的值折算成总金额存到D10。第二个核心是货道电机控制。这里有个设计点想强调电机不是“通电转一会儿就行”要有保护逻辑。我用的方案是选货成功后先给对应输出Y置位同时启动一个5秒的运行定时器。正常情况下货物掉出光电X1触发就立刻复位Y电机停止如果5秒内光电一直没触发说明卡货了程序强制复位Y同时把故障代码写入寄存器触摸屏上会显示“N号货道出货失败”。加这个5秒上限非常关键否则卡货时电机会一直通电轻则烧电机重则引发安全隐患。第三个核心是找零逻辑。假设总投币额存在D10商品价格存在D20找零金额 D10 - D20。如果找零器每个脉冲对应1元那要输出的脉冲数就是找零金额本身。用除法指令把D10-D20的结果除以1商就是脉冲数然后用一个循环发送脉冲Y10置位500毫秒复位500毫秒循环N次。这一段的时序程序很容易写得啰嗦建议用一个功能块封装起来输入是找零金额输出是脉冲次数完成标志这样主程序里只调用一次清爽很多。如果用结构化文本ST表达货道驱动的核心逻辑大概是这个样子方便理解思路FUNCTION_BLOCK FB_ChuteDrive VAR_INPUT Enable: BOOL; // 允许运行 ChuteNo: INT; // 货道号 PhotoSensor: BOOL; // 出货检测光电 END_VAR VAR_OUTPUT MotorRun: BOOL; // 电机输出 Complete: BOOL; // 出货完成 Fault: BOOL; // 出货故障 END_VAR VAR RunTime: TON; // 运行超时定时器 Retry: INT; // 重试计数 END_VAR IF Enable THEN MotorRun : TRUE; RunTime(IN : MotorRun, PT : T#5S); IF PhotoSensor THEN // 检测到货物掉出 MotorRun : FALSE; Complete : TRUE; ELSIF RunTime.Q THEN // 5秒超时 MotorRun : FALSE; Retry : Retry 1; IF Retry 2 THEN Fault : TRUE; // 两次都失败报故障 ELSE Enable : FALSE; // 给一次重试机会复位后重新启动 END_IF END_IF ELSE MotorRun : FALSE; END_IF3.3 功能块如何把逻辑像积木一样搭起来程序规模一大全堆在主程序里的梯形图就很难维护了。我在设计时就把整个系统的功能划分成几个功能块投币处理块、货道选择块、货道驱动块、找零处理块、故障处理块。每个功能块有明确的输入输出接口主程序只负责调用和状态切换。这里多说一句功能块的用法因为很多初学者只在编程软件里见过FB这个概念但不理解什么时候用。拿货道驱动来说8个货道的控制逻辑完全一样如果不用功能块要么复制粘贴8份几乎相同的梯形图要么写一个带变址寻址的循环后者对新手不友好前者后期改一个定时器参数得改8处。用功能块的话定义一个“货道驱动块”输入是货道号、允许运行信号输出是运行完成信号、故障信号内部包含电机启动定时、出货检测窗口、卡货保护这些逻辑。主程序里实例化8个功能块每个货道一个实例参数独立修改通用逻辑时只需改功能块定义调用处全部生效。这就是现代PLC编程强调的可维护性。3.4 从仿真到现场调试的完整路径我先在GX Works2的仿真环境里把整个流程跑了一遍。仿真有个好处是可以强制修改输入点的状态不用接真实硬件就能把逻辑走通。比如强制X0给脉冲看D10金额有没有累加强制X1为1看电机是不是提前停止。这一步基本能把逻辑Bug滤掉70%。仿真通过后把程序下载到PLC开始现场调试。我建议按这个顺序来先空载测试所有输入点用短接线短接X0看软件里是否响应接着不带电机测试输出观察Y点和继电器动作然后接上所有负载做整体联调。千万不要一上来就全接好线、上电、按按钮出了问题根本不知道从哪查起。现场调试最常用的工具就是编程软件的在线监控把梯形图的触点状态看一遍哪个环节没通一眼就能定位。4. 人机界面与数据交互让售货机“可看、可管”4.1 HMI和PLC到底什么关系很多人第一次接触HMI的时候会有一个疑问触摸屏是不是也是一台PLC严格来说不是。HMI的核心作用是“显示和操作”它通过通信协议最常见的是Modbus、专有协议读写PLC内部的数据寄存器把D10的金额显示在画面上把用户点击的按钮写入M寄存器。而所有控制逻辑、时序、保护都在PLC里执行。这样分工是有原因的如果让HMI参与逻辑控制一旦通信抖动整个系统就会失灵PLC只管逻辑HMI只管显示交互即使屏幕临时挂了售货机的核心功能还能靠实体按钮维持。这个层次关系再往上延伸就是SCADA了。SCADA是监控与数据采集系统可以管理几十台PLC汇总数据、生成报表、下发指令。自动售货机的运营后台本质上就是一个简化版的SCADA系统。懂了这层关系你再看那些“SCADA和HMI和PLC有什么区别”的问题其实答案很清晰PLC是执行者HMI是单台设备的交互界面SCADA是面向整个系统的监控平台。4.2 画面设计和驱动配置的三个注意点HMI组态我用过MCGS和威纶通的软件套路都差不多。有几个注意点我觉得值得单独拿出来说。第一个是变量的地址映射。触摸屏里的“金额”控件要和你PLC的D10寄存器关联起来但不同品牌数据格式可能不一样有的默认是16位无符号有的用32位浮点配置的时候一定要把数据类型选对否则显示出来就是乱码或者负数。我习惯在PLC里就把所有要显示的数据先移到连续的寄存器区比如D100到D110专门存显示数据这样触摸屏配地址的时候方便核对。第二个是通信参数的匹配。PLC和触摸屏的通信参数必须完全一致波特率、数据位、停止位、校验位、站号只要有一个对不上画面就会不定时掉线。排查通信问题我通常先用串口调试助手监听如果能看到正常报文说明物理层没问题重点查软件配置如果报文都是乱码重点查参数设置和屏蔽线接地。第三个是时钟同步问题。有的触摸屏和PLC之间如果时钟不同步或者HMI固件有安全机制可能会显示类似“不信任PLC”的报警本质上是通信会话建立失败。常规做法是保证两者时钟一致或者关闭不必要的安全认证选项具体在触摸屏系统设置里找。这个坑不算大但第一次遇到容易懵。4.3 联网与扫码支付怎么接一个完整的自动售货机项目现在基本都要考虑联网运营了。最简单的联网方案是把PLC的通信口接一个串口转以太网模块或者直接用带以太网口的PLC通过网络上传数据到服务器。数据内容实话说不需要太多每台机器的货道库存、销售记录、故障状态、营收金额这就够日常运维了。扫码支付是目前自动售货机的标配。这类模块通常有一个脉冲输出口或者串行通信口投币器接口可以直接替换成扫码模块的继电器输出——扫码成功后给出一个类似投币的脉冲PLC端处理方式几乎不变。核心是搞清模块的触发逻辑有的模块是扫码成功后输出一个短脉冲有的需要PLC给一个电平信号来查询支付状态这个要看具体模块的协议文档但思路和接投币器是相通的。5. 调试中踩过的坑问题定位与解决实录5.1 投币信号抖动导致的计数问题这个坑我调试时被坑了很久硬币投入后金额时多时少有时候投一枚硬币金额却跳了两块。一开始以为是投币器坏了后来用示波器看波形才发现投币器的机械触点回弹严重产生了多个脉冲。PLC的普通输入端在扫描周期内只能采样一次条件状态如果程序里用了边沿检测抖动信号就会被当成多次计数。解决办法有两条路硬件上在投币器输出端和PLC输入之间加一个RC滤波电路软件上改用高速计数器并设置PLC的输入滤波时间常数。三菱FX3U里有个特殊数据寄存器D8020可以调整X0到X7的输入滤波时间默认是10毫秒我改成5毫秒后机械抖动被滤掉计数准确了。这里有个经验别一上来就调寄存器先用示波器或万用表确认脉冲波形异常再动手不然你改了半天可能只是自己骗自己。5.2 卡货与出货检测失败的判定逻辑卡货是自动售货机最常见的现场故障也是最难处理的一种。我的做法是把“检测逻辑”留出足够宽的窗口而不是只靠光电信号。具体是这样电机启动后即使在设置时间内光电没触发也不立刻认为故障而是再给一次“重试”机会——第一次5秒内未检测到出货电机停止2秒复位后再自动启动一次第二次如果还没检测到才置位故障位。为什么这么设计因为货物在货道里位置偏移、弹簧没有完全挂住货物都是常见偶发情况一次失败不能说明机械真的坏了给一次重试机会能把大量假故障自动化解掉运营维护成本会低很多。另外光电传感器的安装位置也很有讲究。我一开始把出货检测光电装在货道出口正下方结果发现货物下落时经常擦着光电边缘滑过检测不到。后来我把它挪到取货口斜面回口的位置让货物必须从光电检测区经过可靠性大大提高。5.3 电磁干扰和误动作怎么定位现场调试时碰到过一次很奇怪的现象某个继电器输出动作的瞬间PLC的一个输入点会短暂闪烁一下程序里就会误触发一次。排查思路我总结成三步第一步观察故障是否和某些输出动作强相关——如果是怀疑是感性负载的反向电动势通过公共端串到了输入回路第二步检查输出端有没有续流二极管没有就先补上第三步检查输入线缆和输出线缆是否走同一个线槽弱电信号容易被强电干扰。那次故障最后就是两个问题叠加电机没有续流二极管且输入信号线和电机电源线扎在了一起。加了续流二极管、重新分开布线之后问题彻底消失。5.4 通信故障排查的优先级通信问题在调试后期也遇到过几次触摸屏偶尔显示乱码、数据不刷新。我排查的顺序永远是先信物理层再看参数最后怀疑程序。物理层看接线是否牢固、屏蔽层有没有单端接地、通信距离是否太远参数看波特率、站号、协议类型程序看寄存器地址有没有写错、数据类型是否匹配。这个顺序能避免很多瞎忙我见过有人一遇到通信问题就改程序改了半天发现是通信线松了。故障现象排查方向优先级