CODESYS 实战箱子分拣系统
我想要一个能逼我像控制工程师那样思考、而不只是写梯形图阶梯的项目。于是我搭建了一个按高度分拣的箱子分拣站。
博途PLC工程智能体 | AI智能体博途网关 | 博途PLC程序知识图谱 | 梯形图转SCL | 自然语言生成梯形图 | 自然语言生成SCL | 逆向生成程序块文档 | 梯形图在线查看 | 博途编程文档MCP | AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI
大多数 PLC 教程都把单条指令孤立地教——这里一个定时器,那里一个计数器。但真实的工业控制系统关注的是这些部件如何在真实约束下协同工作:安全联锁、传感器去抖、set/reset 信号相互竞争带来的竞态条件,还有机器绝不会因为你的逻辑还没跟上就停下来这件事。
我想要一个能逼我像控制工程师那样思考、而不只是写梯形图阶梯的项目。于是我搭建了一个按高度分拣的箱子分拣站:单条入口输送线接入一个 T 形路口,每个箱子在这里按高度分类,被分流到两条出口输送线之一——左线或右线——两侧各有计数器统计吞吐量,还有一个数字显示屏显示已处理的总箱数。我在 CODESYS 中编写逻辑,在 Factory IO 中模拟物理工厂,因此 PLC 程序必须驱动一套真实(虚拟)的机械系统,而不是仅仅切换布尔指示灯。
1、物理布局
该工作站是一条 T 形滚筒输送线:
- 箱子沿主线进入,在路口经过 Pallet_sensor,同时
High_sensor和Low_sensor就安装在交叉点上,箱子通过时测量其高度。 - 根据分类结果,路口把箱子导向 Transf_left 或 Transf_right 路径,各自通向自己的出口输送线(
Conveyor_left/Conveyor_right),并设有安全围栏。 At_left_entry和At_right_entry传感器位于每个分流器之后,确认箱子确实进入了正确的分支。- 路口处的本地控制面板装有启动、停止和急停按钮及状态指示灯——这是整个工作单元的实体 HMI。
- 安全围栏环绕整个路口和两条输出分支,与真实分流站的防护方式一致。
2、将 CODESYS 连接到 Factory IO

这两个应用本身并不直接通信——链路是一个 OPC UA 服务器,在本地以 opc.tcp://localhost:4840 托管,由 Factory IO 暴露,CODESYS 作为 OPC UA 客户端接入。Factory IO 场景中的每个物理传感器和执行器都映射为服务器上的一个命名标签,我再把这些标签直接绑定到 CODESYS 程序中的对应变量:
- 传感器 → PLC 输入:
At_left_entry、At_left_EXIT、At_right_entry、At_right_EXIT、High_sensor、Low_sensor、Pallet_sensor、Loaded、Emergency、Start、Stop、Reset——每个都是布尔标签,实时镜像 3D 场景中的光束传感器或按钮。 - PLC 输出 → 执行器:
Conveyor_entry、Conveyor_left、Conveyor_right、Transf_left、Transf_right、Load,以及Digital_Display和Counter这两个非布尔值,供面板读数使用。
这与真实机器上使用的集成模式相同:PLC 从不"知道"自己在驱动一个模拟——它只是通过工业协议读写标签。让 Factory IO 驱动和 CODESYS 变量列表中的标签名完全匹配是一个虽小但重要的步骤;只要有一个名字对不上,就意味着某段梯形图看起来正确、却永远不会在仿真中触发。
3、系统概览

整个流程端到端如下:
- 控制面板上的启动/停止/急停(Start/Stop/Emergency)控制整条线的主
Running状态。 - 箱子沿入口输送线行进,在路口触发 Pallet_sensor。
- 托盘传感器确认箱子到位,并锁存
Load状态。 - 箱子通过路口时,High_sensor / Low_sensor 这一对传感器将其分类为矮箱或高箱。
- 根据分类结果,箱子被送入右转移或左转移路径,每条路径都经由一个断电延时定时器驱动,使分流机构有时间在驱动信号消失前完成实际动作。
At_left_entry/At_right_entry确认箱子到达正确分支,并复位该侧的转移锁存。- 两个加/减计数器跟踪左右出口输送线上当前的箱数——进入时加一,从远端离开时减一。
- 另一个加计数器统计经由 Pallet_sensor 处理的总箱数,并驱动面板上的数字显示屏。
- **急停(Emergency)**几乎切断每一级阶梯,强制所有执行器进入安全状态,无论其他部分正在做什么——与接入围栏机柜的实体急停按钮一致。
4、逐段解析逻辑(梯形图)

