news 2026/4/25 9:42:05

基于STM32直流电机的PID调节+程序对比,可应用于倒立摆,平衡车等等

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM32直流电机的PID调节+程序对比,可应用于倒立摆,平衡车等等

文章末尾会有参数和波形对比。

“生活化比喻 + 你的电机实际场景”给你讲透,全程不绕专业术语,每个概念都对应你的程序和测试数据,保证你能听懂、会用!

一、先搞懂:PID 到底是干嘛的?

你可以把 PID 想象成一个“智能司机”,电机是 “汽车”,目标转速(比如 100 RPM)是 “目的地”:

  • 司机的任务:让汽车精准、稳定地到达目的地(电机转速精准跟踪目标);
  • PID 的三个参数(Kp、Ki、Kd)就是司机的三个 “技能”:大力士(Kp)、坚持者(Ki)、刹车手(Kd);
  • 你的程序里,PID 根据 “目标转速 - 实际转速 = 误差”,用这三个技能计算出 “PWM 值”(给电机的 “油门大小”),让电机转速逼近目标。

二、逐个拆透 PID 核心参数(Kp、Ki、Kd)

每个参数都讲:是什么→调节什么→你的电机里怎么体现→调大 / 调小的效果→你之前为什么这么调

1. 比例系数 Kp(大力士:负责 “快速发力”)
  • 通俗理解:Kp 是司机的 “力气”,误差越大(离目的地越远),力气用得越大(油门踩得越深)。
  • 核心作用:快速缩小 “目标转速和实际转速的误差”,是 PID 的 “主力”。
  • 在你的电机里的体现
    • 比如目标 100 RPM,实际 0 RPM,误差 = 100;
    • Kp=1.5 时,比例项输出 = 100×1.5=150;
    • 这个 150 叠加到 4000 死区偏置上,PWM=4000+150=4150(刚过死区,电机准备启动)。
  • 调大 / 调小的效果
    Kp 调大Kp 调小
    优点:误差缩小快,电机启动快、响应灵敏优点:转速稳定,不容易震荡(忽快忽慢)
    缺点:容易 “冲过头”(比如目标 100,实际冲到 110),然后来回震荡;还会让积分项快速饱和(你之前 Kp=5.0 时就是这情况)缺点:误差缩小慢,电机启动慢,可能离目标转速有差距(比如目标 100,实际只到 95)
  • 你之前为什么把 Kp 从 5.0 降到 1.5?
    • 原来 Kp=5.0:力气太大,误差 100 时比例项 = 500,叠加后 PWM=4500,但积分项跟着 “猛冲”,很快顶到 2000 的限幅(i_out=200),导致 PWM 卡住不动(4400);
    • 现在 Kp=1.5:力气适中,比例项 = 150,积分项有时间慢慢累积(i_out 从 0 涨到 400),PWM 稳步增长到 4550,电机顺利启动,还不震荡。
2. 积分系数 Ki(坚持者:负责 “彻底达标”)
  • 通俗理解:Ki 是司机的 “耐心”,就算误差很小(快到目的地了),也会一直轻轻踩油门,直到完全到达(误差 = 0),绝不留 “尾巴”。
  • 核心作用:消除 “静差”(比如目标 100,实际稳定在 98,差 2 RPM,这就是静差),是 PID 的 “补刀手”。
  • 在你的电机里的体现
    • 比如目标 100 RPM,实际 98 RPM,误差 = 2;
    • Ki=0.2 时,积分项会累积误差:每次误差 2,累积 5 次就是 10,积分项输出 = 10×0.2=2;
    • 叠加后 PWM 增加 2,实际转速涨到 100,误差 = 0。
  • 调大 / 调小的效果
    Ki 调大Ki 调小
    优点:静差消除快,转速精准度高;积分项累积快,能快速突破死区限制优点:转速稳定,不容易因为积分过量导致震荡
    缺点:积分项容易 “饱和”(累积太多,导致 PWM 一直很大,转速冲过头);启动时可能震荡缺点:静差消除慢,可能一直有小误差(比如目标 100,实际 99);积分项累积慢,突破死区慢
  • 你之前为什么把 Ki 从 0.1 涨到 0.2?
    • 原来 Ki=0.1:耐心不够,积分项累积慢,误差 100 时,累积 10 次才 1000,积分项输出 = 100,叠加后 PWM=4100,刚过死区,转速上不去;
    • 现在 Ki=0.2:耐心足够,积分项累积快,误差 100 时,累积 5 次就 1000,积分项输出 = 200,叠加后 PWM=4200,转速快速逼近 100 RPM,还能消除静差(最后误差 = 0)。
