ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

S7-200 PLC与组态王自动售货机项目实战:从梯形图到上位机监控

S7-200 PLC与组态王自动售货机项目实战:从梯形图到上位机监控 搞PLC这行的人十有八九都绕不过“毕业设计”或者“入门实战”这道坎。而S7-200配合组态王这对组合在国内工控圈的地位就像练武之人的木人桩——不花哨但桩桩件件都是基本功。这套基于S7-200 PLC和组态王打造的5种商品自动售货机听起来就是个典型的教学型项目但真正落地做一轮之后你会发现它把PLC开发里最核心的几块骨头全占了I/O分配、梯形图逻辑、定时器应用、通信组态、上位机监控画面设计、还有现场联调排障。这些能力不是说看两遍书就能会的必须要亲手把一个项目从零跑到通。这篇文章我就把自己做这个项目的完整过程、程序思路、组态细节和踩过的坑全盘托出。不管你是正在做课程设计的学生还是刚入行想找个实例练手的初级工程师照着这条线走一遍比闷头刷十套题都管用。1. 系统总体架构与控制需求拆解1.1 5种商品自动售货机的核心功能需求在动笔写程序之前先把需求掰开揉碎。很多人上来就写梯形图结果写到一半发现I/O不够用或者逻辑绕成一团根源就是需求没理清。这套自动售货机要完成的事情其实就五件事识别投币、累计金额、选择商品、控制出货、找零退币。除此之外还得加上一些状态指示和异常保护。商品内容可以自己定义我用的是常见的五种分类饮料、矿泉水、薯片、饼干和巧克力价格分别设为3元、2元、5元、4元和6元。5种商品对应5个选择按钮投币支持1元、5元、10元三种面额。核心控制逻辑是当投入金额大于等于所选商品价格时允许出货出货完成后如果有多投的金额系统自动找零。这里有个容易被忽略的需求找零怎么实现。如果做成实物设备找零一般靠退币电磁阀或者找零电机来实现每次退一枚硬币。因为无法准确区分币值退币逻辑就是按剩余金额的多少循环退出一元硬币。程序里用比较指令加自减循环来处理模拟仿真时用一个输出点驱动退币执行机构实机上则接退币电机。另外一个隐藏需求是存货检测。如果仓道里已经没有货了用户投了币选了这个商品钱扣了货不出这就属于事故了。所以每个商品的出货通道上装了微动开关或者光电传感器用于检测是否有货。检测到缺货时系统会禁止售卖该商品并在组态画面上给出缺货报警提示。1.2 为什么选S7-200和组态王而不是其他方案先说PLC。S7-200是西门子经典的小型PLCCPU 224型号自带14个数字量输入和10个数字量输出对这套系统来说刚好够用不需要扩展模块。更重要的是S7-200在国内保有量巨大资料满天飞哪怕你手头只有一台二手设备坏了也容易找替换。它的编程软件STEP 7-Micro/WIN虽然是老界面但梯形图编辑、符号表管理、状态表监控这些核心功能都很顺手对初学者极其友好。组态王这边它是由亚控科技出品的国产组态软件在国内工控现场占有率很高。它的优势在于上手门槛低、变量定义直观、画面组态拖拽就能完成而且内置了大量PLC驱动比如S7-200的PPI驱动就是开箱即用。相比WinCC那种偏重型的上位机方案组态王更适合中小型项目和教学场景。有一点要提醒S7-200的通信口是PPI协议组态王通过PC/PPI电缆或者CP5611卡跟PLC通信。电脑没有串口的话要买一条USB转PPI的编程电缆驱动装好后在设备管理器里能看到虚拟串口这个后续通信配置要用。选型思路就是设备够用、驱动齐备、资料好找这三条比参数堆得高更重要。1.3 系统硬件清单与I/O地址分配硬件清单列出来照着准备就行不用追求高端型号关键是要稳定。序号器件名称型号/规格数量作用1PLC西门子S7-200 CPU2241台控制核心2组态王6.53或7.51套上位机监控3编程电缆USB-PPI1根下载程序与通信4投币器支持1/5/10元脉冲输出1个投币识别5商品选择按钮自复位按钮5个选货6出货电机直流减速电机或推货电磁铁5个商品推出7存货检测光电开关/微动开关5个缺货检测8退币电机直流电机1个找零9指示灯24V LED6个状态指示10急停按钮红色自锁1个紧急停止I/O分配是整个项目的地基我按CPU224的地址规划如下输入信号I0.01元投币信号脉冲I0.15元投币信号脉冲I0.210元投币信号脉冲I0.3~I0.75个商品选择按钮I1.0~I1.45个货道存货检测光电开关I1.5退币按钮手动触发找零I1.6急停按钮常闭I1.7投币器故障检测可选输出信号Q0.0~Q0.45个出货电机Q0.5退币电机Q0.6运行指示灯绿色Q0.7报警指示灯红色这里特别注意两点。第一I0.0到I0.2接的是投币器的脉冲输出投一枚币导通一次程序里用上升沿加计数。如果投币器是不同币值对应不同输出口就按我这个接法如果是单口串行输出需要在程序里做协议解析那个复杂度会高不少教学场景一般用前者。第二急停按钮用的是常闭触点一旦按下输入信号断开程序里串联这个信号能立刻切断所有输出。2. PLC程序设计与梯形图逻辑拆解2.1 程序总体结构与变量规划S7-200的程序结构分主程序、子程序和中断程序三层。这个项目正常情况下轮询处理即可不需要中断所以按主程序加子程序的框架来写。我分了四个子程序投币处理、选择出货、找零处理、状态显示。主程序负责调用和逻辑汇总。变量规划上用V存储区定义内部变量。核心变量如下变量名地址类型说明当前金额VB10字节投币累计金额单位元商品1~5库存VB11~VB15字节0缺货 1有货选择商品编号VB16字节记录用户选中的商品出货计时T37~T41定时器5个商品各自的出货时间退币循环计数VB20字节退币时记录剩余需退金额投币锁存M0.0位投币期间的锁存标志出货标志M0.1~M0.5位对应5个商品的出货状态这里说一个很关键的编程习惯尽量用符号名编程不要直接拿I0.0、Q0.0这种绝对地址写程序。在STEP 7-Micro/WIN的符号表里把每个I/O和变量定义好名字程序里显示符号看起来一目了然改地址也不用全程序翻找。2.2 投币金额累计逻辑投币处理是所有逻辑的起点。因为投币器输出的是一路脉冲信号每检测到一个上升沿代表投了一枚对应面额的硬币。梯形图里用上升沿指令配合加法指令把当前金额累加。1元投币这段的逻辑是这样的I0.0上升沿触发ADD_B加法运算把1加到VB10里。但如果连续快速投币脉冲时间很短PLC扫描周期又比较快理论上不会丢脉冲。不过实机上有个细节投币器的脉冲可能在20毫秒左右PLC的输入滤波如果设置得太长会吃掉信号。CPU224的数字量输入滤波默认为6.4毫秒20毫秒的脉冲没问题但如果芯片老化导致脉冲被拉窄可以考虑在系统块里把I0.0~I0.2的滤波时间调到0.2毫秒。5元和10元的逻辑一样只是加的值不同。同时要做一个上限保护如果当前金额超过50元就不再累加防止恶意投币超出找零能力。用指令表描述一下1元投币的核心Network 1 检测1元投币上升沿 LD I0.0 EU LDN M0.0 M0.0 Network 2 金额累加 LD M0.0 MOVB VB10, AC0 ADDB AC0, 1 MOVB AC0, VB10实际上更简洁的做法是用ADD_B直接对VB10操作S7-200的字节运算可以直接写到V区。这里用AC0中转是为了防止扫描周期内多次重复相加实际用上升沿MOVB就够了。这个模块里要特别注意金额数值的单位。S7-200没有浮点货币类型我用整数表示元所以VB10最大255够用了。以后如果要做角分的精度就得用两个字节分别存元和角逻辑会复杂一些但思路一样。2.3 商品选择与出货控制逻辑商品选择的核心是一个“金额够不够”的判断。用户按下某个选择按钮后程序比较VB10和对应商品的价格如果当前金额大于等于价格则启动出货电机同时当前金额减去价格如果金额不够则亮起一个“余额不足”的提示灯并且不清除当前金额允许用户继续投币或者改选其它商品。以商品1价格3元为例伪代码逻辑如下Network 1 商品1选择按钮按下 LD I0.3 EU AN M0.1 M1.0 Network 2 检测库存 LD M1.0 LD I1.0 ALD M1.1 Network 3 金额判断 LD M1.1 LPS AB VB10, 3 AN M2.0缺货锁定标志 S M0.1出货标志 LPP AENO SUB_B VB10, 3梯形图里比较指令的用法和高级语言不太一样更多是用触点比较块。每个商品出货输出Q0.0由M0.1置位驱动同时启动一个定时器T37定时2秒。2秒后T37超时复位M0.1Q0.0断电电机停止一次出货完成。这里有一个特别关键的细节电机运行时间不能太短太短商品推不到位太长会把货物挤坏甚至烧电机。我实测2秒对于弹簧螺旋货道刚好如果你用的是推板式货道1秒基本就能推出去。这个值务必根据实际机械结构调试确定不要照搬。库存信号I1.0的加入方式要重点说。我把它放在金额判断之前串联进去库存为0时I1.0断开M1.1无法置位整个出货链路被掐断。这比在程序里写“库存为0就报警”更直接有效。2.4 找零退币控制逻辑找零是这套系统的灵魂。投币超出商品价格的部分需要退币电机逐个吐出1元硬币。怎么知道要退几个就是当前金额减1再减1直到减到0为止。每减一次Q0.5驱动电机转一圈吐一个币。程序逻辑用一个子程序循环实现Network 1 退币触发 LD I1.5 O M0.3 AN M2.0 M0.3 Network 2 退币循环体 LD M0.3 LPS AB VB10, 0 S Q0.5退币电机 TON T45, 20驱动1秒 LPP A T45 AN T46 MOVB VB10, AC0 DECB AC0 MOVB AC0, VB10 TON T46, 10间隔0.5秒让硬币掉落后再退下一枚这里的循环思路其实不复杂退币电机启动同时金额减1定时器走完一个周期后电机停间隔一小段时间再判断金额是否还有剩余有就继续退没有就关闭退币标志。实现上有两种写法一种是用定时器加跳转构造循环另一种是把退币总次数算出来然后每次触发上位机点一次。我采用定时器加状态位的做法因为它在梯形图里结构最清晰也方便看时序。实操中要小心退币电机的机械结构。如果电机堵转或者硬币卡住电流会升高严重的话烧掉输出点。有条件的话输出点加中间继电器PLC输出点本身过流能力有限S7-200的晶体管输出只有0.75A驱动直流电机最好中转一下。2.5 定时器与状态显示程序状态显示部分相对简单就是几个指示灯的逻辑。运行指示灯Q0.6在非急停且无报警时一直亮报警灯Q0.7在出现缺货或者投币器故障时闪烁报警。报警条件包括两个任意一个货道的库存传感器为0缺货或者退币电机过载信号触发这里我用I1.7作为故障输入有故障时断开。报警时可以用特殊标志位SM0.51秒脉冲来驱动闪烁S7-200的这个位用起来非常方便。定时器的选择上T37~T41和T45、T46都是TON型的100毫秒定时器定时精度足够。注意T37到T41的定时值不要设成一样的防止两个电机同时动作时定时器混乱实际上S7-200的定时器是各自独立的这里只是建议保持逻辑清晰。关于特殊标志位稍微扩展一下SM0.0是常ON触点主程序里一般用来驱动永不关闭的线圈SM0.1是首次扫描脉冲用于初始化SM0.5是1秒方波做闪烁刚好。很多新手不知道SM0.0的用法这里提一句以后写别的程序也用得上。3. 组态王画面开发与通信设置3.1 组态王与S7-200的通信配置组态王这边的工作第一步就是跟PLC建立通信。启动组态王后在工程浏览器左侧的“设备”节点里选择“PLC”然后找到“西门子”再选“S7-200”协议选PPI。通信参数的配置是新手最容易出问题的地方。S7-200的默认PPI地址是2波特率96008数据位、偶校验、1停止位。组态王里的串口参数必须和PLC保持一致。如果你用USB转PPI电缆在电脑设备管理器里看到的是COM3或者COM5之类的虚拟串口组态王里对应选这个串口号就行传输速率选9600。这里有个实用技巧S7-200的通信端口参数其实是在STEP 7-Micro/WIN的系统块里配置的。如果改过端口地址或者波特率下载程序时记得把系统块也下载进去否则PLC可能一直以默认参数运行组态王连不上排查半天最后发现是参数没同步。通信测试时在组态王的设备列表里右键该设备选择“测试”如果返回信息为“设备初始化成功”说明物理链路已经通了。我建议通信测试放在程序编写之前做先把链路打通后续调试心态稳很多。3.2 监控画面结构与变量登记画面设计遵循直观原则。主画面分四个区域商品展示区、投币与余额区、出货状态区、报警信息区。商品展示区放了5个商品图片旁边标注名称和价格。图片用组态王自带的图库或者自绘矩形加文字都可以不需要太精细关键是引导用户操作。投币与余额区放一个“当前金额”显示框一个“投币”按钮组态王里按钮可以关联命令语言按下时往PLC的对应变量写入置位信号。出货状态区每路商品对应一个指示灯绿色表示出货中红色表示缺货。变量登记是组态王里最花时间的环节。在“数据词典”里新建I/O变量时必须填对一个关键字段寄存器地址。S7-200的PPI驱动访问的是V区比如PLC里的VB10当前金额组态王里对应的寄存器就是V10数据类型选BYTE读写属性选“读写”。而I0.3这种输入点对应寄存器是I0.3读写属性只能选“只读”。这里有个匹配关系要牢记PLC地址组态王寄存器数据类型方向VB10V10BYTE读写Q0.5Q0.5BIT读写I0.3I0.3BIT只读M0.1M0.1BIT读写寄存器地址的映射规则是驱动封装好的V10就对应PLC的VB10不用自己换算。但如果PLC里用的是VW字组态王里类型就要选WORD长度对上才能正确显示。这种细节常常是画面数值不对的根源。3.3 画面动画与命令语言联动画面做好静态布局后就要做动态联动了。组态王的动画连接是通过“画面对象属性”里的“动画连接”弹窗来配置的——选中一个显示框在“模拟值输出”里关联“当前金额”变量显示格式设成整数再选中出货指示灯在“颜色动画连接”里关联对应出货状态位设置状态为1时显示绿色、为0时显示灰色。按钮的联动一般用命令语言脚本。比如“投币1元”按钮按下事件里写\\本站点\投币1元命令 1;然后在PLC程序里加一段轮询逻辑检测到组态王的这个M区位置位后模拟一次投币脉冲完成后将M区复位。这样做的原因是组态王直接写I区有时不生效用M区做中间变量是最稳的通信方式。这里我要特别强调一个组态王脚本的坑命令语言里的变量名要加上“\本站点\”前缀这是组态王内部寻址方式写错一个字都执行不了。而且里面的计数、循环、延时逻辑建议能放在PLC里就放在PLC里组态王的脚本执行不是实时系统做时序控制容易出偏差。3.4 实时报警与数据记录配置报警功能在组态王里可以做成弹窗和光带提示。在“报警与事件”节点里为每个缺货信号建立一条报警定义报警类型选“状态报警”设置值为1时触发报警报警文本写成“商品1缺货”。这样当PLC里库存信号变成0时组态王的报警窗口会自动弹出记录。数据记录用于统计售卖情况。在“实时数据库”里把每个商品的出货次数定义成变量用历史曲线或者数据报表来展示。不过这个项目如果只是教学演示数据记录可以放到后期扩展前期把画面和通信跑通才是重点。组态王还有一个很实用的功能是“模拟运行”。在没有真实PLC的情况下可以用模拟驱动模拟变量变化先检查画面逻辑。这个功能适合你在电脑上把画面开发完成后在实验室现场调试前先自测一遍。4. 联调实测与程序下载4.1 STEP 7-Micro/WIN程序下载步骤程序在STEP 7-Micro/WIN里写完编译通过后就可以下载了。下载前先在软件左侧浏览条里设置通信参数在“通信”节点双击弹出通信设置对话框双击PC/PPI电缆的图标把波特率设为9600确认地址是0电脑端地址然后点“确定”保存。之后点工具栏上的“下载”按钮软件会弹出搜索设备的对话框。如果链路正常会显示“找到CPU224”勾选“程序块”、“数据块”、“系统块”三个选项点下载。第一次下载系统块时PLC会停止运行一小段时间这个是正常的。下载完成后把CPU的RUN/STOP开关打到RUN或者用软件工具栏的“运行”按钮在线启动CPU。然后打开“状态图表”把VB10、Q0.0、I0.3这几个关键地址填入用“监控”功能观察数值实时变化。这一步就是PLC调试的核心——不用组态王先用状态表确认逻辑是否正确。4.2 模拟器与实机的差异说明很多学生没有实体PLC用S7-200模拟器比如B25C版本跑程序。模拟器能验证梯形图逻辑但有几个地方和实机差异很大模拟器不真实支持PPI通信组态王连不上模拟器对定时器扫描周期的模拟并不完全实时有些复杂程序的时序会失真模拟器没有真实的I/O接线按钮、传感器的信号变化只能靠手动置位来模拟。所以我的建议是逻辑验证用模拟器通信联调必须上真机。如果实验室设备紧张至少也要用S7-200的实体机配一个编程电缆组态王里才能真正看到数据变化。有一次我在现场调试程序在模拟器里跑得好好的一上实机就出现电机不停转的问题。后来定位到是模拟器里定时器的复位时序和实机不同——实机扫描周期快定时器断开条件在置位前就满足了导致输出一直合上。所以千万别拿模拟器跑通就当完工实机测试才是硬道理。4.3 联调操作流程记录联调阶段按这个顺序走能少走很多弯路第一步空载测试。先不装商品逐个按键测试5个出货电机是否动作定时器到点能否自动停止确认电机的正反转方向正确。第二步投币测试。用投币器实际投1元、5元、10元观察组态王画面上的“当前金额”是否对应累加如果数值乱跳或不变优先查通信和变量类型。第三步选货测试。投入足够金额按下商品按钮观察电机动作和金额扣减。这里要仔细听电机运行声音机械卡顿会导致货物推不出去但PLC已经扣钱了。第四步找零测试。投10元买3元的商品应该退7枚硬币。逐枚观察退币是否连续、中间有没有卡币。第五步缺货测试。手动把某个货道的库存传感器触发成断开状态再投币选该商品确认系统拒绝出货并弹出报警。整个联调最耗时的是“机械卡顿”问题。电机的推力只有那么大货道调整不好就容易卡住而且这一卡PLC程序是感知不到的只有靠库存传感器或者光电检测才能发现。所以如果条件允许在每个出货通道末端加一个“出货确认”光电开关货出去了给一个信号程序里增加“出超时报警”逻辑——电机运行5秒后还没收到出货确认信号就报故障并停机。这个思路是所有售货机项目的标准做法比单纯依赖定时器靠谱得多。4.4 程序修改与在线监控技巧联调时改程序是常态。STEP 7-Micro/WIN支持在线编辑但有一个前提修改多个网络时最好先把PLC切到STOP状态下载完再切回RUN。如果在RUN状态向正在运行的PLC下载程序CPU可能会因为程序瞬时不一致而停机尤其是在修改数据块的时候。在线监控状态表的用法值得多说几句。状态表里可以输入定时器当前值、V区数据、I/O状态还能强制某些位为1或0。我在调试找零逻辑时就是用状态表强制M0.3为1观察VB10的递减过程很快发现了退币计数少了一次的问题——原来是LPS/LPP堆栈操作把比较结果压栈后没有正确恢复。这种问题不看在线状态很难查。5. 常见故障排查与避坑总结5.1 典型故障现象与处理方法做一个常见问题速查表方便你现场照着查故障现象可能原因处理方法组态王连接PLC超时波特率不一致、串口号选错、PPI地址错误检查系统块参数与组态王设置一致重插电缆确认COM口投币金额不增加输入滤波吃掉脉冲、投币器光电管脏污、上升沿指令误用调整系统块滤波时间清洁投币器检查梯形图EU位置电机动作但商品不出弹簧货道卡涩、电机扭矩不足、推板位置偏调整货道间距换更大扭矩电机检查机械结构电机一直转不停定时器没启动、复位条件错误、双线圈输出检查T37~T41的TON指令和R复位指令是否成对组态画面数值不刷新变量类型不匹配、寄存器地址映射错误、通信中断核对数据词典变量类型用设备测试功能检查通信退币数量不对退币循环逻辑栈操作错误、退币检测误差检查LPS/LPP堆栈指令逐步监控VB20的递减过程缺货报警误报传感器安装位置不当、信号波动调整传感器位置必要时在程序里加20毫秒延时滤波接线问题上如果发现某个输入点信号不受控制地通断大概率是线路接触不良或者PLC输入端的COM端没接好。S7-200的漏型输入要求外部电源负极接到COM端这个细节接错了一整排输入全部失灵。调试时先拿万用表量输入点的电位再进程序查逻辑顺序不能乱。5.2 程序编写中的双线圈陷阱写梯形图时双线圈是初学者最容易犯的错误。所谓双线圈就是同一个输出点在程序里被多处赋值比如Q0.0在第一段被置位又在另一段被复位。S7-200对这样的程序并不会直接报错但实际运行时最终输出只取决于最后一个被执行的线圈指令前面的逻辑等于白写了。这个项目的出货控制里我就遇到过典型教训Q0.0既要受M0.1驱动又要受急停信号控制。如果我在两段程序里分别写“LD M0.1 Q0.0”和“LDN I1.6 Q0.0”那么急停信号就会被第一段覆盖掉急停根本不起作用。正确的做法是把这个输出集中到主程序的末尾统一驱动前面只处理中间变量M区最后一段把所有条件汇总到一起再输出到Q点。这也是工业PLC编程里“集中输出”原则的由来养成这个习惯能少踩无数坑。5.3 通信干扰与信号稳定措施工业现场的电磁干扰是个容易忽视的问题。PLC和组态王通过串口连接时如果通信线跟电机电源线扎在同一个线槽里电机一启动通信就容易丢包。表现为组态画面数值跳动、按钮指令有时生效有时不生效。解决办法有几种通信线跟动力线分开走间距至少20厘米通信线用屏蔽双绞线屏蔽层单端接地电机驱动加续流二极管抑制反向电动势投币器和PLC之间用屏蔽线信号地单独接。还有一个更省事的方案把PPI通信改成以太网通信S7-200加一个CP243-1以太网模块组态王走TCP/IP连接抗干扰能力和传输速度都会好很多。当然这个方案成本会高一点教学项目按需取舍。5.4 程序备份与工程管理习惯最后说点项目管理的经验。程序写一半时PC崩溃或者Micro/WIN闪退直接丢半天工作量这是多少人都经历过的噩梦。我的习惯是每完成一个功能模块就另存一个版本文件比如“Vending_V1.0_投币模块”、“Vending_V1.1_出货模块”单独放在一个文件夹里。组态王的工程也要定期备份拷贝整个工程目录包括数据词典和画面文件。版本编号用日期后加序号的方式更明确例如“Vending_0615_01.pwm”。改程序前先备份当前可运行版本万一新逻辑测试失败可以秒回退。这个习惯在工业项目里叫配置管理学生阶段就开始养成到了真正进项目组会非常受益。关于安全和合规方面多说一句如果这套系统以后要放进实际商业场景运营机械安全防护、电气接地、防漏电保护这些都要严格按照标准来不能只在程序层面上保证逻辑正确。教学和演示场景下也必须确保外围设备的机械结构没有夹手风险、电机选型合理不过热这些都符合公序良俗和安全底线。从整体来看这个项目最大的价值不在于它有多复杂而在于它把自动化控制系统开发的完整链路走了一遍。硬件选型、I/O分配、梯形图逻辑、通信组态、上位机画面、现场联调、故障排查每一个环节都是以后吃饭的家伙。我自己在带学生做类似项目时发现凡是这套流程认真走完的后面接触任何中小型PLC项目都能很快上手。最后再分享一个小技巧不要把商品数量限定死在5种程序里用数组存价格、用循环遍历处理选择逻辑以后要扩成8种、10种商品只需要改数据块和组态画面梯形图主体纹丝不动。这就是结构化编程的好处也是项目做完之后值得回头重构一次的原因。
返回列表