
简介面向自动化、机电一体化及电气控制相关专业师生与PLC初学者这份基于PLC的大小球分拣系统设计文档以三菱FX2N系列可编程控制器为核心通过控制机械臂上下、左右移动以及抓取与释放动作完成大球与小球的自动分类传送可用于课程设计、毕业设计选题参考和PLC控制逻辑入门练习。压缩包内共1个docx文件约251KB正文按概述、硬件设计、软件设计、软硬调试等章节展开包含主电路设计、I/O地址分配及接线图、元件选型以及系统流程图、顺序功能图、梯形图与指令表、程序分析等内容并附使用说明、设计感想和参考文献目录结构完整。目前已有643人学习下载读者可据此了解从控制要求分析到梯形图编程、再到联机调试的完整思路适合作为PLC顺序控制类项目的仿写与排错参考。1. 用PLC做大小球分拣为什么比单片机方案更稳一条钢球分选线上直径 20 mm 和 40 mm 两种球混装从振动盘上料落到传送带上依次经过检测位带末必须在几百毫秒内把大球推进侧向料道慢了两种球就撞在一起。这类工位在教学实训台和中小型产线上非常常见基于PLC的大小球分拣系统设计这个题目考的不是分拣这个动作而是三件事传感器能不能稳定区分直径、程序能不能在球到达推杆位置的那一刻准时输出、参数改了以后现场的人能不能自己调回来。单片机方案在实验室跑得通一到车间就露怯24 V 电磁阀断电时的反电动势、粉尘、后期多加一个工位就得重画板子。PLC 的价值在于 I/O 模块化、梯形图可维护现场电工拿着图纸就能改一段逻辑这是 PLC 编程 被产线选中的真实原因。这套设计要落地需要一条完整的链路I/O 点表、带速与遮光时长的换算、状态步序程序、气缸动作时序以及现场误判的排查顺序。适合做 PLC 课程设计 的学生、刚从电气转自动化的工程师以及要把分拣做成标准工位的人。2. 大小球分拣系统的硬件选型与I/O点表设计2.1 传送、检测、执行三段各自的器件怎么挑整条线拆成三段看传送段负责把球按固定间距送出来检测段负责量直径执行段负责把大球拨走。传送段最常见的是三相异步电机加减速机配变频器也有用步进的步进的好处是带速恒定缺点是成本和调试量都上去了。我一般先按 0.20.5 m/s 这个区间定带速因为再快就会把检测段的余量吃干净。检测段是整套系统的精度来源。两种球差 20 mm听起来很好分但光电开关的响应时间和光斑直径会一起吃掉有效时间。选型时优先看响应时间1 ms 以内的对射式光电是基本要求光斑直径要明显小于小球直径否则小球遮光时间被拉长直接判成大球。环节常用器件选型要点容易踩的坑传送三相异步电机 减速机 变频器带速 0.20.5 m/s能整定变频器频率漂移导致测径误差检测对射式光电开关响应 ≤1 ms光斑小于小球直径用漫反射式背景反光误触发执行双作用气缸 二位五通电磁阀缸径按推力算行程盖住料道口不加调速阀推杆冲击把球打飞控制PLC 本体 DI/DO 模块输入点数留 20% 余量公共端接反输入全不亮2.2 按工艺动作拆 I/O 点表留 20% 余量点表不要照着器件抄要照着动作拆。整机动作只有四个启动输送、检测球径、延时到位、推杆分拣再加急停和报警。按这个拆输入点会落在 68 个输出点 4 个左右选 14 点或 16 点的本体就够但我会直接上 24 点的机型因为料道满检测、气缸缩回到位这些点早晚要加。地址符号名类型说明I0.0InletSensorDI入口光电球到达检测位为 1I0.1SizeSensorDI测径光电遮光为 1I0.2CylFrontDI气缸伸出到位磁开关I0.3StartBtnDI启动按钮常开I0.4StopBtnDI停止按钮常开I0.5EStopOKDI急停回路正常为 1Q0.0ConveyorDO传送带接触器Q0.1DiverterDO分拣气缸电磁阀Q0.2RunLampDO运行指示灯Q0.3AlarmLampDO故障报警灯同样的点表换成三菱 FX 系列就是 X0X5 对应输入、Y0Y3 对应输出逻辑一模一样。做 I/O 点表时把符号名一次写好后面写梯形图还是写 SCL 都省事这也是 PLC 编程入门基础知识 里最容易被跳过、又最影响后期维护的一步。2.3 输入映射与公共端的接线细节PLC 的物理输入不要直接散落到程序各处先做一层语义映射。这样换机型或者改点位时只需要动映射这一处梯形图和 SCL 都不用碰。西门子博途里可以用一个全局 DB 存映射结果也可以用 M 区看团队习惯。// 输入信号映射物理地址 - 语义变量 // 建议放在 OB1 的第一个网络每周期执行一次 InputMap.InletSensor : I_0_0; // 入口光电球到达时 1 InputMap.SizeSensor : I_0_1; // 测径光电遮光时 1 InputMap.CylFront : I_0_2; // 气缸伸出到位到位 1 InputMap.StartBtn : I_0_3; // 启动常开接法 InputMap.StopBtn : I_0_4; // 停止常开接法 InputMap.EStopOK : I_0_5; // 急停串在安全回路里正常 1映射段本身没有逻辑它的价值在后面所有功能块只引用语义变量不引用 I 地址。参数上要注意急停信号接常闭回路进 PLC 时正常状态是 1一旦断线或按下急停就变 0程序里用NOT EStopOK判断停机比用常开接法安全因为断线也会触发停机。接线层面还有两个细节值得单独说。一是输入公共端NPN 型传感器要配漏型输入PNP 型配源型输入。二是电磁阀线圈一定要并续流二极管靠 PLC 输出点自己扛反电动势短期看不出问题几个月后输出点就会粘死。提示气缸的进出气口都装上调速阀把推杆伸出速度调到 0.2 s 左右。速度太快会把球弹到料道外面后面再排查会以为是程序问题。3. PLC分拣程序状态步序、球径判定与定时器整定3.1 用状态步序替代一排自锁回路新手写分拣程序容易写成一堆自锁启动按钮自锁传送带、光电自锁延时、延时到位自锁气阀。段数一多中间继电器满天飞改一处逻辑就要顺着看十几行出故障时根本不知道停在哪一步。PLC 梯形图 里更稳的写法是状态步序一个整数变量表示当前步每个扫描周期只执行当前步的动作和跳转条件。这套系统的步序很干净0 待机、10 输送中、20 气阀动作、30 气阀复位、90 停止。急停和停止按钮可以直接从任意步跳到 90出问题时看一个变量就知道机器卡在哪一环。步序还有个好处在调试期用编程软件的监控表盯着 Step 这个变量球走到哪一步、卡在哪一步一眼就能看见比在梯形图里顺着看输出点快得多。3.2 球径怎么算带速乘遮光时间球经过对射光电时会遮挡光路一段时间这段时间等于球的直径除以带速。带速 0.3 m/s 时20 mm 小球遮光约 67 ms40 mm 大球约 133 ms两个数差了一倍中间留出 100 ms 做阈值就很稳。这里的关键是带速必须准用变频器面板显示的频率反推带速误差太大我一般用秒表量球从测径位走到分拣位的时间反推实际带速再写进参数。除了判定阈值还需要一个输送延时。测径位和分拣位之间有一段距离 L球走完这段要用 L/v程序在检测到球通过后延时这么久再决定要不要开阀。L 取 150 mm、v 取 0.30 m/s 时延时正好是 500 ms。参数符号典型取值说明带速v0.30 m/s用秒表实测反推不信面板显示检测位到分拣位距离L150 mm机械安装尺寸卡尺量输送延时T_Delay500 msL / v小球遮光时长t_small约 67 ms20 mm / v大球遮光时长t_big约 133 ms40 mm / v判定阈值T_Threshold100 ms取两值中间两侧余量约 30%气阀保持时间T_Blow200 ms保证球离开料道口3.3 分拣核心逻辑的 SCL 实现时间测量用上升沿启动定时器、下降沿读当前值的方式。注意定时器每个扫描周期只能调用一次把调用放在 IF 分支里是常见错误会导致计时值跳变。下面的写法和状态步序合在一起梯形图和 SCL 都能照这个结构搭。FUNCTION_BLOCK FB_BallSort VAR_INPUT InletSensor : Bool; // I0.0 入口光电球到达 1 SizeSensor : Bool; // I0.1 测径光电遮光 1 CylFront : Bool; // I0.2 气缸伸出到位 StartBtn : Bool; // I0.3 启动常开 StopBtn : Bool; // I0.4 停止常开 EStopOK : Bool; // I0.5 急停回路正常 1 T_Delay : Time : T#500MS; // 输送延时由 L/v 算出 T_Threshold : Time : T#100MS; // 大球判定阈值 T_Blow : Time : T#200MS; // 气阀保持时间 END_VAR VAR_OUTPUT Conveyor : Bool; // Q0.0 传送带 Diverter : Bool; // Q0.1 分拣气缸电磁阀 RunLamp : Bool; // Q0.2 运行指示 Alarm : Bool; // Q0.3 气缸超时报警 END_VAR VAR RiseEdge : R_TRIG; FallEdge : R_TRIG; WidthTimer : TON_TIME; // 遮光时间计时 WidthEnable : Bool; DelayTimer : TON_TIME; // 输送延时 DelayEnable : Bool; BlowTimer : TON_TIME; // 气阀保持 CylTimer : TON_TIME; // 气缸到位监视 Step : Int : 0; // 当前步序号 IsBigBall : Bool; PulseWidth : Time; BigCount : DInt; // 大球计数验收用 SmallCount : DInt; // 小球计数验收用 END_VAR BEGIN // ---- 边沿检测 ---- #RiseEdge(CLK : #SizeSensor); #FallEdge(CLK : #SizeSensor); // ---- 定时器每周期只调用一次 ---- #WidthTimer(IN : #WidthEnable, PT : T#1S); #DelayTimer(IN : #DelayEnable, PT : #T_Delay); #BlowTimer(IN : #Diverter, PT : #T_Blow); #CylTimer(IN : #Diverter AND NOT #CylFront, PT : T#500MS); #Alarm : #CylTimer.Q; // ---- 遮光时间测量上升沿起表下降沿锁存 ---- IF #RiseEdge.Q THEN #WidthEnable : TRUE; END_IF; IF #FallEdge.Q THEN #WidthEnable : FALSE; #PulseWidth : #WidthTimer.ET; // 锁存本次遮光时长 IF #PulseWidth #T_Threshold THEN #IsBigBall : TRUE; #BigCount : #BigCount 1; ELSE #IsBigBall : FALSE; #SmallCount : #SmallCount 1; END_IF; #DelayEnable : TRUE; // 触发输送延时 END_IF; // ---- 状态步序 ---- CASE #Step OF 0: // 待机 #Conveyor : FALSE; #Diverter : FALSE; #RunLamp : FALSE; IF #StartBtn AND #EStopOK THEN #Step : 10; END_IF; 10: // 输送中 #RunLamp : TRUE; #Conveyor : TRUE; IF (NOT #EStopOK) OR #StopBtn THEN #Step : 90; END_IF; IF #DelayTimer.Q THEN // 球已到分拣位 #DelayEnable : FALSE; IF #IsBigBall THEN #Step : 20; // 大球推入大球道 END_IF; END_IF; 20: // 气阀伸出 #Diverter : TRUE; IF #BlowTimer.Q THEN #Step : 30; END_IF; 30: // 气阀复位 #Diverter : FALSE; IF NOT #BlowTimer.Q THEN #Step : 10; END_IF; 90: // 停止 #Conveyor : FALSE; #Diverter : FALSE; #RunLamp : FALSE; IF #StartBtn THEN #Step : 0; END_IF; END_CASE; END_FUNCTION_BLOCK逻辑说明边沿检测和三个定时器的调用放在 CASE 之前保证每个扫描周期定时器只被调用一次WidthTimer计时上限设 1 s超过这个值说明光路被长期遮挡或传感器损坏读到的值一定是大球会被判错所以上限值本身就是个异常信号。DelayTimer用使能位控制启停比在 CASE 里直接调用可靠。CylTimer监视气阀通电后 500 ms 内气缸是否伸出到位不到位就报警这是最早能发现气压不足的地方。参数说明T_Threshold是最核心的一个值改带速或者换球径都要重算T_Delay只跟安装尺寸和带速有关机械不动就不用改T_Blow一般给 150250 ms给短了推杆提前缩回球会卡在料道口。3.4 定时器与计数器的参数整定表定时器不是拍脑袋给的每个值都有对应的物理量。整定时按下面这个顺序走先用秒表量实际带速再算阈值和延时最后微调气阀保持时间。整定完之后把这三个值记录下来换品种时要重新算。定时器时间基准整定依据异常表现WidthTimer1 s 上限最长遮挡时间长期计时说明光路遮挡DelayTimer100 ms 分辨率L / v偏大球被推空偏小球没到就推BlowTimer10 ms 分辨率推杆行程 / 推速偏短卡料偏长打乱节拍CylTimer100 ms 分辨率气缸全行程时间 余量频繁报警说明气压不足计数方面BigCount和SmallCount不是装饰。整机跑一小时以后这两个数加起来应该等于上料球数如果对不上说明有球从测径位溜过去了问题在检测段而不是执行段。这个判断能省掉大量盲猜。注意所有 Time 类型参数的比较都用 TIME 类型直接比不要转成整数毫秒再比。不同机型对时间内部单位的处理不一样直接比较能避开这个差异。4. 分拣误动作排查从传感器标定到扫描周期4.1 误判大球、漏推、推空的成因对照现场出问题时先分清楚是识别错了还是执行错了。识别错的典型特征是计数对不上执行错的典型特征是计数对得上但落料位置不对。按照下面这张表顺序排查八成的问题在前两行就能定位。现象优先怀疑现场动作小球被推进大球道阈值偏小或光斑大于小球直径监控 PulseWidth 实测值重算阈值大球漏推输送延时不准带速漂移秒表复测 L/v检查变频器频率推杆推空气阀保持时间短或气压低保持时间加到 250 ms查减压阀无规律连续动作输入滤波太短干扰被当球DI 滤波时间由 0.1 ms 调到 3.2 ms气缸报警频繁节流阀开度小或电磁阀卡滞调大节流阀手动测试阀体动作表里最容易误判的是无规律连续动作。很多人第一反应是程序逻辑写错了其实是测径光电的输入滤波时间设得太短车间里变频器和高频设备的干扰被当成了一次遮光程序照样走完一整套分拣动作。4.2 带速一高就漏检输入滤波与扫描周期的边界带速提到 0.8 m/s 以上时20 mm 小球的遮光时间只剩 25 ms如果有干扰测量误差就会明显放大。这时候两个边界要盯住一是 PLC 数字量输入的滤波时间默认值通常在毫秒级球速快时滤波会把有效脉宽削掉一截二是扫描周期如果主程序里塞了大量浮点运算或者通讯扫描周期超过 10 ms边沿检测本身就会丢脉冲。实测办法很简单把测径光电的脉冲宽度用一个计数器累加跟理论值对比。差得不多说明是滤波差一个数量级说明是丢脉冲得把边沿检测挪到硬件中断里或者改用高速计数器模块测量脉宽。// 诊断段统计过球数、判大球数、气阀动作次数三者对照定位故障段 // 放在 FB 末尾或单独的诊断 FC 里 IF #RiseEdge.Q THEN Dbg.SizeEdgeCnt : Dbg.SizeEdgeCnt 1; // 测径位过球次数 END_IF; IF #FallEdge.Q AND #IsBigBall THEN Dbg.BigJudgeCnt : Dbg.BigJudgeCnt 1; // 判定为大球的次数 END_IF; IF #Diverter THEN Dbg.ValveOnCnt : Dbg.ValveOnCnt 1; // 气阀通电次数 END_IF; // 诊断结论 // SizeEdgeCnt BigJudgeCnt SmallJudgeCnt - 识别段正常 // BigJudgeCnt ValveOnCnt - 执行段正常这段代码没有控制作用纯统计。三个数一旦出现差值就能直接定位问题段SizeEdgeCnt大于两个判定数之和说明有球的遮光时间落进了不判定区间问题在定时器上限或者滤波BigJudgeCnt大于ValveOnCnt说明有判定没输出问题在步序跳转或者急停条件被误触发。整定期间可以把这三个数放到 HMI 上现场人员看到数值对不上就能打电话报故障段不用等工程师到现场。4.3 用三个计数做分拣准确率的验收验收不要靠肉眼看抓 100 个球大球小球按实际配比混装跑完统计三组数上料总数、大球道收料数、小球道收料数。准确率要求一般能做到 99% 以上达不到就按计数差值往回查。验收还要覆盖两个边界条件空载连续运行 30 min 看有没有误动作满载运行 10 min 看节拍能不能跟上这两个测试能暴露绝大部分偶发问题。5. 分拣参数配方化把球径阈值与延时交给HMI去改调试完成后真正决定这套系统好不好用的是换品种时改参数要花多久。把球径、带速、安装距离这些工程参数放进一个配方数据块换算在启动时做一次操作工只需要在 HMI 上填两个直径和一个带速。// 全局 DB分拣配方HMI 只读写这个块 DATA_BLOCK DB_Recipe VAR BallSmall_mm : Real : 20.0; // 小球直径 BallBig_mm : Real : 40.0; // 大球直径 BandSpeed_mps : Real : 0.30; // 实测带速 Distance_mm : Real : 150.0; // 测径位到分拣位 ValveHold_ms : Int : 200; // 气阀保持时间 ThMs : DInt; // 换算结果判定阈值 DelayMs : DInt; // 换算结果输送延时 END_VAR换算只需要两行因为长度用毫米、带速用米每秒时算出来的数值正好就是毫秒数省掉了单位换算这一步。距离 150 mm 除以带速 0.30 m/s 得 500直接就是 500 ms球径均值 30 mm 除以 0.30 m/s 得 100直接就是 100 ms。// 在启动步Step 0 跳 10 之前执行一次即可 DB_Recipe.DelayMs : REAL_TO_DINT(DB_Recipe.Distance_mm / DB_Recipe.BandSpeed_mps); DB_Recipe.ThMs : REAL_TO_DINT( ((DB_Recipe.BallSmall_mm DB_Recipe.BallBig_mm) / 2.0) / DB_Recipe.BandSpeed_mps); // 转成 TIME 后传给功能块 #T_Delay : DINT_TO_TIME(DB_Recipe.DelayMs); #T_Threshold : DINT_TO_TIME(DB_Recipe.ThMs); #T_Blow : DINT_TO_TIME(DB_Recipe.ValveHold_ms);配方之外还有一个技巧把ThMs和实测到的PulseWidth一起显示在 HMI 的趋势图上换品种时先空跑十几个球看实测脉宽落在阈值的哪一侧。大球实测值离阈值至少要有 20% 余量小球同理两边都够才说明带速稳定、光斑合适。这一步比反复调阈值有效得多很多怎么调都不准的情况根子在于带速本身在漂而不是阈值没找对。本文还有配套的精品资源点击获取