主运行允许 (RS_0) 一个置位-复位锁存:Start 置位 Running,Stop 或 Emergency 复位它。程序的其他每一部分都以这个位为门控——除非系统真正在运行,否则什么都不动。

入口输送机控制 (RS_1) 入口输送机在 Running 为真时运行;一旦箱子在 At_left_entry 或 At_right_entry 处被识别就复位(上升沿、脉冲触发,使每个箱子只触发一次,而不是在传感器被遮挡的整段时间内持续触发)。当 Stop、箱子已 Loaded 或发生 Emergency 时也会复位——防止输送机把第二个箱子送进仍在处理前一个箱子的路口。

载荷检测 (RS_2) 一旦 Running 和 Pallet_sensor 同时为真,Load 即锁存。当下游 Loaded 触发时复位,或在 Stop/Emergency 时复位。这是"箱子物理上位于路口"与"系统已确认并准备好分类"之间的交接点。

高度分类 (RS_3) 这是实际的分拣决策,就在路口做出。Low_sensor 置位 box_Type,High_sensor 复位它。哪个传感器先触发,哪个就决定该箱的分类——这是编码二元决策的一种简单而稳健的方式,无需模拟量高度测量。

右/左转移 (RS_4 + TOF_0, RS_5 + TOF_1) 每个分支都有一个由 loaded 和相应 box_Type 值门控的置位-复位锁存,由该分支入口传感器(At_right_entry / At_left_entry)的脉冲或 Emergency 复位。输出馈入一个设定为 1 秒的 **TOF(断电延时)**定时器,使复位条件发生后分流器仍保持得电整整一秒——给 Factory IO 中的物理机构留出完成行程的时间,而不是在动作中途失去动力。Emergency 以串联方式接在输出线圈上,作为独立于锁存逻辑的最终安全切断。


输送机载荷计数器 (CTUD_0, CTUD_1) 加/减计数器:箱子到达该分支入口传感器时脉冲加计数,从输送线远端离开时脉冲减计数。Reset 和 Emergency 都会把计数器强制归零。这给出每条出口输送线上任意时刻精确在册的箱数——便于在堵塞或缓存溢出回灌到路口之前发现问题。

总吞吐量计数器 (CTU_0) 一个简单的加计数器,由 Pallet_sensor 触发,面板上的 Reset 按钮复位,预设值为 100。它的当前值馈入控制面板的 Digital_Display——已处理箱数的累计值,正是产线操作员会扫一眼的那种 KPI。
5、为什么选择 Factory IO
CODESYS 逻辑如果只是在测试台里驱动模拟布尔量,很难说明你的程序在真实机构上是否真的行得通。Factory IO 给了我 T 形路口的 3D 物理模拟,包括滚筒输送线、真实光束传感器,以及一个有实际行程时间的分流器——通过标准 I/O 映射连接到 CODESYS。这暴露出了一堆纸面检查永远不会发现的问题:
- 传感器脉冲需要边沿检测(
P触点)而不是电平检测,否则只要箱子在光束上多停留一会儿,计数器就会多计或少计。 - 转移输出上需要断电延时定时器——没有它,分流器会在箱子完全跨上分支输送线之前失去驱动力、卡在行程中途。
- 入口输送机重启与下一个箱子到达高度传感器之间的竞态条件,这促使我在
At_left_entry/At_right_entry上加入脉冲门控,而不是依赖原始传感器状态。 - 让路口几何和传感器位置(
High_sensor/Low_sensor恰好放在交叉点)调对,使分类在分流器必须决定方向之前可靠完成。
6、接下来我想改进的地方
- 用一个模拟量距离传感器加比较器替换两个离散高度传感器,以支持两类以上的分拣。
- 把面板上单一的数字显示屏扩展成完整的 HMI 屏幕,带故障指示和各分支实时计数。
- 把硬编码的定时器/计数器预设值改成一个小参数表,这样更换箱型时无需改动逻辑。
7、要点总结
这个项目的关键不在于某条单指令,而在于构建控制系统时的纪律——这套系统必须经受住与运动中的物理(哪怕是模拟的)工厂打交道:时序、边界情况,以及不能事后才补的安全联锁。如果你在学 PLC 编程,我强烈建议搭配 Factory IO 这样的仿真器——这是发现你的梯形图中哪些部分只是看起来正确的最快方式。
在 CODESYS 中构建,在 Factory IO 中模拟。很乐意分享完整项目文件或带你走查任意一段逻辑——随时联系我。
原文链接: Building a Box-Sorting System in CODESYS + Factory IO: A PLC Programming Project
汇智网翻译整理,转载请标明出处