3. 微分系数 Kd(刹车手:负责 “稳定车身”)
  • 通俗理解:Kd 是司机的 “预判能力”,能提前判断 “转速变化趋势”,比如转速涨得太快,就提前踩刹车(减小 PWM),避免冲过头。
  • 核心作用:抑制转速震荡(忽快忽慢),让转速更平稳,是 PID 的 “稳定器”。
  • 在你的电机里的体现
    • 比如实际转速从 88 涨到 102,变化量 = 14,Kd=0.5 时,微分项输出 = 14×0.5=7;
    • 这个 7 会 “抵消” 一部分比例 + 积分的输出,PWM 从 4550 降到 4394,避免转速继续涨到 110。
  • 调大 / 调小的效果
    Kd 调大Kd 调小
    优点:震荡抑制强,转速特别稳;能快速刹车,避免冲过头优点:对转速变化不敏感,启动时转速上升快
    缺点:转速响应变慢(刹车太狠,明明没到目标,却不让踩油门);容易受噪音影响(比如编码器计数波动,会误判为转速变化)缺点:震荡抑制弱,转速可能忽快忽慢;冲过头的概率大
  • 你之前为什么把 Kd 从 2.0 降到 0.5?
    • 原来 Kd=2.0:刹车太狠,误差 100 时,微分项输出 = 200,直接抵消了比例 + 积分的输出,PWM 一直卡在 4400,转速上不去;
    • 现在 Kd=0.5:刹车力度适中,既不会让转速冲过头,又不影响 PWM 增长,最后转速稳定在 100 RPM,误差 = 0。

三、死区(你的电机 “启动门槛”)

1. 什么是死区?
  • 通俗理解:你的电机是 “懒虫”,必须给足够大的油门(PWM≥4000)才肯动,低于 4000 的 PWM 都是 “无效指令”,这就是死区。
  • 硬件原因:电机内部有线圈电阻、摩擦力,驱动板输出的电压必须超过一定值,才能克服这些阻力,让电机转动。
  • 你的电机死区:4000 PWM(低于这个值,电机完全不转)。
2. 死区对 PID 的影响(为什么必须保留 4000 偏置?)
  • 如果没有 4000 偏置:PID 计算出的 PWM 可能是 1000、2000(低于 4000),电机不转,误差一直存在,PID 会一直增大输出,但永远达不到死区,最后 PWM 顶到 7200,电机突然猛转(失控);
  • 你的程序处理方式:在do_pid_left里加了 4000 偏置(output = output + 4000),让 PID 的 “有效输出” 从 4000 开始,直接跳过死区,电机能正常响应。
3. 死区的关键注意点(你之前踩过的坑)
  • 死区偏置必须和最小 PWM 匹配:你主函数里把最小 PWM 调到 4000,就是为了避免 PID 输出 4000 以下的无效值;
  • 死区会压缩 PID 调节空间:你的 PWM 最大 7200,死区 4000,所以 PID 的 “有效调节范围” 是 4000~7200(只有 3200 的空间),这就是为什么要调大积分限幅(让 PID 能在这个空间里充分调节)。

四、积分限幅(防止 PID “冲过头” 的 “安全阀”)

1. 什么是积分饱和?(你之前的核心问题)
  • 通俗理解:积分项是 “坚持者”,但如果太坚持,就算误差已经很小,还在累积,导致 PWM 一直增大,转速冲过头,之后又要往回调,这就是 “积分饱和”。
  • 你的电机里的体现:原来积分限幅 2000,Ki=0.1,积分项最大输出 = 2000×0.1=200,叠加 4000 偏置后,PWM=4200,刚过死区,转速上到 100 就卡住了(积分项顶到上限,没法再增大 PWM);
  • 后果:误差一直存在(比如目标 150,实际 107),但 PID 没法再调节,转速永远达不到目标。
