138 lines
4.9 KiB
Markdown
138 lines
4.9 KiB
Markdown
# 糖包拆线 ModbusTCP 协议说明
|
||
|
||
**应用名称**: BagThreadPosition(糖包拆线)
|
||
**版本**: v2.0
|
||
**日期**: 2026-02-09
|
||
|
||
## 概述
|
||
|
||
糖包拆线应用作为 ModbusTCP **客户端(Master)**,主动连接远端 PLC(Slave),通过轮询寄存器实现扫描控制和检测结果输出。
|
||
|
||
### 基本信息
|
||
|
||
- **客户端(Master)**: 糖包拆线应用(BagThreadPosition)
|
||
- **服务端(Slave)**: PLC 或其他支持 ModbusTCP 的设备
|
||
- **协议**: ModbusTCP(基于 TCP/IP 的 Modbus 协议)
|
||
- **默认远端地址**: 192.168.2.1:502
|
||
- **功能码**: 0x03(读保持寄存器)、0x06(写单个保持寄存器)、0x10(写多个保持寄存器)
|
||
|
||
### 配置参数
|
||
|
||
在 `config.xml` 的 `<ModbusTCP>` 元素中配置:
|
||
|
||
| 属性 | 说明 | 默认值 |
|
||
|------|------|--------|
|
||
| `ip` | 远端 PLC 的 IP 地址 | 192.168.2.1 |
|
||
| `port` | 远端 PLC 的端口号 | 502 |
|
||
| `pollingInterval` | 轮询间隔(毫秒) | 200 |
|
||
| `bigEndian` | Float 数据字节序(true=大端,false=小端) | true |
|
||
|
||
配置示例:
|
||
```xml
|
||
<ModbusTCP bigEndian="true" ip="192.168.2.1" port="502" pollingInterval="200" />
|
||
```
|
||
|
||
## 寄存器地址映射
|
||
|
||
### 控制寄存器
|
||
|
||
| 地址 | 功能 | 操作方 | 数据类型 | 说明 |
|
||
|------|------|--------|----------|------|
|
||
| 0 | 启动扫描 | PLC 写入1 → 应用读取并清零 | uint16 | PLC 写入1请求扫描,应用检测到后清零 |
|
||
| 2 | 检测状态 | 应用写入 | uint16 | 0=检测中, 1=成功, 2=失败 |
|
||
|
||
### 数据寄存器
|
||
|
||
| 地址 | 功能 | 操作方 | 数据类型 | 说明 |
|
||
|------|------|--------|----------|------|
|
||
| 4+ | xyzu数据 | 应用写入 | float[] | 拆线位置数据(每条拆线8个寄存器) |
|
||
|
||
## 通信流程
|
||
|
||
### 应用端(Client/Master)自动执行流程
|
||
|
||
```
|
||
1. 应用启动 → 主动连接 PLC(Slave)
|
||
2. 连接成功 → 开始轮询读取 reg[0]
|
||
3. 检测到 reg[0] 从 0→1(边沿检测):
|
||
a. 清零 reg[0] = 0
|
||
b. 清零 reg[2] = 0(检测中)
|
||
c. 暂停轮询
|
||
d. 触发相机扫描和算法检测
|
||
4. 检测完成:
|
||
a. 成功: reg[2] = 1,reg[4+] 写入 xyzu 数据
|
||
b. 失败: reg[2] = 2
|
||
c. 恢复轮询
|
||
5. 连接断开 → 自动重连(每2秒尝试一次)
|
||
```
|
||
|
||
### PLC 端(Server/Slave)操作步骤
|
||
|
||
1. **请求扫描**: 将 reg[0] 写为 1
|
||
2. **等待结果**: 读取 reg[2],直到值不为 0
|
||
- 值为 1:检测成功,从 reg[4] 开始读取 xyzu 数据
|
||
- 值为 2:检测失败
|
||
3. **下次扫描**: 等待 reg[0] 被应用清零后,再次写 1
|
||
|
||
## 数据格式
|
||
|
||
### 寄存器布局
|
||
|
||
每条拆线占用 8 个寄存器(4个float,每个float占2个寄存器):
|
||
|
||
```
|
||
寄存器[4+i*8+0:1] -> x (centerX, float)
|
||
寄存器[4+i*8+2:3] -> y (centerY, float)
|
||
寄存器[4+i*8+4:5] -> z (centerZ, float)
|
||
寄存器[4+i*8+6:7] -> u (rotateAngle, float)
|
||
```
|
||
|
||
其中 i 为拆线索引(从0开始)。
|
||
|
||
### xyzu 含义
|
||
|
||
- **x (centerX)**: 拆线端部中心点的X坐标(毫米)
|
||
- **y (centerY)**: 拆线端部中心点的Y坐标(毫米)
|
||
- **z (centerZ)**: 拆线端部中心点的Z坐标(毫米)
|
||
- **u (rotateAngle)**: 拆线旋转角度(度,范围 -30° ~ 30°)
|
||
|
||
### Float 数据格式
|
||
|
||
每个 float 值占用 2 个 uint16 寄存器(IEEE 754 单精度浮点数)。
|
||
字节序由配置文件的 `bigEndian` 属性决定:
|
||
- **大端(默认)**: 高16位在前,低16位在后
|
||
- **小端**: 低16位在前,高16位在后
|
||
|
||
## 自动重连机制
|
||
|
||
- 应用启动时主动连接配置的 PLC 地址
|
||
- 连接断开后自动重连,每 2 秒尝试一次
|
||
- 重连成功后自动恢复轮询
|
||
- 页面显示机械臂在线/离线状态
|
||
|
||
## 注意事项
|
||
|
||
1. **角色变更**: v2.0 起应用从 Server 模式改为 Client 模式,主动连接 PLC
|
||
2. **边沿检测**: 只在 reg[0] 从 0→1 变化时触发扫描,避免重复触发
|
||
3. **数据顺序**: 拆线数据按检测顺序排列
|
||
4. **自动输出**: 检测成功后,应用自动将 xyzu 数据写入远端 PLC 的寄存器
|
||
5. **超时处理**: 建议 PLC 端设置合理的超时时间(如30秒)等待检测完成
|
||
6. **单次检测**: 检测期间轮询暂停,检测完成后自动恢复
|
||
|
||
## 错误处理
|
||
|
||
如果 reg[2] 返回 2(失败),可能的原因:
|
||
- 相机未连接
|
||
- 检测算法失败
|
||
- 检测处理器未初始化
|
||
|
||
建议 PLC 端在失败后重新将 reg[0] 置 1 发起扫描,或通知操作人员检查设备状态。
|
||
|
||
## MThings 测试方法
|
||
|
||
1. MThings 启动 **Slave 模式**,监听 502 端口
|
||
2. BagThreadPosition 应用启动后自动连接 → 页面机械臂状态显示"在线"
|
||
3. 在 MThings 中将 reg[0] 写为 1 → 应用触发检测
|
||
4. 检测完成后在 MThings 中查看 reg[2](状态)和 reg[4+](xyzu数据)
|
||
5. 断开 MThings → 页面机械臂状态显示"离线" → 重启 MThings → 自动重连
|