499 lines
15 KiB
Markdown
499 lines
15 KiB
Markdown
|
||
# 物流小车嵌入式控制系统(STM32F103,TCP/IP)
|
||
# Logistics AGV Embedded System (STM32F103, TCP/IP)
|
||
|
||
---
|
||
|
||
## 📖 项目简介 | Project Overview
|
||
|
||
本项目为基于 STM32F103 的物流小车(AGV)嵌入式控制系统,支持 TCP/IP 局域网通信、RFID 站点识别、红外循迹、超声避障、电机闭环控制等功能。适用于智能仓储、自动运输等场景。
|
||
|
||
This project is an embedded control system for a logistics AGV based on STM32F103, supporting TCP/IP LAN communication, RFID station recognition, IR line tracking, ultrasonic obstacle avoidance, and closed-loop motor control. Suitable for smart warehouse and auto-transport scenarios.
|
||
|
||
---
|
||
|
||
## 📦 目录结构 | Directory Structure
|
||
|
||
```
|
||
├── Core/ # 主代码(BSP、驱动、协议、控制任务等)
|
||
│ ├── Bsp/ # 板级支持包(电机、PID、循迹、RFID、超声、串口等)
|
||
│ ├── Inc/ # 头文件
|
||
│ └── Src/ # CubeMX自动生成及主循环
|
||
├── Drivers/ # HAL库、CMSIS等外部驱动
|
||
├── Middlewares/ # 第三方中间件(如FreeRTOS)
|
||
├── build/ # 构建输出
|
||
├── cmake/ # CMake工具链与脚本
|
||
├── 物流小车/ # 机械结构、上位机、3D模型、调试工具
|
||
│ ├── 3D/ # 机械3D模型(SolidWorks/STEP)
|
||
│ ├── esp_12f/ # ESP-12F相关工具
|
||
│ └── web/ # 上位机/调试脚本
|
||
├── CMakeLists.txt # CMake主构建脚本
|
||
├── f103_car.ioc # CubeMX工程文件
|
||
└── README.md # 项目说明文档
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ 硬件与软件需求 | Hardware & Software Requirements
|
||
|
||
### 硬件 | Hardware
|
||
- STM32F103ZET6 开发板
|
||
- ESP-12F WiFi模块(TCP透传)
|
||
- AT8236-MS 电机驱动板 + 4路直流电机
|
||
- 霍尔测速传感器 ×4
|
||
- 红外循迹模块 ×4
|
||
- 超声波测距模块(HC-SR04)
|
||
- RC522 RFID读卡器
|
||
- 3.3V/5V 电源、线缆、机械底盘
|
||
|
||
### 软件 | Software
|
||
- Keil/STM32CubeIDE/GCC + CMake
|
||
- FreeRTOS
|
||
- 串口调试助手(XCOM/SecureCRT)
|
||
- TCP调试工具(NetAssist等)
|
||
- SolidWorks/STEP查看器(3D结构)
|
||
|
||
---
|
||
|
||
## ⚙️ 编译与烧录 | Build & Flash
|
||
|
||
1. 安装依赖(HAL库、FreeRTOS、CMake等)
|
||
2. 用 STM32CubeMX 生成代码(f103_car.ioc)
|
||
3. CMake 构建:
|
||
```sh
|
||
mkdir build && cd build
|
||
cmake .. -G "Ninja"
|
||
ninja
|
||
```
|
||
4. 用 JLink/ST-Link 烧录 .elf/.bin 到开发板
|
||
5. ESP-12F 配置为 TCP Server,波特率115200,透传模式
|
||
|
||
---
|
||
|
||
## 🚗 功能总览 | Features
|
||
|
||
- TCP/IP 通信协议,支持上位机远程控制与状态监控
|
||
- RFID 站点识别与到站锁存
|
||
- 红外循迹(4路/5路,带去抖与方向判定)
|
||
- 超声波避障(自动停车/恢复)
|
||
- 电机PWM闭环控制(PID,支持死区补偿)
|
||
- 任务调度与消息队列(FreeRTOS)
|
||
- 详细日志输出(EasyLogger)
|
||
|
||
---
|
||
|
||
## 📡 通信协议 | Communication Protocol
|
||
|
||
### 指令帧结构 | Frame Structure
|
||
|
||
```
|
||
LOGI:<PAYLOAD>:<CS>#
|
||
```
|
||
- LOGI: 固定帧头
|
||
- <PAYLOAD>: 有效载荷(如 ST:RUN、GS:001)
|
||
- <CS>: 2字节十六进制校验和(从'L'累加到最后一个冒号前)
|
||
- #: 帧尾
|
||
|
||
### 下行指令(上位机→小车)| Downlink (PC→Car)
|
||
|
||
| 功能 | 指令格式 | 示例 | 说明 |
|
||
|------|----------|------|------|
|
||
| 设置站点 | LOGI:GS:NNN:CS# | LOGI:GS:001:CA# | NNN为3位站点号 |
|
||
| 启动运行 | LOGI:ST:RUN:CS# | LOGI:ST:RUN:3B# | 启动自动循迹 |
|
||
| 停止运行 | LOGI:ST:STOP:CS# | LOGI:ST:STOP:8C# | 急停/暂停 |
|
||
| 设置速度 | LOGI:SP:VVV:CS# | LOGI:SP:050:D7# | VVV为000-100 |
|
||
|
||
### 上行遥测(小车→上位机)| Uplink (Car→PC)
|
||
|
||
- 周期状态:
|
||
`LOGI:STAT:SP:050,STA:001,RUN:1,DIS:12.5,TRK:0010,RPM:25:25:25:25:CS#`
|
||
- 指令反馈:
|
||
`LOGI:FB:GS:1:A5#`(1=成功,0=失败)
|
||
|
||
### 校验和算法 | Checksum
|
||
|
||
所有字符ASCII累加,取低8位,转2位十六进制。
|
||
|
||
```python
|
||
def calculate_cs(data_str):
|
||
return sum(data_str.encode('ascii')) & 0xFF
|
||
```
|
||
|
||
---
|
||
|
||
## 🧩 主要模块说明 | Main Modules
|
||
|
||
### 1. 电机与PID | Motor & PID
|
||
- 4路PWM控制,AT8236-MS驱动,支持正反转与刹车
|
||
- PID参数可调,支持死区补偿,闭环速度控制
|
||
|
||
### 2. 霍尔测速 | Hall Speed
|
||
- 外部中断计数,定时计算RPM,支持实时测速
|
||
|
||
### 3. 红外循迹 | IR Tracking
|
||
- 4路/5路红外,带去抖与方向判定,支持丢线/十字/偏移等状态
|
||
|
||
### 4. 超声波避障 | Ultrasonic
|
||
- HC-SR04,DWT微秒级测距,自动停车/恢复
|
||
|
||
### 5. RFID站点 | RFID Station
|
||
- RC522,UID白名单匹配,支持多站点扩展,到站自动锁存
|
||
|
||
### 6. 串口与TCP | UART & TCP
|
||
- UART1+DMA,ESP-12F透传TCP,空闲中断帧接收
|
||
|
||
### 7. 协议栈 | Protocol
|
||
- 指令解析、校验、消息队列、状态上报、反馈应答
|
||
|
||
---
|
||
|
||
## 🚦 典型使用流程 | Typical Workflow
|
||
|
||
1. 上电,ESP-12F配置为TCP Server,波特率115200,透传模式
|
||
2. 上位机通过TCP工具连接小车IP/端口
|
||
3. 发送 `LOGI:GS:001:XX#` 设置目标站点
|
||
4. 发送 `LOGI:ST:RUN:XX#` 启动小车
|
||
5. 小车自动循迹,遇障碍自动停车,RFID到站自动锁存
|
||
6. 上位机周期接收状态帧,随时可发 `STOP`/`SP:xxx` 控制
|
||
|
||
---
|
||
|
||
## 🖥️ 上位机开发建议 | PC/Host Development
|
||
|
||
- 推荐用 Python/C#/LabVIEW 等实现 TCP 客户端,直接发送/解析 ASCII 指令
|
||
- 校验和算法见上,协议字段可扩展
|
||
- 参考 `Core/Bsp/up_readme.md` 获取协议范例
|
||
|
||
---
|
||
|
||
## 🛠️ 调试与常见问题 | Debug & FAQ
|
||
|
||
### 1. 无法连接TCP
|
||
- 检查IP/端口/波特率/透传配置
|
||
- 确认ESP-12F与主控串口连接正常
|
||
|
||
### 2. 指令无响应/校验失败
|
||
- 检查指令格式与校验和
|
||
- 查看串口/网络日志
|
||
|
||
### 3. RFID/循迹/测速异常
|
||
- 检查硬件连线、电源、模块初始化
|
||
- 查看日志与状态上报帧
|
||
|
||
### 4. CubeMX生成代码被覆盖
|
||
- 用户代码请写在 `USER CODE BEGIN ... END` 区域
|
||
- 驱动/业务任务建议放在 `Core/Bsp/`,主循环仅调用接口
|
||
|
||
---
|
||
|
||
## 🤝 贡献与联系方式 | Contributing & Contact
|
||
|
||
- 欢迎提交PR、Issue,或邮件联系作者
|
||
- Author: Beihong Wang
|
||
- Email: [your_email@example.com]
|
||
- 日期/Date: 2026-04-16
|
||
|
||
---
|
||
|
||
## 📝 附录 | Appendix
|
||
|
||
- 详细协议范例、上位机代码、硬件原理图、3D模型等请见 `Core/Bsp/up_readme.md`、`物流小车/3D/`、`物流小车/web/`
|
||
- 关键代码均含中文注释,便于二次开发与维护
|
||
|
||
---
|
||
|
||
> 本文档中英双语,便于团队协作与国际交流。后续如有更新请及时同步。
|
||
|
||
## 测试与验证
|
||
|
||
### 1. 启动服务器
|
||
|
||
使用 TCP 测试软件创建服务器并启动。
|
||
|
||
### 2. 实际连接与发送测试
|
||
|
||
通过串口助手发送数据,验证数据是否成功传输。
|
||
|
||
---
|
||
|
||
## 连接示意图
|
||
|
||

