基于 STM32 的双轮自平衡小车——从原理到实践

一、项目整体介绍

双轮自平衡小车本质上是一个倒立摆系统
车身就像一根竖着的棍子,两侧的轮子不断调节转速,让车身维持在“快要倒、但没倒”的状态。

一个典型的 STM32 平衡小车系统通常包含:

  • 主控 MCU:STM32F103C8T6 / STM32F103RCT6 等

  • 姿态传感器:MPU6050(陀螺仪 + 加速度计)或其他 IMU

  • 驱动模块:L298N、TB6612 或带编码器的直流电机驱动板

  • 电机与编码器:12V/6V 直流减速电机 + 光电/霍尔编码器

  • 电源模块:锂电池 + 升降压模块 + 5V/3.3V 稳压

  • 通信与调试:蓝牙串口 / 无线串口 / 上位机(串口助手、MATLAB、QT 等)

  • 显示与按键(可选):OLED/LCD,参数显示与调参

二 、平衡小车的控制原理

平衡小车常用的几个关键物理量:

  • 角度 Angle(θ):相对于竖直方向的偏移角度,0° 为完全直立

  • 角速度 Gyro(ω):车身倾斜变化的速度

  • 车速 Speed(v):两个轮子的平均转速

  • 位移 Position(s):小车前后移动的距离

对应的控制目标:

  1. 保持直立:θ 尽量接近 0°

  2. 速度控制:让期望速度 v_target 与实际速度 v 接近

  3. 位置控制(可选):让车回到某个目标位置

因此,常见的控制结构是三环控制

三、硬件系统设计

3.1 姿态传感器:MPU6050

MPU6050 内部集成:

  • 三轴陀螺仪(Gyro):角速度

  • 三轴加速度计(Accel):加速度(静止时可估算重力方向 → 倾角)

接线常见方式:

  • MPU6050 → STM32:I2C 通信(SCL/SDA)

  • 电源:3.3V(注意供电电压与 IO 电平)

3.2 电机与驱动

  • 两个直流减速电机(带编码器)安装在小车两侧;

  • 通过 L298N/TB6612 等驱动芯片接到 STM32 的 PWM / GPIO 引脚;

  • 编码器接到 STM32 的外部中断 / 正交编码接口(TIMx_CH1/2)用于测速和记步。

注意事项:

  1. 电机电源与单片机电源注意分开供电或加足够滤波,避免干扰;

  2. 驱动芯片的电流、功率要匹配电机参数;

  3. 启停电流比较大,注意电池放电能力。

3.3 电源管理

  • 常见方案:12V锂电池 + 升降压模块;

  • 输出 12V(电机)、5V、3.3V(单片机与传感器);

  • 要有电压检测功能(ADC 采样),方便实现欠压保护与电量显示。

四、姿态解算(角度计算)

MPU6050 提供:

  • 陀螺仪:角速度(积分后得到角度,但会漂移)

  • 加速度计:可算出倾角(但对震动和加减速非常敏感)

常用方法:互补滤波

核心思想:

  • 低频成分信任加速度计(抗漂移)

  • 高频成分信任陀螺仪(抗噪声)

一个简单的互补滤波公式:


float angle;      
float K = 0.98f;  // 互补滤波系数,一般 0.95~0.99

void Update_Angle(float gyro, float accel_angle, float dt)
{
    float gyro_angle = angle + gyro * dt;  // 陀螺仪积分角度
    angle = K * gyro_angle + (1 - K) * accel_angle;
}

实际实现时的关键点:

  1. 陀螺仪和加速度计在上电后需要零偏校准

  2. 采样周期 dt 要尽量稳定(用定时器中断);

  3. 互补滤波系数 K 的选择会影响响应速度与稳定性,可以先 0.98 起步再微调。

如果想要更好的效果,可以使用卡尔曼滤波或开源的姿态解算库(如 Mahony/Madgwick),但对于简单的平衡小车,互补滤波已经够用。

五、PID 控制策略

5.1 常见三环结构

  1. 角度环(平衡环)PID

    • 输入:目标角度 θ_target(一般设为 0)与当前角度 θ 的误差

    • 输出:期望速度 v_expect(或者直接输出 PWM 分量)

  2. 速度环 PID

    • 输入:目标速度 v_target 与实际速度 v 的误差

    • 输出:对目标角度或角度环的偏置量(如让小车略微前倾以加速)

  3. 位置环 PID(可选)

    • 输入:目标位置与当前位移差

    • 输出:作为速度环的目标速度 v_target

在初学阶段,建议先实现:

  • 只做角度环:先让车能在原地站住

  • 然后增加速度环:实现前进/后退 + 静止保持

  • 最后再考虑位置环与转向控制。

typedef struct
{
    float Kp;
    float Ki;
    float Kd;
    float integral;
    float last_error;
} PID_t;

PID_t angle_pid = { .Kp = 50.0f, .Ki = 0.0f, .Kd = 1.0f, .integral = 0, .last_error = 0 };

float PID_Calc(PID_t *pid, float target, float measure)
{
    float error = target - measure;
    pid->integral += error;
    float derivative = error - pid->last_error;
    pid->last_error = error;

    float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
    return output;
}

六、调试与 PID 参数整定经验

6.1 调试顺序建议

  1. 先调角度解算

    • 把小车放在桌面上,读取角度值;

    • 手工轻轻前后倾斜,看看角度变化是否线性、方向是否正确;

    • 静止时角度是否基本稳定(抖动范围小于 ±1° 为佳)。

  2. 再调电机驱动

    • 单独写一个测试程序:给定 PWM 值,让左右轮正转/反转;

    • 检查轮子转向是否符合预期,是否有一边明顯比另一边快;

    • 确保编码器计数正常。

  3. 只开角度环

    • 速度环、位置环全部关闭;

    • 仅用角度 PID 输出电机 PWM;

    • 小车会在原地“抖着站立”,此时重点调 Kp、Kd;

    • Ki 一开始可以设为 0,避免积分导致发散。

  4. 加入速度环

    • 让车可缓慢前进后退,并在停止命令时能大致停住;

    • 速度环的输出不要太大,否则会干扰角度环。

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱嵌入式的乌鸦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值