2. 积分限幅的作用?
  • 给积分项 “设上限”,让它累积到一定程度就停止,避免 PWM 过大导致转速失控;
  • 同时要保证上限足够大,能让 PID 在死区调节空间里充分调节(4000~7200)。
3. 你之前为什么把积分限幅从 2000 调到 8000?
  • 原来限幅 2000:积分项最大输出 200,PWM 最大 4200,不够支撑 100 RPM 以上的转速;
  • 现在限幅 8000:积分项最大输出 = 8000×0.2=1600,叠加 4000 偏置后,PWM 最大 = 4000+1600=5600,足够支撑 150 RPM 的目标(你测试时 PWM 到 4550 就已经让转速到 100 了);
  • 注意:限幅不能太大(比如 10000 以上),否则积分项会过量,导致转速震荡。

五、微分先行(进阶知识,按需使用)

1. 什么是微分先行?
  • 普通 PID:对 “误差”(目标 - 实际)做微分(Kd×(当前误差 - 上一次误差));
  • 微分先行:对 “实际转速” 做微分(Kd×(当前实际转速 - 上一次实际转速)),不对目标转速做微分;
  • 通俗理解:普通 PID 会因为 “目标转速突然变化”(比如从 100 调到 150)导致微分项突变,PWM 突然增大,电机猛冲;微分先行能过滤掉目标变化的影响,只关注转速本身的变化,更稳定。
2. 什么时候用微分先行?
  • 适合 “目标转速频繁变化” 的场景(比如机器人避障时需要快速加减速);
  • 你的场景(目标转速固定,比如 100、150):不需要用,普通 PID 足够稳定,用了反而会让响应变慢。
3. 你的程序里需要改吗?
  • 不需要!你现在的场景是 “稳定跟踪固定目标转速”,普通 PID + 合适的 Kd 已经能抑制震荡,微分先行反而没必要。

六、总结:参数调节口诀(你以后自己调参用)

  1. 先调 Kp(大力士)
    • 从 1.0 开始,慢慢增大,直到电机能快速接近目标转速,且不明显震荡;
    • 如果震荡,就减小 Kp(比如你从 5.0 降到 1.5)。
  2. 再调 Ki(坚持者)
    • Kp 调好后,如果转速稳定但有静差(比如目标 100,实际 98),慢慢增大 Ki;
    • 直到静差消除,且不震荡(比如你从 0.1 升到 0.2)。
  3. 最后调 Kd(刹车手)
    • 如果转速震荡(忽快忽慢),慢慢增大 Kd;
    • 直到转速稳定,且不影响响应速度(比如你从 2.0 降到 0.5)。
  4. 死区和积分限幅配套调
    • 死区偏置 = 电机最小启动 PWM(你的 4000);
    • 积分限幅 =(最大 PWM - 死区偏置)/Ki(你的(7200-4000)/0.2=16000,取 8000 留余量)。
