这条传动带料箱输送线是我去年参与的一个老厂区智能化改造项目,核心任务是要实现料箱的自动分拣与目的地跟踪。系统整合了七个不同品牌的工业设备,包括英特诺直流辊筒电机、Sick条码阅读器、碧彩称重模块等,堪称"工业设备联合国"。最要命的是客户要求保留原有西门子S7-1500 PLC(1515-2 PN型号)和TP700 Comfort触摸屏,程序必须用STL语言开发,说是为了与遗留系统兼容。
关键挑战:不同设备的通讯协议五花八门,包括Profinet、Modbus RTU、TCP/IP三种主流协议,且各厂商的数据格式定义存在差异。
PLC:西门子S7-1515-2 PN,带双Profinet端口
HMI:TP700 Comfort触摸屏
| 设备类型 | 品牌型号 | 通讯方式 | 关键参数 |
|---|---|---|---|
| 直流辊筒电机 | 英特诺MultiControl | Modbus RTU | 速度范围0.1-2.5m/s |
| 条码阅读器 | Sick CLV620 | TCP/IP | 扫描频率200Hz |
| 称重模块 | 碧彩BIZERBA | Profinet | 量程0-50kg,精度±10g |
| 提升机变频器 | 丹佛斯FC系列 | Modbus RTU | 升降速度0.5m/s |
| 堆垛机 | MiniLoad | Anybus模块 | 定位精度±1mm |
设备布局图采用Eplan P8绘制,特别注意了以下细节:
电机控制卡MultiControl采用Modbus RTU通讯,在STL中需要处理字节顺序问题:
stl复制// 速度设定值转换流程
L "Speed_Setpoint" // 装载设定值(0-100%)
L 100
/I // 标准化
L 2.5
*R // 映射到实际速度(m/s)
T "Temp_Real" // 临时存储
// 字节顺序转换(MSB->LSB)
L "Temp_Real"
T DB100.DBD0 // 原始值存入DB块
L DB100.DBB3 // 取最高字节
T DB101.DBB0 // 存为最低字节
L DB100.DBB2
T DB101.DBB1
L DB100.DBB1
T DB101.DBB2
L DB100.DBB0
T DB101.DBB3 // 完成字节反转
// Modbus地址映射
L P#DB101.DBX0.0 BYTE 4 // 指向转换后数据
T "MultiControl_Speed" // Modbus映射地址
CALL "MB_MASTER" // 轮询发送
踩坑记录:初期未发现字节序问题,导致速度设定值在超过1.25m/s时出现跳变。通过Wireshark抓包分析Modbus数据帧才发现厂商使用LSB在前格式。
Sick CLV620条码阅读器通过TCP/IP通讯,采用中断驱动方式处理:
stl复制// OB35中断组织块(10ms周期)
L "BarCode_Trigger" // 扫码触发信号
FP "Edge_Mem" // 上升沿检测
JCN _End
// 动态解析变长条码
L P##BarCode_Struct // 装载结构体指针
LAR1
L W [AR1,P#0.0] // 读取长度字
T #Temp_Length
L D [AR1,P#2.0] // 获取数据区指针
LAR2
// 数据转存到MB区
L #Temp_Length
JL _Err // 长度校验(≤20字符)
L 0
_loop: T #Counter
L B [AR2,P#0.0] // 读取当前字节
T MB[#Counter + 100] // 存入MB100开始区域
+AR2 P#1.0 // 指针递增
L #Counter
+ 1
L #Temp_Length
>=I
JCN _loop
// 触发后续处理
S "Barcode_Ready"
JU _End
_Err: R "Barcode_Ready" // 错误处理
_End: NOP 0
优化技巧:
MiniLoad堆垛机通过Anybus模块通讯,采用异步通讯优化:
stl复制// OB1主循环中的处理逻辑
CALL "TRCV_C" , DB200 // 异步接收块
CONT :=TRUE
CONNECT :="Stacker_Connection"
DONE :=#Recv_Done
BUSY :=#Recv_Busy
ERROR :=#Recv_Error
STATUS :=#Recv_Status
CALL "TSEND_C" , DB201 // 异步发送块
CONT :=TRUE
CONNECT :="Stacker_Connection"
DONE :=#Send_Done
BUSY :=#Send_Busy
ERROR :=#Send_Error
STATUS :=#Send_Status
// 状态机处理
L #Recv_Status
L W#16#7001
==I
JC _Process_Data // 接收成功处理
性能参数:
碧彩称重模块的原始值转换算法:
stl复制// 重量值转换(带量程切换)
L "Weight_Raw" // 读取原码值
ITD // 转双整数
DTR // 转浮点
// 量程选择
L "Scale_Select" // 量程选择信号
L 0
==I
JC _Range1
L 1
==I
JC _Range2
_Range3: L 1.415e-4 // 50kg量程系数
JU _Calc
_Range2: L 7.223e-5 // 20kg量程系数
JU _Calc
_Range1: L 3.125e-5 // 10kg量程系数
_Calc: *R // 乘以系数
L "Tare_Value" // 去皮值
+R // 相加
T "Weight_Actual" // 最终重量
校准要点:
采用状态矩阵实现路由决策:
stl复制// 路径选择逻辑
L #Current_Position // 当前位置(1-12)
L #Destination // 目标位置(1-12)
-I // 计算差值
JZ _Bypass // 直达情况
// 矩阵索引计算
L #Current_Position
L 12
*I // 行偏移
L #Destination
+I // 列偏移
DEC 1 // 调整为0-based
SLW 3 // 转换为指针偏移(8字节/条目)
LAR1
// 查表获取下一节点
L "Route_Matrix"[AR1]
T #Next_Node // 下一节点编号
// 转向控制输出
L #Next_Node
L 1
==I
JC _Turn_Left
L 2
==I
JC _Turn_Right
_Bypass: NOP 0 // 直行逻辑
矩阵生成方法:
提升机与输送线的协同控制:
stl复制// 丹佛斯变频器控制
A "Lift_Up" // 上升指令
FP "Edge_Up" // 边沿检测
JCN _Chk_Down
// 控制字设置
L W#16#047F // 启能+外部控制
T "FC_ControlWord"
// 速度设定
L 50.0 // 默认频率(Hz)
T "FC_Frequency"
// 超时监控
L "Timer_Up"
SD T#5S // 5秒超时
_Chk_Down: A "Lift_Down" // 下降逻辑类似
...
安全联锁:
指针安全:
扫描周期优化:
调试技巧:
协议转换:
数据对齐:
故障排查:
这套系统最终实现了98.7%的料箱一次分拣正确率,最让我自豪的是在老旧PLC上通过STL优化,将扫描周期控制在15ms以内。对于想学习工业通讯集成的同行,我的建议是:先吃透Modbus协议,它就像工业界的通用语,掌握后各种设备集成都能触类旁通。下次如果再做类似项目,我会考虑用OPC UA统一通讯架构,不过在现场设备五花八门的老厂房里,有时候"土办法"反而最可靠。