ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

双STM32六足机器人:舵机PWM控制与步态算法实现解析

双STM32六足机器人:舵机PWM控制与步态算法实现解析 简介基于 STM32 的六足机器人控制系统完整设计资料涵盖结构分析、步态控制、多模式交互与软硬件协同实现可作为单片机、嵌入式方向课程设计或毕业设计的综合参考。系统采用主控板与舵机控制板分离的双板架构主控 STM32F103VET6 负责数据处理与显示舵机控制板 STM32F103R8T6 负责角度控制两板通过串口通信同时引入无线网络、蓝牙、语音识别、手势识别及云端服务器可针对不同应用场景选择不同控制方案。压缩包共 944 个文件、约 101.91MB涵盖 C 语言源码与头文件、Keil 工程、Altium Designer 原理图与 PCB、制板文件、安卓工程与手机安装包、PDF 说明等能够支撑从源码阅读、电路打样、焊接测试到移动端验证的完整流程。目前已有 314 人学习。配套资料中还提供可直接安装调试的手机 APP、云端平台 C# 服务端代码及完整机器人工程文件方便核对硬件连接、复现步态算法并扩展语音/手势控制逻辑适合需要一手项目资料或二次开发的学习者。1. 双核驱动的六足机器人为什么一块 STM32 不够用六足机器人最容易翻车的地方不是算法本身而是舵机一多单片机的中断和时序就全面失控。常见配置六条腿各带 3 个舵机共 18 路 PWM 要持续刷新与此同时还要处理蓝牙、WiFi、语音和手手势识别数据单颗 STM32F103C8T6 的资源在真实负载下非常吃紧。BlackPearlRobot 工程给出的方案是把系统拆成主控板和舵机控制板主控板用 STM32F103VET6 负责通信决策与指令仲裁舵机板用 STM32F103R8T6 专职输出 PWM两块板之间通过串口交换数据。这个架构把实时性要求高的舵机刷新和实时性要求高但频率低的控制逻辑解耦适合课程设计也适合作为量产前验证的原型。2. 双 STM32 硬件分工与舵机板 PWM 资源设计2.1 为什么把控制权拆成两块板单芯片方案不是不能跑一块高主频 STM32F4 也能同时完成 18 路 PWM 和通信处理但 103 系列定位下把负载分开是性价比最高的做法。舵机 PWM 刷新周期通常 20ms即 50Hz在一个周期里 18 路舵机的脉宽要精确到微秒级任意一路的中断延迟抖动都会让舵机表现为抖动或异响。当主控板同时在做步态计算、串口解析、语音指令识别和 WiFi 数据转发时中断嵌套会让 PWM 输出的 jitter 明显增大。舵机控制板的任务被压缩到只剩两个解析串口协议、更新 PWM 比较寄存器。这样舵机刷新不依赖操作系统和复杂逻辑十六条物理链路的数据流是确定的。主控板则把精力放在步态状态机和工作模式切换上两边各干各的出问题时也更容易通过串口日志定位是通信层还是控制层的问题。2.2 舵机控制板的 PWM 定时器映射舵机控制板选用 STM32F103R8T6它提供 TIM1、TIM2、TIM3、TIM4 四个可输出 PWM 的定时器每个定时器 4 个通道共 16 路。对于 18 自由度六足机器人直接映射还差两路工程上常见三种补法一是减少死重舵机把六足设计成 12 路舵机每条腿 2 个自由度二是通过 I2C 外扩 PCA9685三是把两条步态同步的腿部舵机并联在同一通道。第三种做法在测试中容易出现堵转电流叠加烧驱动器我一般不会用。更稳妥的是保留 16 路定时器 PWM剩余两路用一个独立小舵机板或 PCA9685 补足。一个常规的通道分配表格如下实际编号按工程中的 BLackPearlRobot 舵机索引即可。定时器通道 1通道 2通道 3通道 4TIM1左前腿髋左前腿大腿左前腿小腿左中腿髋TIM2左中腿大腿左中腿小腿左后腿髋左后腿大腿TIM3右前腿髋右前腿大腿右前腿小腿右中腿髋TIM4右中腿大腿右中腿小腿右后腿髋右后腿大腿PWM 初始化时要把定时器分频和重装载值算准。以 72MHz 系统时钟为例输出 50Hz 的 PWM预分频 PSC 设为 71这样计数频率是 72MHz / (711) 1MHz即每计数一次为 1 微秒。自动重装载值 ARR 设为 19999得到 1MHz / 20000 50Hz。舵机脉宽 0.5ms 到 2.5ms 对应 CCR 值 500 到 2500。初始化代码里要把定时器的 PWM 模式配成向上计数、输出极性为高这样逻辑分析仪观察到的波形和舵机实际响应一致。2.3 双板串口通信协议设计主控板与舵机控制板之间采用串口进行数据交互波特率 115200 在 20ms 的控制周期内足够传输完整的舵机角度帧。协议帧的格式是帧头 0xAA 0x55命令字18 路角度数据每路 2 字节高位在前最后加一个累加和校验。帧头防止串口错位校验字节防止干扰导致舵机误动作。typedef struct { uint8_t head[2]; uint8_t cmd; uint16_t angle[18]; uint8_t checksum; } ServoFrame; uint8_t calc_checksum(const ServoFrame* f) { uint8_t sum 0; for (uint16_t i 0; i 38; i) { sum ((uint8_t*)f)[i]; } return sum; }代码里的angle[18]存放舵机目标角度值单位是 0.1 度所以 900 代表 90 度。calc_checksum把整个帧结构按字节累加帧尾的checksum字段与累加值相等时才执行角度更新。实测中出现舵机随机抖动时先看校验失败的帧占比如果校验失败率高优先排查串口共地问题和舵机大电流对逻辑电源的冲击而不是改协议。3. 原理图与 PCB 实现Altium Designer 16 的布板细节与打样调试3.1 最小系统四件套启动、晶振、复位、下载主控板在 Altium Designer 16 中完成原理图和 PCB 设计围绕 STM32F103VET6 的最小系统有四块电路必须画对。启动电路用 BOOT0 和 BOOT1 跳线组合正常运行时 BOOT0 拉低选择 Flash 启动需要 ISP 升级时拉高。晶振电路给主控提供 8MHz 主频和 32.768kHz 的 RTC 时钟源两个负载电容各取 20pF 左右布局时晶振尽量贴近 MCU 引脚走线要短且对称。复位电路使用 RC 复位10kΩ 电阻上拉到 3.3V100nF 电容对地复位时间常数约 1ms按下复位按键时能产生可靠的低电平复位信号。下载接口直接引出 SWD 四线SWDIO、SWCLK、GND、3V3。相比串口 ISPSWD 在板子调试阶段更实用不占用串口资源也不受 BOOT 跳线状态影响。原理图绘制时STM32 每个电源引脚旁边都要放一个 100nF 去耦电容并且电容物理位置要尽量靠近对应电源引脚如果打样回来发现程序跑飞或 ADC 采样跳动先检查是不是去耦电容离引脚太远。3.2 电源树与模块接口的噪声控制整版电源树从外部 5V 输入开始5V 直接供给舵机电源轨逻辑部分经 AMS1117-3.3 稳压到 3.3V。舵机属于大电流脉冲负载瞬间电流可达 2A 级别所以舵机电源和逻辑电源要完全分开走线只在输入端共地。ESP8266 在 WiFi 发射时电流尖峰明显必须在模块电源引脚就近放置 1000μF 电解电容和 0.1μF 陶瓷电容并联否则 WiFi 透传时主控板会随机复位。PCB 布线时注意几个关键规则信号类型最小线宽间距要求说明舵机电源 5V40mil与信号线 10mil载流决定线宽可铺铜加厚3.3V 逻辑电源20mil与地间距 8mil电源平面扇出串口/USB 信号10mil与电源线 8mil差分对等长晶振走线10mil包地处理走线下方不要铺其他信号在 Altium Designer 16 里除了在 Rule 菜单里设定这些线宽和间距规则还要给 GND 做铺铜。打样回来后焊接顺序也有讲究先焊电源部分上电用万用表量 3.3V 是否正常再焊晶振和复位电路用示波器确认 8MHz 波形起振最后焊 STM32 和 SWD 接口连接 ST-Link 能读到芯片 ID 才算最小系统通过再逐个焊接外设接口。一次把所有元件焊完再上电的做法在小批量调试中很容易烧板不推荐。4. 步态算法与多控制模式从三脚步态到云端指令链4.1 六足结构自由度与舵机转角约束六足机器人的腿部机构采用三条腿各 3 个自由度的构型基节舵机负责腿部前后摆动大腿舵机负责抬腿高度小腿舵机负责足端着地姿态。每个舵机有机械限位典型范围是基节 -90° 到 90°大腿 -45° 到 135°小腿 -30° 到 150°超出范围就会堵转。步态算法输出的角度必须经过限幅避免舵机齿轮打齿。运动学逆解的目标是把足端坐标映射成三个舵机角度。基节角由足端位置在水平面上的投影和机器人身体中心的连线与正前方夹角决定大腿和小腿角则由两点距离配合余弦定理求解。4.2 三脚步态的时序编排六足机器人最基本的稳定步态是三脚步态六条腿分成两组第一组是右前、左中、右后第二组是左前、右中、左后两组交替支撑和摆动。任意时刻至少有三条腿着地组成一个三角形支撑面重心落在三角形内就能保持静止或缓慢移动稳定。步态周期参数放在步态结构体里通过调整抬腿高度、步幅和周期来适配不同的地面条件。typedef struct { uint8_t swing_phase; // 0 表示支撑相1 表示摆动相 uint16_t cycle_time_ms; // 完整步态周期如 600ms int16_t step_height; // 抬腿高度单位 0.1mm int16_t step_length; // 步幅单位 0.1mm int16_t body_height; // 机身高度单位 0.1mm } GaitParam; int16_t leg_angle[6][3]; void update_gait(GaitParam* gait, uint16_t elapsed_ms) { for (int leg 0; leg 6; leg) { int phase ((elapsed_ms * 2 / gait-cycle_time_ms) leg) % 2; if (phase 0) { // 支撑相足端相对身体后移推动身体前进 joint_trajectory(leg, 0, -gait-step_length / 2); } else { // 摆动相足端抬起并向前摆动 joint_trajectory(leg, gait-step_height, gait-step_length / 2); } } }update_gait按时间递进每组三条腿交叉进入摆动相。phase的计算把腿编号偏移加入时间轴避免所有腿同时切换导致重心失稳。摆动相里的joint_trajectory负责把足端轨迹平滑转换到舵机角度如果直接阶跃切换角度机器人会像抽搐一样前进。控制周期建议 10ms 一帧步态周期 600ms 时一个周期内更新 60 次舵机运动曲线足够平滑。4.3 WiFi、蓝牙、语音、手势的指令汇聚4.3.1 本地链路的优先级仲裁系统支持 WiFi、蓝牙、语音识别和手势识别四种控制方式。WiFi 采用 ESP8266 透传模块默认 AT 固件主控通过串口发送 AT 指令配置为 STA 模式连接路由器手机 APP 通过 TCP 连接模块的 8080 端口下发动作指令。蓝牙使用经典蓝牙透传模块配对后 APP 直接用虚拟串口发送数据。语音识别选用离线模块通过串口输出识别到的关键词编号。手势识别则是把惯性传感器佩戴在手腕上板载姿态解算输出手势标签。主控板串口规划USART1 接 ESP8266USART2 接蓝牙USART3 接舵机控制板语音和手势分别占用 USART4 和 USART5。多路指令同时到达时必须有仲裁机制实际操作中把指令按优先级分级控制源优先级典型指令语音急停最高“停止”触发立即停车蓝牙手柄高前进、后退、转弯手势识别中向左、向右云端 APP低路径规划、远程巡检这些指令统一进入主控命令队列高优先级可以直接抢占低优先级指令例如语音急停在任何状态下都要立刻置零舵机目标角度不能让云端指令把当前状态覆盖掉。4.3.2 云端指令流与 C# 服务端云端平台采用 C# 实现常见做法是使用 ASP.NET Core 建一个 WebSocket 或者 SignalR 服务把手机 APP 和机器人端的 ESP8266 连接在一起。手机通过 WiFi 或 4G 访问云端云端再把控制指令推送到机器人的 TCP 长连接上。信号从请求产生到舵机动作的链路是APP 按下前进按钮发起 HTTP 或 WebSocket 请求云端收到后查寻在线设备表把指令转发给对应设备ESP8266 收到后经串口交给主控主控调步态更新再由串口把角度帧给舵机板。public class CmdHub : Hub { public async Task SendCmd(string deviceId, string cmd) { // 设备端通过 RegisterDevice 加入设备组 await Clients.Group(deviceId).SendAsync(cmd, cmd); } }deviceId是每一台六足机器人的唯一标识比如BLACKPEARLROBOT_01。SendCmd把指令投递到对应 SignalR 分组ESP8266 端的客户端库负责接收并回传给主控。这里要注意只控制指令若走公网云端和机器人之间必须做设备鉴权和指令合法性校验否则任何连上网的人都能控制你的机器人。5. 上位机联调技巧串口抓包、参数标定与工程文件规范很多六足机器人调试到最后才发现问题全出在舵机角度和通信帧错位上所以建议先把上位机联调工具链跑通再整机测试。用 Android Studio 开发的应用可以实时下发指令但我在整机测试时习惯先做一个 Python 串口回放脚本直接通过 USB 转串口连接主控板把要测试的步态数据逐帧发出去避免手机端的问题倒灌到机器人端。import serial, struct, time ser serial.Serial(COM5, 115200, timeout0.1) for i in range(100): frame bytes([0xAA, 0x55, 0x01]) struct.pack(36H, *angles) bytes([0xFF]) ser.write(frame) time.sleep(0.01)angles是 18 个舵机角度列表代码里使用大端序打包成帧。这个脚本的价值在于可以通过修改angles直接验证舵机正反向、限位是否一致同时用串口打印主控返回的应答帧来判断协议是否闭环。测试步态时建议先把所有舵机置于中位用手按压机器人身体确认每个关节的物理方向与逻辑方向一致避免反转错误被放大成步态错乱。舵机标定要逐个通道进行记录实测脉宽和理论值的偏差通道中位脉宽/μs最小脉宽/μs最大脉宽/μs死区修正11505510249512214985052490-6死区修正是把实测中位与理论 1500μs 的偏差写入主控的参数表里角度计算时统一补偿否则六条腿在空载时看起来位置一致负载后整体往一侧偏。标定完成后把参数表导出成头文件和固件一起打 tag 归档。工程文件从 YS-V0.3 到 YS-V0.7 的版本演进过程里固件、AD 工程和 APP 源码的版本号需要保持同步建议每次改动硬件布局或舵机映射时同步更新BLACKPEARLROBOT.apr对应的宏定义文件并在源码仓库里写清楚改动点。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进