1. 平衡车控制系统概述
两轮自平衡车作为典型的嵌入式控制系统,融合了传感器技术、电机控制、自动控制理论等多个领域的知识。这个项目基于STM32F407工业级MCU,实现了完整的平衡车控制系统,包含姿态解算、运动控制、电机驱动和通信接口等核心模块。
在实际工程应用中,平衡车系统需要满足几个关键指标:首先是实时性,控制周期必须足够短(通常5-10ms)才能保证系统稳定性;其次是鲁棒性,要能应对各种异常情况;最后是扩展性,便于功能升级和硬件适配。
2. 核心算法架构解析
2.1 系统控制框图
整个控制系统采用分层架构设计:
- 底层硬件层:包括STM32F407 MCU、MPU6050姿态传感器、AS5048A编码器、无刷电机驱动电路等
- 驱动层:提供硬件抽象接口,如PWM输出、编码器读取、传感器数据采集
- 算法层:包含姿态解算、PID控制、故障诊断等核心算法
- 应用层:实现平衡控制、速度控制、转向控制等具体功能
2.2 控制策略设计
系统采用串级PID控制结构:
- 外环:角度环,维持车身直立
- 内环:角速度环,抑制车身晃动
- 速度环:实现定速行驶
- 转向环:通过差速控制实现转向
这种结构相比单级PID具有更好的抗干扰能力和动态响应特性。在实际调试中发现,串级PID的参数整定虽然复杂一些,但最终控制效果明显优于单级方案。
3. 硬件接口与驱动实现
3.1 传感器接口配置
MPU6050作为核心姿态传感器,通过I2C接口与MCU通信。在硬件设计时需要注意:
- I2C总线需加上拉电阻(通常4.7kΩ)
- MPU6050的VCC引脚建议增加0.1μF去耦电容
- 传感器安装位置应尽量靠近车辆重心
c复制// MPU6050初始化代码示例
void MPU6050_Init(void) {
// 配置采样率1kHz,陀螺仪量程±2000°/s,加速度计量程±8g
I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_SMPLRT_DIV, 0x07);
I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_GYRO_CONFIG, 0x18);
I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_ACCEL_CONFIG, 0x10);
// 启用所有轴
I2C_WriteByte(MPU6050_ADDR, MPU6050_RA_PWR_MGMT_1, 0x01);
}
3.2 无刷电机驱动实现
无刷电机采用6步换相控制,关键点包括:
- 换相时机检测:通过编码器获取转子位置
- PWM频率选择:20kHz可避免可闻噪声
- 死区时间设置:通常1-2μs防止上下管直通
c复制// 6步换相表
const uint8_t commutation_table[6][3] = {
{1, 0, 0}, // A+
{1, 1, 0}, // A+ B+
{0, 1, 0}, // B+
{0, 1, 1}, // B+ C+
{0, 0, 1}, // C+
{1, 0, 1} // A+ C+
};
void BLDC_Driver_Commutate(uint8_t motor_id, uint16_t angle) {
uint8_t sector = angle / 682; // 4096/6=682
if(motor_id == 1) {
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, commutation_table[sector][0]);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, commutation_table[sector][1]);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, commutation_table[sector][2]);
}
}
4. 软件算法实现细节
4.1 卡尔曼滤波姿态解算
相比互补滤波,卡尔曼滤波在动态性能和抗干扰能力方面表现更优。实现时需要注意:
- 过程噪声Q和测量噪声R需要根据实际传感器特性调整
- 协方差矩阵P初始值影响收敛速度
- 计算周期必须固定,不能使用非定时查询方式
c复制void Attitude_Solve_Kalman(void) {
// 预测步
Car_State.Pitch_Angle += DT * (gyro_rate - gyro_err);
P[0][0] += DT * (DT*P[1][1] - P[0][1] - P[1][0] + Q_angle);
// 更新步
angle_err = accel_angle - Car_State.Pitch_Angle;
K[0] = P[0][0] / (P[0][0] + R_angle);
Car_State.Pitch_Angle += K[0] * angle_err;
// 更新协方差
P[0][0] -= K[0] * P[0][0];
}
4.2 PID控制器实现
工业级PID实现需要考虑:
- 积分抗饱和:限制积分项积累
- 输出限幅:防止执行器饱和
- 微分滤波:抑制高频噪声
c复制float PID_Calc(PID_TypeDef *pid, float set, float actual) {
pid->Err = set - actual;
// 抗饱和积分
pid->Integral += pid->Err * DT;
pid->Integral = constrain(pid->Integral, pid->Integral_Min, pid->Integral_Max);
// PID计算
pid->Output = pid->Kp * pid->Err + pid->Ki * pid->Integral
+ pid->Kd * (pid->Err - pid->Err_Last) / DT;
// 输出限幅
pid->Output = constrain(pid->Output, pid->Output_Min, pid->Output_Max);
pid->Err_Last = pid->Err;
return pid->Output;
}
5. 系统集成与调试
5.1 控制周期管理
使用定时器中断确保控制周期精确:
c复制void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if(htim->Instance == TIM6) { // 200Hz定时器
Balance_Steer_Control();
static uint8_t cnt = 0;
if(++cnt >= 20) { // 每100ms上报一次状态
State_Report();
cnt = 0;
}
}
}
5.2 PID参数整定步骤
- 先调角度环P,使车体能够勉强站立
- 加入角速度环D,抑制振荡
- 调速度环P,实现速度控制
- 最后调转向环参数
调试中发现,角度环P值过大容易导致系统振荡,过小则响应太慢。经验值是先从小值开始,逐步增加直到出现轻微振荡,然后回退20%。
6. 工程优化与故障处理
6.1 常见问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 车体持续向一侧倾斜 | 加速度计未校准 | 执行传感器校准程序 |
| 站立时高频振荡 | 角速度环D值过大 | 减小GYRO_D参数 |
| 电机转动不顺畅 | 换相时序错误 | 检查编码器安装位置 |
| 突然停止工作 | 电池电压过低 | 检查电源系统 |
6.2 工程优化建议
- 增加参数在线调整功能,避免反复烧录
- 实现SD卡数据记录,便于分析问题
- 添加OLED显示屏,实时显示状态信息
- 升级到FOC控制,提高电机效率
7. 硬件选型与适配
7.1 关键器件选型建议
- MCU:STM32F407VGT6,168MHz主频,带FPU,满足计算需求
- 姿态传感器:MPU6050(低成本)或MPU9250(带磁力计)
- 电机编码器:AS5048A(14位分辨率)或TLE5012B
- 电机驱动:DRV8301(集成电流检测)或IR2104+MOSFET方案
7.2 电源设计要点
- 主电源:3S锂电池(11.1V),需加保护电路
- MCU供电:通过LDO稳压到3.3V
- 电机驱动:直接使用电池电压
- 电流检测:0.1Ω采样电阻+运放放大
在实际项目中,电源噪声是常见问题,建议在电机驱动电源端增加大容量电解电容(如470μF)和小容量陶瓷电容(如0.1μF)并联。
8. 扩展功能实现
8.1 无线遥控功能
通过蓝牙模块(如HC-05)实现手机遥控:
c复制void Bluetooth_Control(void) {
if(Bluetooth_Available()) {
char cmd = Bluetooth_Read();
switch(cmd) {
case 'F': Car_State.Speed_Cmd = 50; break; // 前进
case 'B': Car_State.Speed_Cmd = -50; break; // 后退
case 'L': Car_State.Steer_Cmd = -30; break; // 左转
case 'R': Car_State.Steer_Cmd = 30; break; // 右转
case 'S': Car_State.Speed_Cmd = 0; break; // 停止
}
}
}
8.2 状态监测与保护
完善的故障检测机制:
c复制void Fault_Diagnosis(void) {
// 倾角超限检测
if(fabs(Car_State.Pitch_Angle) > MAX_TILT_ANGLE) {
Enter_Fault_Mode(FAULT_OVER_TILT);
return;
}
// 低电压检测
if(Car_State.Battery_Voltage < LOW_VOLTAGE) {
Enter_Fault_Mode(FAULT_LOW_VOLTAGE);
}
}
9. 性能测试与优化
9.1 实时性测试
使用GPIO翻转法测量各任务执行时间:
- 姿态解算:约0.3ms
- PID计算:约0.15ms
- 电机控制:约0.1ms
总执行时间约0.55ms,远小于5ms的控制周期,留有充足余量。
9.2 控制性能指标
经过优化后系统达到:
- 平衡角度误差:±1°
- 速度控制精度:±0.1m/s
- 转向响应时间:<0.5s
- 最大倾斜恢复角度:30°
10. 项目总结与展望
这个平衡车项目完整实现了从算法设计到工程落地的全过程,几个关键创新点包括:
- 采用串级PID结构,提升控制性能
- 实现无刷电机精确控制,延长续航
- 完善的故障诊断机制,提高可靠性
在实际调试中,最大的挑战是PID参数整定,需要反复测试才能找到最佳值。一个技巧是先用Ziegler-Nichols方法初步确定参数范围,再精细调整。
未来可改进方向:
- 升级到FOC控制,提高能效
- 增加路径规划功能
- 实现基于视觉的自主导航
- 添加跌倒自动恢复机制