|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 1. 无法连接服务器
|
||
|
||
- 检查 IP 和端口是否正确。
|
||
- 确保 Wi-Fi 配置无误。
|
||
|
||
### 2. 透传模式无法退出
|
||
|
||
- 确保发送 `+++` 时未勾选“发送新行”。
|
||
- 确保发送后停顿 1 秒以上。
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### 相关工具截图
|
||
|
||
#### TCP 测试软件
|
||
|
||

|
||
|
||
#### 创建服务器
|
||
|
||

|
||
|
||
#### 启动服务器
|
||
|
||

|
||
|
||
#### 实际连接发送测试
|
||
|
||

|
||
|
||
---
|
||
|
||
## 串口重定向
|
||
|
||
使用以下函数,用于串口重定向:
|
||
|
||
```c
|
||
#ifdef __GNUC__
|
||
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
|
||
#else
|
||
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
|
||
#endif
|
||
|
||
PUTCHAR_PROTOTYPE {
|
||
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||
return ch;
|
||
}
|
||
```
|
||
|
||
该函数用于将 `printf` 输出重定向到串口。
|
||
|
||
---
|
||
|
||
## TCP 接收与发送
|
||
|
||
### 接收数据
|
||
|
||
使用空闲中断接收 TCP 数据,开启了 DMA 接收:
|
||
|
||
```c
|
||
void UART_IDLE_Callback(UART_HandleTypeDef *huart) {
|
||
/* 仅处理 USART1 的实例 */
|
||
if (huart == NULL || huart->Instance != USART1)
|
||
return;
|
||
|
||
/* 清除空闲中断标志位(HAL库宏) */
|
||
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
||
|
||
/* 停止 DMA 以便安全读取计数器并更新状态 */
|
||
HAL_UART_DMAStop(huart);
|
||
|
||
/* 计算接收到的字节数:总缓冲区长度 - DMA 剩余传输计数 */
|
||
uint16_t recv_len = UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
|
||
|
||
if (recv_len > 0 && recv_len < UART1_RX_BUF_SIZE) {
|
||
uart1_rx_len = recv_len;
|
||
uart1_rx_buf[recv_len] = '\0'; /* 添加字符串结束符,方便后续字符串处理 */
|
||
uart1_rx_flag = 1; /* 置位标志,通知应用层新消息到达 */
|
||
|
||
/* 仅供调试:在中断中打印接收到的数据(注意:printf 可能会影响实时性) */
|
||
elog_raw("UART1 Received: %s\r\n", (char *)uart1_rx_buf);
|
||
}
|
||
|
||
/* 重新启动新一轮的 DMA 接收 */
|
||
HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE);
|
||
}
|
||
```
|
||
|
||
### 发送数据
|
||
|
||
封装了发送函数,只需填入数据即可发送:
|
||
|
||
```c
|
||
const char *message = "Hello, ESP12F! This is a test message.";
|
||
HAL_StatusTypeDef status = ESP12F_TCP_SendMessage(message);
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 物流小车 TCP 通信协议 (v1.2)
|
||
|
||
本项目采用自定义 ASCII 协议进行上位机控制与状态监控。
|
||
|
||
### 1. 指令帧结构
|
||
`LOGI:<PAYLOAD>:<CS>#`
|
||
- **LOGI**: 固定帧头
|
||
- **PAYLOAD**: 有效载荷 (详见下表)
|
||
- **CS**: 2字节十六进制校验和 (从 'L' 累加到 ':' 之前)
|
||
- **#**: 固定帧尾
|
||
|
||
### 2. 控制指令 (上位机 -> 小车)
|
||
|
||
| 功能 | 指令格式 | 示例 | 说明 |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **设置站点** | `GS:NNN` | `LOGI:GS:001:CA#` | NNN为3位站点号 (支持 001/002) |
|
||
| **启动运行** | `ST:RUN` | `LOGI:ST:RUN:3B#` | 开始任务 (必须先设有效站点) |
|
||
| **停止运行** | `ST:STOP` | `LOGI:ST:STOP:8C#` | 立即停止 |
|
||
| **设置速度** | `SP:VVV` | `LOGI:SP:050:D7#` | VVV为000-100 (百分比) |
|
||
|
||
### 3. 上行遥测 (小车 -> 上位机)
|
||
|
||
#### 3.1 状态推送 (每 500ms 推送一次)
|
||
**格式**: `LOGI:STAT:SP:速度,STA:站点,RUN:运行,DIS:距离,TRK:循迹状态,RPM:M1:M2:M3:M4:CS#`
|
||
**字段**:
|
||
- `SP`: 当前速度 %
|
||
- `STA`: 目标站点号
|
||
- `RUN`: 运行状态 (1:运行, 0:停止)
|
||
- `DIS`: 避障距离 (cm)
|
||
- `TRK`: 4位红外状态 (0/1组合, 顺序为 H4 H3 H2 H1)
|
||
- `RPM`: 四路电机实际转速,以 `:` 分隔 (顺序为 LR:LF:RF:RR)
|
||
|
||
#### 3.2 指令反馈 (即时回复)
|
||
**格式**: `LOGI:FB:指令类型:状态值:CS#`
|
||
**示例**: `LOGI:FB:GS:1:A5#` (1代表成功, 0代表失败)
|
||
|
||
---
|
||
|
||
### 4. 业务逻辑约束
|
||
1. **到站锁存**: 到达站点后小车自动停下,`RUN` 变为 0。
|
||
2. **解锁流程**: 车辆停稳后,必须重新发送 `GS` 指令设置新站点(或覆盖旧站点),方可再次发送 `ST:RUN` 启动。否则,小车将报警并拒绝运行。
|
||
|
||
|
||
这些是上位机发送的指令:
|
||
按照这些来写代码
|
||
|
||
这是一个基于 TCP/IP 局域网通信的物流小车控制指令协议设计方案。
|
||
|
||
为了方便调试和开发,本协议采用 **ASCII 文本格式**(类似于 Modbus ASCII 或简单的串口透传格式),而不是二进制格式。这样你可以直接使用网络调试助手(如 NetAssist)手动发送字符串来测试小车,而无需编写专门的上位机软件。
|
||
|
||
---
|
||
|
||
### 📡 通信基础参数
|
||
|
||
- **通信方式**:TCP Client (上位机) 连接 TCP Server (单片机/小车)
|
||
- **数据格式**:ASCII 字符串
|
||
- **换行符**:建议使用 `\r\n` (回车+换行) 作为每条指令的结束标志,以便单片机解析。
|
||
- **字节序**:N/A (文本协议不涉及大小端问题)
|
||
|
||
---
|
||
|
||
### 📦 指令帧结构
|
||
|
||
每条指令由以下几个部分组成,字段之间用英文冒号 `:` 分隔:
|
||
|
||
`[帧头][命令字][数据内容][校验和][帧尾]`
|
||
|
||
- **帧头**:固定为 `LOGI` (代表 Logistics),用于快速识别有效数据包。
|
||
- **命令字**:2位字符,代表具体操作(如 `GS` 代表去站点)。
|
||
- **数据内容**:具体的参数,长度可变。
|
||
- **校验和**:2位十六进制数,用于验证数据完整性(防止丢包或乱码)。
|
||
- **帧尾**:固定为 `#`。
|
||
|
||
---
|
||
|
||
### 📝 具体控制指令定义
|
||
|
||
以下是针对你提出的四个需求(去站点、停止、启动、速度)的具体指令格式。
|
||
|
||
#### 1. 去往指定站点
|
||
- **功能**:指示小车移动到编号为 N 的站点。
|
||
- **指令格式**:`LOGI:GS:NNN:CS#`
|
||
- **参数说明**:
|
||
- `GS`: 命令字 (Go to Station)。
|
||
- `NNN`: 站点编号,3位数字,不足补0。例如:1号站写为 `001`,12号站写为 `012`。
|
||
- `CS`: 校验和。
|
||
- **示例**:
|
||
- 去往 **5号站点**:`LOGI:GS:005:15#` (假设校验和计算结果为15)
|
||
|
||
#### 2. 启动运行
|
||
- **功能**:让处于停止或待机状态的小车开始执行任务或继续运行。
|
||
- **指令格式**:`LOGI:ST:RUN:CS#`
|
||
- **参数说明**:
|
||
- `ST`: 命令字 (Start/Status)。
|
||
- `RUN`: 固定参数,表示启动。
|
||
- **示例**:
|
||
- 启动小车:`LOGI:ST:RUN:2A#`
|
||
|
||
#### 3. 紧急停止/暂停
|
||
- **功能**:立即停止小车的运动,通常用于急停或到达站点后的确认暂停。
|
||
- **指令格式**:`LOGI:ST:STOP:CS#`
|
||
- **参数说明**:
|
||
- `STOP`: 固定参数,表示停止。
|
||
- **示例**:
|
||
- 停止小车:`LOGI:ST:STOP:32#`
|
||
|
||
#### 4. 设置运行速度
|
||
- **功能**:动态调整小车的行驶速度。
|
||
- **指令格式**:`LOGI:SP:VVV:CS#`
|
||
- **参数说明**:
|
||
- `SP`: 命令字 (Set Speed)。
|
||
- `VVV`: 速度值,3位数字 (000-100),代表百分比或具体PWM占空比等级。
|
||
- `000`: 停止
|
||
- `050`: 50% 速度
|
||
- `100`: 全速
|
||
- **示例**:
|
||
- 设置速度为 **80%**:`LOGI:SP:080:04#`
|
||
|
||
---
|
||
|
||
### 🧮 校验和算法
|
||
|
||
为了防止无线信号干扰导致指令错误,我们需要一个简单的校验和。
|
||
|
||
- **算法**:将 **帧头** 到 **数据内容** 结束的所有字符的 ASCII 码值相加,然后对 256 取余,最后转换为 2位十六进制字符串。
|
||
- **公式**:`Sum = (Byte1 + Byte2 + ... + ByteN) % 256`
|
||
|
||
**举例计算 (去往 1 号站点):**
|
||
1. 原始字符串:`LOGI:GS:001`
|
||
2. ASCII 码值相加:
|
||
- 'L'(76) + 'O'(79) + 'G'(71) + 'I'(73) + ':'(58) + 'G'(71) + 'S'(83) + ':'(58) + '0'(48) + '0'(48) + '1'(49)
|
||
- 总和 = 614
|
||
3. 取余:`614 % 256 = 102`
|
||
4. 转十六进制:`102` -> `66`
|
||
5. 最终发送指令:`LOGI:GS:001:66#`
|
||
|
||
---
|
||
|
||
### 💬 小车回复机制 (可选但推荐)
|
||
|
||
单片机执行指令后,应向上位机返回执行结果,以便上位机显示状态。
|
||
|
||
**回复格式**:`[命令字]:[状态码]:[描述]#`
|
||
|
||
- **状态码定义**:
|
||
- `OK`: 指令接收正确并执行。
|
||
- `ERR`: 指令格式错误或校验失败。
|
||
- `BUSY`: 小车正在忙,无法执行新指令。
|
||
|
||
**示例回复**:
|
||
- 成功去往站点:`GS:OK:Arrived#`
|
||
- 速度设置成功:`SP:OK:SpeedSet#`
|
||
- 校验错误:`CMD:ERR:CheckSum#`
|
||
|
||
---
|
||
|
||
### 📌 总结清单
|
||
|
||
你可以直接将下表发给单片机开发人员:
|
||
|
||
| 功能 | 指令模板 | 示例 (假设校验和为 XX) | 说明 |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **去站点** | `LOGI:GS:NNN:XX#` | `LOGI:GS:003:XX#` | NNN为3位站点号 |
|
||
| **启动** | `LOGI:ST:RUN:XX#` | `LOGI:ST:RUN:XX#` | 开始运动 |
|
||
| **停止** | `LOGI:ST:STOP:XX#` | `LOGI:ST:STOP:XX#` | 立即停止 |
|
||
| **设速度** | `LOGI:SP:VVV:XX#` | `LOGI:SP:050:XX#` | VVV为0-100 |
|
||
|
||
|
||
我创建了 处理解析指令的任务和传递消息的消息队列。
|
||

|
||
|