1. 硬件选型与核心模块解析

做四足机器人最头疼的就是硬件选型了,我刚开始玩的时候踩过不少坑,要么是舵机扭矩不够,要么是主控性能不足。经过多次实测,最终确定了这套高性价比方案:STM32F103C8T6作为主控,PCA9685驱动舵机,SG90作为执行单元,JDY-31实现蓝牙控制,再加上OLED显示屏用于状态监控。

STM32F103C8T6 这颗芯片真是性价比之王,72MHz的主频完全能满足实时控制需求,128KB闪存足够存放复杂的步态算法。我特别喜欢它的外设资源,光是定时器就有11个,PWM输出根本不用愁。最重要的是社区资源丰富,遇到问题随便一搜就有解决方案。

PCA9685舵机驱动板 绝对是多舵机项目的救星。之前用STM32直接驱动12个舵机,引脚根本不够用,还要外加电平转换电路。这个芯片通过I2C就能控制16路PWM,精度达到12位(4096级),而且自带时钟发生器,不占用主控资源。实测下来发现,它还能输出最高1526Hz的PWM频率,比普通舵机50Hz的控制频率精准多了。

这里有个实际接线技巧:VCC要接5V才能保证舵机扭矩,但逻辑电平是3.3V兼容的。SDA和SCL记得接上拉电阻,我一般用4.7kΩ的,通信距离可以到1米左右。

SG90舵机 虽然便宜,但要注意扭矩只有1.6kg·cm。如果机器人重量超过400g,建议升级到MG90S金属齿轮舵机。控制原理很简单:0.5ms脉冲对应0度,1.5ms对应90度,2.5ms对应180度。不过实际测试发现,不同厂家的舵机中位点可能有偏差,需要单独校准。

JDY-31蓝牙模块 比HC-05好用太多,默认就是透传模式,不需要额外配置。支持AT指令修改设备名和波特率,我最喜欢它的自动连接特性,配对过一次之后上电自动回连。实测在开阔场地传输距离能达到20米,室内隔一堵墙还有10米左右。

OLED我选用的是0.96寸SSD1306驱动的那款,四线I2C接口,只占用2个IO口。显示功耗极低,适合电池供电场景。编程时注意要使用硬件I2C,软件模拟I2C在控制多个舵机时可能会产生干扰。

2. 硬件连接与电源管理

硬件连接可不是简单插线就行,我吃过亏才总结出这些经验。先来看核心接线表:

模块STM32引脚连接方式注意事项
PCA9685PB6(I2C1_SCL), PB7(I2C1_SDA)I2C需4.7k上拉电阻
JDY-31蓝牙PA9(TX), PA10(RX)串口1交叉连接(TX-RX)
OLED显示屏PB10(I2C2_SCL), PB11(I2C2_SDA)I2C地址通常0x78
舵机信号线接PCA9685输出口PWM注意电源隔离

电源设计是关键中的关键!最初我直接用开发板的5V输出给所有舵机供电,结果一动起来就重启。后来才明白,舵机启动瞬间电流可能达到2A,必须独立供电。我的方案是:18650锂电池组(7.4V)经过MP1584降压模块生成5V舵机电源,再经过AMS1117-3.3产生MCU电源。一定要在电源入口加1000μF的电解电容缓冲瞬间电流。

布线时要注意数字地和功率地分开,最后在电源入口处单点共地。舵机信号线尽量远离电源线,我都是用绞线方式减少干扰。每个舵机旁边最好加个0.1μF的去耦电容,特别是当舵机数量多于4个时。

3. CubeMX工程配置详解

用CubeMX配置工程能省一半时间,特别是时钟树配置。我习惯先开启外部晶振(HSE),然后选择PLL倍频到72MHz。调试接口一定要选SWD,留出调试后路。

I2C配置有两个要点:PB6/PB7对应I2C1,PB10/PB11对应I2C2。速度都用标准模式(100kHz)足够,高速模式反而容易受干扰。记得开启I2C中断,这样读写操作不会阻塞主循环。

串口配置要特别注意:JDY-31默认波特率是9600,但实际测试发现115200更稳定。开启串口中断并设置接收缓冲区,我一般用DMA方式接收,避免丢失数据。

定时器是关键资源!TIM1和TIM8是高级定时器,可以产生互补PWM,但这里我们用不到。我给系统滴答留了TIM2,舵机控制完全交给PCA9685,这样就释放了STM32的定时器资源。

时钟树配置要一步步来:先选择HSE作为时钟源,PLL倍频系数设9,因为8MHz晶振×9=72MHz。APB1总线频率不能超过36MHz,APB2可以到72MHz。USB时钟需要48MHz,不过我们这个项目用不到。

GPIO设置也有讲究:所有空闲引脚都设为模拟输入,这样可以降低功耗。调试用的LED灯接在PC13,推挽输出模式。按键接PA0,上拉输入模式。

4. 舵机控制原理与校准

虽然用了PCA9685,但底层原理必须懂。PCA9685的寄存器映射很巧妙:LED0_ON_L、LED0_ON_H、LED0_OFF_L、LED0_OFF_H四个寄存器控制一个通道。通常我们把ON时间设为0,用OFF时间控制脉宽。

计算公式是这样的:PWM频率=25MHz/(4096×prescale)。预设分频器计算公式:prescale = round(25MHz/(4096×freq)) - 1。对于50Hz舵机,prescale=121(实测值)。

具体脉冲宽度计算:脉冲计数 = (脉宽时间 × 4096 × 频率) / 1000。比如1.5ms脉宽在50Hz时:1.5×4096×50/1000=307.2,取整307。

