关于 USB Servo Controller
USB Servo Controller 是一款开源硬件 USB-C 控制板及配套软件,可控制最多 12 个业余舵机。其 MCP 服务允许 AI Agent 发出移动和序列指令并读取电源轨测量值,同时提供运动与电流保护。
主要功能
- 01控制 12 路 PWM 舵机
- 02兼容 Maestro 串行协议
- 03读取电源轨电流与电压
- 04运行姿势和已存序列
- 05每通道限位与渐变移动
- 06过流和欠压关断
适用场景
- 01通过 AI Agent 驱动舵机
- 02在控制板上运行姿势和序列
- 03监测舵机电源轨
- 04触发保护条件时停止运动
MCP 相关
内置 MCP 服务向 MCP 客户端提供舵机移动、姿势、序列以及电源轨电流和电压读数,并支持配置限位、渐变移动和过流停止。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
16收录的工具列表 · 更新于 5 天前
此工具无需参数。
详细介绍
USB-C 12 通道舵机控制器
12 通道 USB-C 舵机控制器,兼容 Pololu Maestro,并配有 MCP 服务,让 AI Agent(Claude 等)可以驱动舵机。售价 $18,见 Tindie · 产品页面。
▶ 2 分钟视频:接线、电流监测、GUI,以及控制器驱动真实 MG995 的演示
这是 Pololu Mini Maestro 12 的开源替代品, 支持 Maestro 串行协议,因此 Maestro 库无需修改即可使用 — 此外还配备 USB-C、舵机电源轨电流和电压检测,以及板载脚本。针对 JLCPCB 交钥匙组装设计,100 件时每块约 $4.43,而 Maestro 售价为 $29.95。
| MCU | WCH CH32V203C8T6,RISC-V 96 MHz,LQFP-48 |
| 通道 | 12 路硬件 PWM,50 Hz,0.5 µs;每路可设置行程限位(64–4080 µs,默认 500–2500);0–7 路支持模拟输入 |
| 主机接口 | USB-C、CDC 串行(无需驱动);ASCII 协议以及 Pololu Maestro Compact / Pololu / Mini SSC 协议 |
| 舵机电源 | 通过 5.08 mm 螺丝端子连接的独立电源轨,5–13.2 V 时功能完整,总电流约 5 A |
| 检测 | 电源轨电流(5 mΩ + INA180A2)和电压(÷4),过流 / LiPo 欠压切断 |
| PCB | 66 × 38 mm,2 层,所有元件均位于顶层,4 × M3 |
| 状态 | 首块电路板已于 2026-09-28 完成硬件验证 — selftest.py --rail --move 测试通过 58/58;通道 1–11 尚未连接真实舵机进行驱动 |
| 文档 | 用途 |
|---|---|
USER.md | 电路板使用说明:接线、电源、工具、命令参考、刷写 |
tools/README.md | 主机工具:库、CLI、GUI、脚本、MCP 服务、发布版本构建 |
| 本文件 | 设计说明:各项选择的原因、BOM 和成本、限制、量产前的待办事项 |
AI Agent(MCP 服务)
tools/servo_mcp.py 是一个 MCP 服务,可让 AI Agent 移动舵机、
运行姿态和序列,并读取电源轨电流 / 电压,同时提供安全防护:每个通道的限位、
渐变移动、过流停止。运行 pip install -r tools/requirements.txt,然后:
Claude Code
claude mcp add servo -- python /path/to/UsbServoController/tools/servo_mcp.py
Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"servo": {
"command": "python",
"args": ["/path/to/UsbServoController/tools/servo_mcp.py"]
}
}
}
添加 "--port", "COM5" 以选择端口,或添加 "--mock" 以在没有硬件的情况下试用。
请先关闭 GUI:串行端口一次只能由一个程序占用。
该服务也已发布到 PyPI,因此任何 MCP 客户端都可以无需克隆仓库即可运行:
命令为 uvx,参数为 ["ucan-servo-mcp"](还可添加 --config path/to/servogui.json
以使用 GUI 保存的限位、姿态和序列)。
1. 快速开始
pip install -r tools/requirements.txt
python tools/servogui.py # GUI (or --mock with no hardware)
python tools/servoctl.py set 0 1500 # CLI
cd embedded-ch32 && make flash # build + flash over USB, ~3 s, no jumper
**下载:**固件映像和适用于 Windows 与 Linux 的预构建 GUI 可在
Releases 页面下载。
要自行构建 GUI:运行 python tools/build_release.py → 输出到 tools/dist/。
2. 为什么选择 CH32V203C8T6
硬性要求是芯片内置 USB ROM 引导加载程序,这样空白芯片无需编程器即可通过 USB-C 烧录。这排除了设计最初采用的 STM32F103(仅支持 USART 引导加载程序)。在 JLCPCB 有库存且符合要求的 LQFP-48 芯片中:
| 候选型号 | 空白芯片支持 USB 引导 | 库存 | $@100 |
|---|---|---|---|
| CH32V203C8T6(选用) | ✅ | 8,643 | 0.877 |
| CH32X035C8T6 / CH32F203C8T6 | ✅ | ~500 | 0.72 / 1.02 |
| AT32F415CBT7 | ✅ | 10,518 | 1.319 |
| STM32F072C8T6 | ✅ | 2,945 | 2.495 |
这是有实际库存的最低价芯片,价格只有 STM32F072 的三分之一,而且与 STM32F103 的布局引脚兼容(33 个已连接引脚中有 32 个相同)。
选择该芯片的代价:
- 固件采用 RISC-V,使用 WCH HAL,不支持 CubeMX。
- ST-Link 无法使用。 调试通过 J9 上的 WCH 2 线 SDI 接口进行,需要 WCH-LinkE。日常烧录通过 USB 完成,因此调试探针仅用于调试。
- 该芯片的 PB2 是 BOOT1,因此通过 R17(5.1 kΩ)将其拉低。
3. 硬件
U4 INA180A2 (Kelvin across R18) ─► PA5 I_SENSE
J2 Servo V+ ── R18 5mΩ ──┬────────► servo header V+ rail (unfused)
(VSRV_RAW) ├─ R19..R22 ÷4 ─► PA4 V_SENSE
└─ JP1 ──D2──┐
├─► HT7533-1 ─► 3V3 ─► CH32V203, LED
USB-C VBUS 5V ─────────────D1──────────┘
GND: one continuous plane, common to both supplies
- 两个电源域,共用一个地。 D1/D2 构成二极管或电路,确保两路电源不会互相供电。每个舵机放大器都经过 R18,因此电流读数涵盖整个电路板。
- JP1(2 针排针,默认断开):安装跳线帽后,可在没有 USB 的情况下由舵机电源为逻辑电路供电——对应 Maestro 的
VSRV=VIN模块。 - JP2(2 针排针):将 BOOT0 拉高,仅用于首次烧录/恢复。
- 逻辑电路耗电约为 15 mA,因此即使使用 2S LiPo 供电,HT7533-1(100 mA,静态电流 2.5 µA)的功耗也只有 0.07 W。
- USB-C:CC 下拉电阻为 R14/R15,SRV05-4 用于钳位 D+、D−、CC1、CC2。
- 舵机信号为 3.3 V,经 220 Ω 电阻(R1–R12)连接。排针引脚顺序为 SIG / V+ / GND。
通道映射
| 通道 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 引脚 | PA0 | PA1 | PA2 | PA3 | PA6 | PA7 | PB0 | PB1 | PA8 | PA9 | PA10 | PB8 |
| 定时器 | T2C1 | T2C2 | T2C3 | T2C4 | T3C1 | T3C2 | T3C3 | T3C4 | T1C1 | T1C2 | T1C3 | T4C3 |
| 模拟输入 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | — | — |
保留引脚:PA4/PA5 用于电源轨检测 · PA11/PA12 用于 USB · PA13/PA14 用于 SDI · PD0/PD1 用于晶振 · PC13 用于 LED · PB2 用于 BOOT1。LQFP-48 只有 10 个 ADC 引脚,而 PA4/PA5 用于检测,因此模拟输入为 12 个通道中的 8 个——Maestro 12 的 12 个通道都支持模拟输入。
电源轨检测
| 电流(R18 + U4) | 电压(R19–R22) | |
|---|---|---|
| 元件 | 5 mΩ、1 W 分流电阻,INA180A2,增益 50,高侧检测 | 4 × 5.1 kΩ,÷4,100 nF |
| 满量程 | 13.2 A | 13.2 V |
| 分辨率 | 约 3.2 mA | 约 3.2 mV |
高侧检测可保持地平面完整。它测量的是电源轨的总电流,而非各通道的电流。ADC 的参考电压为 VDDA,即 LDO 输出电压(LQFP-48 没有 VREF+),因此读数适用于阈值判断,不适合校准计量。固件在连续 5 次读数异常后(约 50 ms)关闭所有通道:默认过流阈值为 5 A,欠压阈值则自动选择(2S → 6.4 V、3S → 9.6 V,其他情况关闭)。详情见 USER.md §4.4。
电源限制
| 限制 | 依据 | 数值 |
|---|---|---|
| J2 的绝对最大值 | C15/C16,16 V 电解电容 | 16 V |
| 完整功能(电压检测) | ÷4 分压器 | 13.2 V |
| 持续电流 | 排针排之间宽 2.4 mm 的铜箔 | 约 5 A(温升 20 °C 时为 6.1 A) |
限制因素不是 24 A 接线端子,而是它后面的铜箔。
PCB
双层板,每层 1 oz,厚 1.6 mm,最小线宽/间距 0.2 mm,过孔 0.3/0.6 mm。两层均铺设完整 GND 铜箔;SERVO_V+ 由三块按优先级排列的顶层区域承载。排针沿底边布置,USB-C 位于右侧,接线端子位于左侧,MCU 位于中央。
⚠️ F8(从原理图更新 PCB)会删除 H1–H4——它们没有原理图符号。请取消勾选 Delete footprints with no symbols,或在以下位置重新添加:(16, 4)、(61.5, 4)、(16, 33)、(61.5, 33)。
⚠️ HT7533-1 与它替代的 AMS1117 引脚不兼容(SOT-89:GND / VIN+散热片 / VOUT)。散热片引脚为 VIN。
4. 物料清单与成本
类别:B 基础 · P 优选(两者均免手续费)· E 扩展(SMT 需支付 $3.07 供料器费)。
| Ref | 零件 | LCSC | 类别 | 数量 | $/板 |
|---|---|---|---|---|---|
| U1 | CH32V203C8T6,LQFP-48 | C3001172 | E | 1 | 0.8770 |
| U2 | HT7533-1,SOT-89-3 | C14289 | B | 1 | 0.1430 |
| U3 | SRV05-4 ESD,SOT-23-6 | C558418 | E | 1 | 0.0270 |
| U4 | INA180A2,SOT-23-5 | C192764 | E | 1 | 0.1920 |
| J1 | USB-C 16P TYPE-C-31-M-12 | C165948 | E | 1 | 0.1860 |
| J2 | 5.08 mm 2P 螺丝接线端子 | C474952 | E (THT) | 1 | 0.1920 |
| J3–J8 | 1×6 2.54 mm 排针 | C37208 | E (THT) | 6 | 0.2520 |
| JP1, JP2 | 1×2 2.54 mm 排针 | C358684 | E (THT) | 2 | 0.0180 |
| Y1 | 8 MHz 晶振 SMD5032 | C115962 | B | 1 | 0.2450 |
| D1–D2 | B5819W,SOD-123 | C7420330 | P | 2 | 0.0340 |
| D3 | 红色 LED 0603 | C2286 | B | 1 | 0.0070 |
| R1–R13 | 220 Ω 0603(舵机串联电阻 + LED) | C22962 | B | 13 | 0.0650 |
| R14–R17, R19–R22 | 5.1 kΩ 0603 | C23186 | B | 8 | 0.0160 |
| R18 | 5 mΩ 1 W 分流电阻,1206 | C7419996 | E | 1 | 0.0370 |
| C1–C8, C17–C18 | 100 nF 0603 X7R | C14663 | B | 10 | 0.1200 |
| C9–C11 | 10 µF 0603 X5R | C19702 | B | 3 | 0.0960 |
| C12 | 1 µF 0603 | C15849 | B | 1 | 0.0170 |
| C13–C14 | 30 pF 0603 C0G | C1658 | B | 2 | 0.0160 |
| C15–C16 | 470 µF 16 V 电解电容 | C46550400 | E | 2 | 0.2140 |
| 58 | $2.7540 |
J9(SDI)不安装。分流电容(C100114,每块板需两个)无法由 JLCPCB 安装——请单独订购,每 100 个约 $1.80。
| 100 个 | 总计 | 每块板 |
|---|---|---|
| 元件 | $275.40 | $2.754 |
| 组装:设置费 $8.18,钢网 $1.53,SMT 167 个焊点 $26.72,THT 42 个焊点 $68.88 + $3.58,6 项供料器费 $18.42 | $127.31 | $1.273 |
| PCB 制板(估算) | ~$40 | ~$0.40 |
| 总计 | ≈ $443 | ≈ $4.43 |
不含运费和关税。价格按 LCSC 采购 100 个计算;库存核查日期为 2026-09-19/20(CH32V203 库存最少,仅 8,643 个)——下单前请重新确认。
成本构成:
- 通孔焊接占组装成本的 57 %。 J3–J8 的元件成本为 $0.25,手工焊接成本为 $0.59。若仅采用 SMT,并另购排针,组装成本可降至每块板 $0.55。
- 成本关键在于独有的扩展 SMT 零件,而非单价。 因此,220 Ω 电阻兼作 LED 电阻,5.1 kΩ 电阻用于 CC1/CC2/BOOT0/BOOT1/分压器,一个 SRV05-4 替代分立 TVS 二极管,JP1/JP2 共用同一种排针零件。
5. 固件(embedded-ch32/)
RISC-V、WCH ch32v20x HAL 和 USB 设备库、xPack riscv-none-elf-gcc
15.2(使用 make GCC_PATH=... 覆盖)。版本为 USBServoController 0.4。
| Flash 区域 | 地址 | 大小 | 内容 |
|---|---|---|---|
| Bootloader | 0x0000 | 12 KB | 自有 USB CDC bootloader(bootloader/) |
| 应用程序 | 0x3000 | 48 KB | 舵机固件 |
| 脚本 | 0xF000 | 2 KB | 存储的板载脚本 |
| 设置 | 0xF800 | 已使用 256 B | 行程限位、Maestro 速度/加速度(User/settings.c、W) |
布局定义在 User/flash_layout.h 和两个 Link.ld 文件中。
make # build/USBServoController-ch32.{elf,hex,bin}
make flash # BOOT command -> bootloader -> write, CRC-32 check, restart (~3 s)
make hosttest # on the PC: sense.c protection (21 supply scenarios), maestro.c protocol, ramps and limits (11)
python tools/verify_pinmap_ch32.py # schematic <-> pin table <-> firmware
**空白芯片或恢复:**运行 make full,插上 JP2,再连接 USB,
运行 wchisp flash build/USBServoController-ch32-full.bin,拔掉 JP2,重新插拔 USB。
在这款芯片上,从固件跳转到 ROM bootloader 不起作用(已测试),
因此电路板配备了自己的 bootloader。
**时序:**定时器频率为 96 MHz,PSC 47 → 0.5 µs 计时周期,ARR 39999 → 20 ms 帧。 0.25 µs 需要 4 MHz 计时频率,只有在 ≥ 100 Hz 时才能用 16 位计数器实现。
**协议:**每行一条 ASCII 命令,每条回复为 OK / OK <value> / ERR <reason>。
舵机(S G E X A)、电源轨检测(I U F L P C Z N)、存储的脚本
(QC QA QS QI QG QR QX)、系统(V BOOT)。完整参考:USER.md §4.3。
Maestro 协议(User/maestro.c):0x80 及以上的字节是 Pololu
Maestro 命令,支持 Compact、Pololu(设备 12)和 Mini SSC 帧格式,并使用 Maestro 自身的单位在板载端进行速度和加速度渐变。两种协议共用端口。参考:USER.md §4.3b。
脚本引擎(User/script.c):最多支持 254 条指令,包括带渐变时间的移动、等待、同步、循环、跳转、模拟量等待/分支。脚本由 tools/servoscript.py 从文本编译而来,可在无 PC 时运行,也可选择在上电时运行。
工具链注意事项
- 上游 GCC 会静默忽略
interrupt("WCH-Interrupt-fast")— 会发出一条警告,随后 ISR 以ret而不是mret结束。请使用interrupt("machine")。 - GCC 15 默认使用 C23,此时
bool是关键字;WCH 的usb_type.h会对其进行 typedef。构建时使用了-std=gnu11和一个修补过的头文件。 -march=rv32imac_zicsr_zifencei— GCC 15 将 CSR 和 fence.i 拆分了出来。- 运行时不使用
printf。 bring-up 时,WCH 示例代码在 USB 挂起钩子中调用printf导致 ISR 卡住,而且 PA9(USART1 TX)是舵机输出引脚。
修改过的厂商文件:usb_endp.c(OUT 端点 → 解析器)、usb_prop.c
(通过 User/cdc_glue.c 处理线路编码)、ch32v20x_it.c(TIM2 驱动舵机)。
6. 局限性及与 Maestro 12 的比较
| Maestro 12 | 本板 | 改进方案 |
|---|---|---|
| mini-USB | USB-C | 更好 |
| 无电源轨检测 | 电流和电压检测、过流保护及 LiPo 截止保护 | 更好 |
| $29.95 | ≈ $4.43 | 更好 |
| 5–16 V 舵机电源 | 5–16 V(完整功能支持 13.2 V) | 持平 |
| 12 路模拟输入 | 8 路 | 改版(引脚数量限制) |
| 5 V 信号、5 V 用户引脚 | 3.3 V,无 5 V 电源轨 | 改版 |
TTL 串口、菊花链、ERR 引脚、3 个 LED | 仅 USB、1 个 LED | 改版 |
| Pololu / Compact / Mini SSC 协议 | 支持(0.4):设置目标位置、速度、加速度,读取位置 / 运动状态 / 错误,回到原点 | 持平 |
| 每通道最小/最大值 64–4080 µs,1–333 Hz | 每通道限值为 64–4080 µs,通过 W 保存;固定 50 Hz | 频率:固件 |
| 0.25 µs 分辨率 | 0.5 µs | 固件,且需 ≥ 100 Hz |
| 由固件实现速度和加速度 | 支持通过 Maestro 协议实现 | 持平 |
| 闪存中存储设置、原点位置、启动行为 | 存储限值和速度/加速度;无原点位置,所有通道启动时均关闭 | 固件 |
| 错误寄存器、串口超时故障保护 | 仅协议错误位;无串口超时 | 固件 |
| 8 KB 脚本语言 | 254 条指令的运动脚本 | 更简单 |
| Maestro Control Center | 自有 GUI(servogui.py) | 受 Pololu VID 限制 |
| 28 × 36 mm | 66 × 38 mm | — |
其他已知缺陷:J2 没有反接保护——电池组接反会损坏 U4,并可能导致 C15/C16 泄压(有意省略了 P-FET 理想二极管,成本约 $0.19);断电后会丢失电流检测零点(Z)。
加入 Maestro 生态系统
Maestro 软件分为两部分。运行时控制——几乎所有社区库(FRC4564/Maestro、maestro-servo、ROS 1/2 驱动程序、Node、C++)——都会打开 CDC 端口,并使用 Pololu/Compact/Mini SSC 字节协议,不检查 USB ID。配置(Control Center、UscCmd)使用绑定到 Pololu VID 0x1FFB 的控制传输,因此在这里永远无法工作。
固件 0.4 实现了这些串行协议,因此运行时库无需修改即可工作:已在硬件上使用未修改的 FRC4564 maestro.py 验证(目标、速度、加速度、位置、运动状态)。根据首字节进行一次分发即可支持所有协议:0xAA 为 Pololu,0xFF 为 Mini SSC,0x80–0xFE 为 Compact,可打印的 ASCII 字符则使用现有协议。
与 Maestro 仍有差异:输出步进为 0.5 µs(0.25 µs 需要 ≥ 100 Hz 的帧率)、固定 50 Hz 帧率、没有原点位置、CRC 或串行超时。每通道的行程限制(64–4080 µs)以及启动速度/加速度通过 W 存储在板上——GUI 的齿轮按钮可设置限制。后续计划:可配置帧率 → 串行超时故障保护 → 原点位置。
7. 设计说明
JP1 是排针,不是电源多路复用 IC。 6 V 以上的自动多路复用需要理想二极管控制器和 FET(LM5050,每块板增加 $2.12);TPS2116 的上限为 5.5 V。二极管或电路成本为 $0.03,且 JP1 仅承载约 15 mA 的逻辑电流。排针和分流帽($0.05)比滑动开关更便宜,而且本身没有电压限制。
JP2 也是排针,因此每块板首次烧录所需的那个跳线无需使用烙铁。
HT7533-1 替代了 AMS1117;后者尺寸过大 66 倍,静态电流为 5 mA,而且需要 22 µF 钽电容。HT7533 更便宜,可承受 30 V,并且与现有的 10 µF 陶瓷电容搭配时稳定。
8. 仓库结构
| 路径 | 内容 |
|---|---|
PCB/usbservocontroller/ | KiCad 10 原理图和电路板;production/ = Fabrication Toolkit 输出 |
embedded-ch32/ | 应用固件(User/)、引导加载程序(bootloader/)、主机测试(test/) |
embedded-ch32/tools/ | verify_pinmap_ch32.py;将 wchisp 下载到此处(不要放进仓库) |
tools/ | 主机工具——参见 tools/README.md |
USER.md | 用户手册 |
Fabrication Toolkit 从封装读取
LCSC,而不是从符号读取。同步原理图后,检查grep -c 'property "LCSC"' usbservocontroller.kicad_pcb(目前为 58)——缺少字段时,JLCPCB 会显示“part not found”。
9. 下次打样前
根据 2026-09-29 的文件检查:ERC 0,DRC 11 个错误,均为固有的排针 Courtyard 重叠(在 2.54 mm 网格上排列成三行),未连接项为 0。
- 修正 JP2 的电路板位号。 封装被标记为
BOOT0_SEL而非JP2,因此 DRC 会报告 JP2 缺失并多出一个封装,打样文件也会带有错误的位号。运行 F8(不要勾选 Delete footprints with no symbols)。 - 将 J9 设为 DNP,并将 H1–H4 排除在 BOM/位置文件之外。 这两个标志目前都未设置,因此
fabrication-toolkit-options.json中的EXCLUDE DNP不起作用。 - 将 R13 从 220 Ω 改为 1 kΩ(C21190,Basic)。PC13 的额定电流为 3 mA;220 Ω 会使 LED 电流达到约 6 mA。首块板能正常工作,但超出规格。
- 删除 3 个重复过孔(GND 位于 11.5、35.2;I_SENSE 和 V_SENSE 位于 32、16–18 附近),并决定如何处理 Courtyard 错误——缩小 Courtyard,或添加 DRC 排除项,以免真正的错误被掩盖在其中。
- 重新生成
production/——该目录内容来自 2026-09-20,早于上一次电路板修改。然后检查bom.csv和positions.csv中是否已移除 H1–H4 和 J9。 - 重新验证 JLCPCB 库存(§4)。
使用 kicad-cli sch erc usbservocontroller.kicad_sch 和
kicad-cli pcb drc --schematic-parity usbservocontroller.kicad_pcb 重新运行检查。
许可证
MIT — 硬件设计文件、固件和主机工具。
带有 WCH(南京沁恒微电子)版权声明的文件——ch32v20x HAL、USB 库、启动代码,以及 embedded-ch32/User/ 中基于 WCH 的文件——仍受 WCH 自身条款约束,这些条款将其使用范围限定为 WCH 微控制器。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。