// ============ PID参数设置 ============ // 直接在这里设置PID参数,调整后重新下载即可 // 根据您的电机:PWM 3000以上才能达到500RPM // 初始参数:Kp=5.0, Ki=00.1, Kd=2.0 ph2_timer_dev->set_pid_left_kp(1.5); // 比例系数 ph2_timer_dev->set_pid_left_ki(0.2); // 积分系数 ph2_timer_dev->set_pid_left_kd(0.5); // 微分系数 // ============ 控制模式选择 ============ // 0: 开环测试模式(原来的正反转测试) // 1: PID闭环控制模式(速度环控制) static uint8_t control_mode = 1; // 默认使用PID闭环控制 static int16_t target_speed = 100; // 目标速度300RPM
int16_t do_pid_left(int16_t error) { TMX_PID* pid = &(_ph2_timer_dev.pid_left); static int debug_count = 0; debug_count++; if(debug_count % 20 == 0) { printf("PID调试: error=%d, kp=%.2f, ki=%.2f, kd=%.2f\r\n", error, pid->kp, pid->ki, pid->kd); printf("PID计算: p_out=%.2f, i_out=%.2f, d_out=%.2f, sum=%.2f\r\n", pid->kp * error, pid->ki * pid->error_sum, pid->kd * (error - pid->error_last), pid->kp * error + pid->ki * pid->error_sum + pid->kd * (error - pid->error_last)); } // 位置式PID算法 float output; // 比例项 float p_out = pid->kp * error; // 积分项(带积分限幅) pid->error_sum += error; // 积分限幅防止积分饱和 if(pid->error_sum > 2000) pid->error_sum = 2000; if(pid->error_sum < -2000) pid->error_sum = -2000; float i_out = pid->ki * pid->error_sum; // 微分项 float d_error = error - pid->error_last; float d_out = pid->kd * d_error; // PID输出叠加到基准PWM上 // PID总和 output = p_out + i_out + d_out; // ============ 关键修改:根据开环测试添加偏置 ============ // ============ 关键:加上最小启动偏置 ============ // 根据您的测试:4000-5000PWM才能启动 // 我们加一个基础偏置,让PID输出从4000开始 if(output >= 0) { output = output + 4000; // 正转:加4000偏置 } else { output = output - 4000; // 反转:减4000偏置 } // 输出限幅 if(output > 7200) output = 7200; if(output < -7200) output = -7200; pid->error_last = error; return (int16_t)output; }

这是我的程序

这是我的实验参数

以及上位机波形对比

最后再回顾你的测试数据,验证理解:

  • 目标 100 RPM,初始实际 0 RPM,误差 100;
  • Kp=1.5→比例项 150,Ki=0.2→积分项慢慢累积到 400,叠加 4000 偏置→PWM=4550;
  • 电机启动,实际转速涨到 88→误差 12,比例项 18,积分项继续累积;
  • 最后实际转速 100→误差 0,比例项 0,积分项 380→PWM=4380,稳定运行;
  • 整个过程没有震荡,没有静差,完美匹配 PID 的调节逻辑!

以后再调目标转速(比如 150 RPM),按上面的口诀微调即可:比如 Kp 调到 1.8,Ki 保持 0.2,积分限幅保持 8000,大概率能稳定到 150 RPM~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 19:21:31

零基础入门:10分钟用EasyPlayer做第一个视频网站

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个极简的HTML5视频播放页面&#xff0c;集成EasyPlayer基础功能。只需要最基本的HTML和CSS代码&#xff0c;包含清晰的注释说明每个部分的作用。提供一键复制粘贴即可运行的完…

作者头像 李华
网站建设 2026/4/22 22:00:48

日本成功开发1.4nm纳米“光刻机”

来源&#xff1a;EETOP日本印刷株式会社&#xff08;DNP&#xff09;近日宣布&#xff0c;成功开发出电路线宽为10纳米的NIL纳米压印技术&#xff0c;可用于相当于1.4纳米等级的逻辑半导体电路图形化。 公司表示&#xff0c;该产品针对智能手机、数据中心、NAND Flash等应用场景…

作者头像 李华
网站建设 2026/4/22 3:23:29

AI如何简化Supervisord配置与管理?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个AI辅助工具&#xff0c;能够根据用户输入的进程需求&#xff08;如Python脚本、Node.js服务等&#xff09;&#xff0c;自动生成最优的Supervisord配置文件。要求包含进程名…

作者头像 李华
网站建设 2026/4/18 3:52:12

密码锁小白必看:忘记密码怎么办?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个面向新手的密码锁知识科普应用&#xff0c;包含&#xff1a;1. 密码锁类型介绍&#xff1b;2. 密码设置和记忆技巧&#xff1b;3. 忘记密码的基础解决方案&#xff1b;4. 预…

作者头像 李华
网站建设 2026/4/18 12:01:39

2、深入了解 OpenStack 网络:功能、架构与实践

深入了解 OpenStack 网络:功能、架构与实践 1. OpenStack 网络简介 在当今的数据中心中,网络包含的设备数量比以往任何时候都多。曾经占据大量数据中心空间的服务器、交换机、路由器、存储系统和安全设备,现在都以虚拟机和虚拟网络设备的形式存在。这些设备给传统的网络管…

作者头像 李华
网站建设 2026/4/23 8:17:51

torch.where在图像处理中的5个实战案例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 生成一个图像处理项目&#xff0c;使用torch.where实现&#xff1a;1) 图像阈值分割 2) 两张图像的像素级混合 3) 基于条件的图像区域替换 4) 数据增强中的随机遮挡 5) 异常像素检测…

作者头像 李华