舵机校准是我花时间最多的部分。每个舵机都要单独校准:先给中位信号(1.5ms),然后机械臂安装到90度位置。用以下代码实现微调:

void servo_calibrate(uint8_t ch, float angle) {
    float pulse_width = 1.5 + (angle / 90.0); // 0.5-2.5ms对应0-180度
    uint16_t pulse_count = (uint16_t)(pulse_width * 4096 * 50 / 1000);
    pca9685_set_pwm(ch, 0, pulse_count);
}

实际测试发现,廉价舵机存在死区问题,就是小角度变化时不动。解决方法是在角度变化小于2度时保持原位置,或者采用增量式控制。

5. 四足机器人机械结构设计

结构设计直接影响运动性能。我最初用3mm亚克力板,结果走几步就裂了。后来改用3D打印PLA材料,填充率20%,层厚0.2mm。关键受力部位要加厚,腿关节处要设计加强筋。

每条腿两个自由度:髋关节控制前后摆动,膝关节控制抬腿高度。关节间距很重要:大腿长度建议80-100mm,小腿长度60-80mm。太长了重心不稳,太短了步幅不够。

舵机安装位置有讲究:髋关节舵机要尽量靠近身体中心,降低转动惯量。膝关节舵机放在大腿末端,这样小腿重量最轻。所有线材要走内腔,避免运动时缠绕。

重心计算不能忽略!电池要放在身体中心位置,我用的是18650电池组,重量约120g。整机重量控制在400g以内,否则SG90舵机扭矩不够。实测单个舵机在5V供电时能提供1.6kg·cm扭矩,足够支撑100g的负载。

装配技巧:先用M2螺丝固定舵盘,然后安装舵臂。所有螺丝不要一次拧紧,先调整到合适位置再逐步紧固。关节处要留0.5mm间隙,避免卡死。

6. 步态算法设计与实现

四足步态最稳定的是对角步态:左前右后腿一起动,右前左后腿一起动。这样始终有三个点着地,重心投影永远在支撑三角形内。

我设计的步态周期分四相:支撑相、抬腿相、摆动相、落腿相。每个相位占25%周期,通过定时器中断实现平滑过渡。

关键参数表:

参数数值说明
步态周期1000ms完整一步的时间
步幅60mm单步移动距离
抬腿高度30mm避免磕碰地面
身体高度120mm重心高度

逆运动学计算是核心。从足端坐标反算关节角度要用几何法:

void leg_ik(float x, float y, float z, float *hip_angle, float *knee_angle) {
    float L1 = 80.0; // 大腿长度
    float L2 = 60.0; // 小腿长度
    float D = sqrt(x*x + y*y + z*z);
    *knee_angle = acos((L1*L1 + L2*L2 - D*D) / (2*L1*L2));
    *hip_angle = atan2(y, x) + asin(z/D);
}

实际编程时要加入限制保护,每个关节都有运动范围。髋关节±45度,膝关节0-90度。超过范围就取边界值,避免舵机卡死。

步态生成器用状态机实现:IDLE->LIFT->SWING->DROP->SUPPORT。每个状态持续250ms,用定时器中断触发状态迁移。在中断服务函数里计算下一时刻的各关节角度,然后通过PCA9685输出。

7. 蓝牙遥控与状态显示

JDY-31蓝牙模块配置成透传模式后,就像有线串口一样方便。我定义了一套简单的控制协议:首字节0xFF,第二字节命令码,第三字节数据,第四字节校验和。

常用命令码表:

命令码功能数据范围
0x01前进/后退0-100%速度
0x02左转/右转0-100%角度
0x03身体高度80-150mm
0x04步态切换0-3种步态

在串口中断服务函数中解析数据:

void USART1_IRQHandler(void) {
    static uint8_t buffer[4], index=0;
    uint8_t data = USART1->DR;
    if(index==0 && data!=0xFF) return;
    buffer[index++] = data;
    if(index==4) {
        if(check_sum(buffer)) execute_cmd(buffer);
        index = 0;
    }
}

OLED显示实时状态:第一行显示电池电压,我用分压电阻采样电压,精度到0.1V。第二行显示当前步态和速度。第三行显示蓝牙连接状态。第四行显示错误码,比如舵机卡死会显示ERROR 01。

电池电量检测很重要,我用ADC采样电压值,当电压低于6.5V(3.3V×2)时闪烁警告,低于6.0V自动进入休眠状态,保护锂电池不过放。

8. 系统调试与优化技巧

调试最好分步进行:先调通单个舵机,再调单条腿,最后协调四条腿。用示波器看PCA9685输出的PWM波形,确保频率和脉宽准确。

常见问题1:舵机抖动。通常是电源功率不足,我在每个舵机供电脚并联了100μF电容解决。也可能是机械阻力太大,加点润滑油就好。

常见问题2:走路歪斜。原因是舵机中位不准,要用前面说的校准方法逐个调整。也可能是地面不平,可以加入陀螺仪检测姿态。

常见问题3:蓝牙控制延迟。增加数据校验和重发机制,每个命令发送两次,间隔100ms。我在APP端做了按钮按住连续发送,松开立即停止的控制逻辑。

功耗优化技巧:不用的时候进入睡眠模式,电流从120mA降到15mA。舵机保持力矩很大,可以在停止时发送松弛命令,让舵机断电。

稳定性提升:加入异常检测机制,当某个舵机电流异常增大时自动停止。我在每个舵机电源回路加了0.1Ω采样电阻,通过ADC检测电流。

最后给大家分享我的调试心得:先用手机蓝牙调试助手测试通信,再用串口助手监控数据。机械部分要先静态调试再动态测试,步态要先从慢速开始逐步加速。遇到问题不要慌,百分之九十都是电源或接线问题。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