Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
.idea
.idea
# Python 缓存
__pycache__/
*.pyc

# 固件与二进制文件(量产固件建议通过 GitHub Release 发布,而非直接塞进源码仓库)
tools/firmware/*.bin

# Arduino 编译临时目录
build/
.build/

.gitignore~
..gitignore.un~
*.un~
*~
143 changes: 143 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

# ESP32 底盘控制程序 (esp32_base_control)

本项目基于 ESP32-C3(支持 Geekble Mini ESP32-C3 开发板)开发,用于移动机器人底盘的底层核心控制。项目包含完整的 Arduino 源码工程,以及面向工厂/团队的高效批量自动烧录与全自动质检工具链。

---

## 🛠 场景一:源码开发与环境配置 (开发者适用)

如果你需要修改底层控制逻辑或调试传感器,请使用图形化 IDE 进行开发。

### 1. 环境变量配置 (国内加速)
为避免国内网络环境下下载乐鑫依赖链极易卡死的问题,请在系统环境变量中添加加速源:
- **Windows**: 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」,在用户变量中新建:
- 变量名:`IDF_GITHUB_ASSETS`
- 变量值:`dl.espressif.com/github_assets`
- **macOS / Linux**: 在终端配置文件(如 `~/.zshrc` 或 `~/.bash_profile`)中追加:
```bash
export IDF_GITHUB_ASSETS="https://dl.espressif.com/github_assets"
```


### 2. Arduino IDE 配置

1. 打开 Arduino IDE,进入 `Preferences` (偏好设置)。
2. 在 `Additional boards manager URLs` 中填入国内第三方加速索引源:
```text
https://arduino.me/packages/esp32.json
```
3. 进入 `Boards Manager` (开发板管理器),搜索 `esp32` 并安装由 **Espressif Systems** 发布的开发板核心库。


### 3. 编译与烧录

1. 用 Arduino IDE 打开工程主文件:`arduino/base_control/base_control.ino`。
2. 在开发板选择中搜索并选中 `Geekble Mini ESP32-C3`。
3. 选择对应的物理 USB 串口(macOS 通常为 `/dev/cu.usbmodemXXXX`,Windows 通常为 `COMX`)。
4. 点击 **Upload (上传)** 开始编译并烧录。

---

## ⚡ 场景二:一键式批量自动烧录 (生产/量产适用)

当底盘控制程序验证完毕、需要进行多台设备批量固件写入时,请使用项目内置的自动化量产工具。

### 1. 准备合并固件

在第一次使用 Arduino IDE 成功烧录后,从本地编译缓存中捞出合并好的单体固件 `base_control.ino.merged.bin`,并将其放置到本仓库的 `tools/firmware/` 目录下。

### 2. 安装量产依赖

确保本地已安装 Python 3 环境,在终端执行以下命令安装乐鑫官方烧录核心驱动:

```bash
pip3 install esptool
```

### 3. 启动批量烧录系统

进入工具链目录并启动监听脚本:

```bash
cd tools
python3 batch_burner.py
```

### 4. 流水线实操规程

1. **接入硬件**:使用 USB 数据线将新的底盘主控板接入电脑。
2. **自动闪存**:脚本将自动捕获新端口并以最高稳定波特率(`921600`)执行顺序写入,耗时通常在 5~8 秒。
3. **断开换板**:终端打印出绿色 `[成功]` 提示后,直接拔掉数据线,换下一块板子插入,全程无需触碰键盘鼠标。

---

## 🔍 场景三:底盘功能与通信协议全自动质检 (研发质检/品控适用)

在固件烧录成功后,保持数据线连接,可直接使用项目内置的协议压力测试工具对底盘的底层状态机、双轴控制及编码器反馈进行高精度功能质检:

### 1. 安装质检依赖
确保本地安装了 Python 串口通信组件:
```bash
pip3 install pyserial
```

### 2. 查找当前主控板的正确串口号

把已经成功烧录好固件的 ESP32 底盘通过数据线连上 Mac/Linux。在终端确认它的端口(假设依然是刚才的通用端口):
```bash
ls /dev/cu.usb*
```
假设获取到的端口号是:`/dev/cu.usbmodemXXXX`


### 3. 一键运行自动化品检

无需修改脚本源码,直接通过命令行传入当前板子在 Mac/Linux 下分配的动态串口路径:

```bash
python3 tests/test_uart.py /dev/cu.usbmodemXXXX
```

*注:串口路径为必填参数。波特率默认对齐底盘源码的 `115200`。如需修改,可追加参数如 `--baud 9600`。*


### 4. 出厂判定标准

终端将瞬间瀑布式执行 26 项子协议断言测试。

* **合格**:结尾显示绿色 `[PASS]` 汇总,且 26/26 项全部通过,底盘准予出厂。
* **不合格**:若出现红色 `[FAIL]` 或随机时序错乱,请重点排查底盘供电稳定度、编码器接线或芯片物理损坏。

---

## 🔍 场景四:烧录 + 26项功能全自动联动质检 (品控质检适用)

为了确保烧录完成的底盘物理接线、编码器状态和通信状态机 100% 合格,本项目支持“烧录即质检”的流水线联动模式。

### 1. 安装质检依赖
确保本地安装了 Python 串口通信组件:

```bash
pip3 install pyserial
```

### 2. 启动联动质检流水线

在终端中附加 `--test` 参数启动烧录脚本:

```bash
python3 tools/batch_burner.py --test
```

### 3. 联动流水线 SOP 规范

1. **插入新设备**:脚本自动捕获串口,并以最高稳定波特率(`921600`)执行固件烧录。
2. **自动质检**:固件部署成功后,系统在原地等待 1 秒钟(等待硬件冷启动),随后**自动无缝调用** `tests/test_uart.py` 进行 26 项高精度串口通信与传感器状态校验。
3. **出厂判定**:
* 若 26/26 项测试全部显示绿色 `[PASS]`,底盘合格。
* 若出现红色 `[FAIL]` 或串口中断,请重点排查底盘供电、编码器物理接线或芯片损坏。
4. **换板**:拔掉当前设备,接入下一块,系统自动进入下一轮“烧录+质检”循环。

---

26 changes: 22 additions & 4 deletions tests/test_uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import struct
import sys
import termios
import argparse

# ── 配置 ──────────────────────────────────────────────
PORT = "/dev/ttyS1"
BAUD = 115200
#PORT = "/dev/cu.usbmodem11301"
#PORT = "/dev/ttyS1"
#BAUD = 115200
TIMEOUT = 1.0 # 秒

# ── 命令/响应字 ───────────────────────────────────────
Expand Down Expand Up @@ -390,6 +392,16 @@ def test_reset(ser, t):
# ── 主程序 ───────────────────────────────────────────

def main():

# 动态构建参数解析器
parser = argparse.ArgumentParser(description="ESP32-C3 电机控制器 UART 协议全面测试")
parser.add_argument("port", type=str, help="物理设备串口路径 (如 Mac 下的 /dev/cu.usbmodem11101)")
parser.add_argument("--baud", type=int, default=115200, help="通讯波特率 (默认: 115200)")
args = parser.parse_args()

PORT = args.port
BAUD = args.baud

print("="*50)
print(" ESP32-C3 电机控制器 UART 协议全面测试")
print(f" 端口: {PORT} 波特率: {BAUD}")
Expand Down Expand Up @@ -419,10 +431,16 @@ def main():
test_unknown_cmd(ser, t)
test_reset(ser, t)
finally:
# 确保测试结束后电机停止
# 确保测试结束后电机停止且清除缓冲区:退出前将底盘控制状态机复位,防止电机持续空转
try:
if ser.is_open:
# 在关闭串口前,发送复位信号,确保底盘恢复状态
# if ser.is_open:
if 'ser' in locals() and ser.is_open:
ser.write(build_frame(CMD_RESET))
time.sleep(0.05) # 给硬件极短的重置反应时间
ser.reset_input_buffer()
ser.reset_output_buffer()

except Exception:
pass # 串口已断开,忽略错误
finally:
Expand Down
Loading