1.从洗澡调水温到工业控制:PID算法原理与嵌入式实现

发布时间:2026/9/30 7:09:41

1.从洗澡调水温到工业控制:PID算法原理与嵌入式实现
一、PID的核心思想三个字母控制世界PID是Proportional比例、Integral积分、Derivative微分的缩写三个部分各司其职配合起来实现精准控制P比例像“现在就调”误差越大调整幅度越大I积分像“持续调”把历史误差累加起来消除稳态偏差D微分像“提前调”根据误差变化趋势提前刹车防止超调我们用洗澡调水温的例子一步步拆解1. P比例控制——误差越大调得越多冷水开太大水温偏冷你会说“冷了多少就开大多少热水”这就是比例控制。误差乘以系数Kp就是输出简单直接但有个致命缺陷永远到不了目标温度总会差那么一点。2. I积分控制——消除最后的偏差你等了很久水温还是偏冷烦了就说“既然一直偏冷我就再开大一点热水”多次累加误差产生累积量这就是积分控制。误差乘以系数Ki随时间不断累积逼着系统消除那点偏差。3. D微分控制——提前刹车防超调积分上来之后水温升得太快马上就超过目标你会提前收小热水。变化的快慢叫微分变化越快D项越大提前踩刹车。误差的斜率乘以Kd用来抑制超调和震荡。4. 三者配合P主力、I纠偏、D阻尼三个部分配合起来就是完整的PID输出u Kp×e Ki×∫e dt Kd×de/dtP说现在有误差快调I说误差存在太久了继续调D说变化太快了慢点调二、嵌入式C语言PID实现可直接运行的代码下面是一套基于STM32 HAL库的完整PID实现包含结构体封装、初始化、计算和限幅功能可直接用于电机转速、温度、位置控制等场景。1. 头文件定义pid.h#ifndef __PID_H #define __PID_H #include stm32f1xx_hal.h // PID控制器结构体 typedef struct { // 核心参数 float Kp; // 比例系数 float Ki; // 积分系数 float Kd; // 微分系数 float Ts; // 采样周期单位s // 限幅参数 float max_integral; // 积分上限 float min_integral; // 积分下限 float max_output; // 输出上限 float min_output; // 输出下限 // 状态变量 float integral; // 积分累加值 float prev_error; // 上一次误差 float output; // 当前输出 } PID_HandleTypeDef; // 函数声明 void PID_Init(PID_HandleTypeDef *pid, float Kp, float Ki, float Kd, float Ts, float max_integral, float min_integral, float max_output, float min_output); float PID_Calc(PID_HandleTypeDef *pid, float setpoint, float feedback); void PID_Reset(PID_HandleTypeDef *pid); #endif2. 实现文件pid.c积分抗饱和Anti-windup与输出限幅Output Clamping的必要性在实际PID控制中积分项会持续累加误差当系统输出达到物理极限如电机最大转速、阀门全开而误差仍然存在时积分项会继续累积导致积分饱和。这会使系统恢复时产生严重的超调和震荡。积分抗饱和通过限制积分项的累积范围来防止这种现象。输出限幅则是将PID总输出限制在物理执行器的有效范围内防止过冲损坏设备或系统不稳定。#include pid.h #include /** brief PID控制器初始化 param pid: PID控制器指针 param Kp: 比例系数 param Ki: 积分系数 param Kd: 微分系数 param Ts: 采样周期s param max_integral: 积分上限 param min_integral: 积分下限 param max_output: 输出上限 param min_output: 输出下限 retval 无 */ void PID_Init(PID_HandleTypeDef *pid, float Kp, float Ki, float Kd, float Ts, float max_integral, float min_integral, float max_output, float min_output) { pid-Kp Kp; pid-Ki Ki; pid-Kd Kd; pid-Ts Ts; pid-max_integral max_integral; pid-min_integral min_integral; pid-max_output max_output; pid-min_output min_output; pid-integral 0.0f; // 初始化积分累加值为0 pid-prev_error 0.0f; // 初始化上一次误差为0 pid-output 0.0f; // 初始化输出为0 } /** brief PID计算函数 param pid: PID控制器指针 param setpoint: 目标设定值 param feedback: 实际反馈值 retval PID输出值 */ float PID_Calc(PID_HandleTypeDef *pid, float setpoint, float feedback) { // 1. 计算当前误差目标值减去实际值 float error setpoint - feedback; // 2. 比例项当前误差乘以比例系数Kp float P_out pid-Kp * error; // 3. 积分项带抗饱和限幅 // 积分累加将当前误差乘以采样周期加到积分器中 pid-integral error * pid-Ts; // 积分抗饱和限幅防止积分项无限累积导致饱和 if (pid-integral pid-max_integral) { pid-integral pid-max_integral; // 超过上限则钳位到上限 } else if (pid-integral pid-min_integral) { pid-integral pid-min_integral; // 低于下限则钳位到下限 } float I_out pid-Ki * pid-integral; // 积分项输出 Ki × 积分累加值 // 4. 微分项计算误差变化率抑制超调 float derivative (error - pid-prev_error) / pid-Ts; // 误差变化率 (当前误差 - 上次误差) / 采样周期 float D_out pid-Kd * derivative; // 微分项输出 Kd × 误差变化率 // 5. 总输出比例项 积分项 微分项 pid-output P_out I_out D_out; // 6. 输出限幅将总输出限制在执行器有效范围内 if (pid-output pid-max_output) { pid-output pid-max_output; // 超过输出上限则钳位到上限 } else if (pid-output pid-min_output) { pid-output pid-min_output; // 低于输出下限则钳位到下限 } // 更新上一次误差用于下一次微分计算 pid-prev_error error; return pid-output; // 返回经过限幅的PID输出值 } /** brief 重置PID控制器状态 param pid: PID控制器指针 retval 无 */ void PID_Reset(PID_HandleTypeDef *pid) { pid-integral 0.0f; // 清零积分累加值 pid-prev_error 0.0f; // 清零上一次误差 pid-output 0.0f; // 清零输出值 }3. 使用示例电机转速控制#include pid.h // 定义PID控制器实例 PID_HandleTypeDef speed_pid; // 电机转速控制初始化 void MotorSpeed_Init(void) { // 初始化PID参数Kp2.0, Ki0.1, Kd0.5, 采样周期10ms PID_Init(speed_pid, 2.0f, 0.1f, 0.5f, 0.01f, 100.0f, -100.0f, // 积分限幅 1000.0f, 0.0f); // 输出限幅PWM占空比0~1000 } // 电机转速控制循环在定时器中断中调用10ms一次 void MotorSpeed_Control_Loop(void) { float target_speed 1000.0f; // 目标转速1000RPM float actual_speed Get_Encoder_Speed(); // 读取编码器实际转速 // 计算PID输出 float pwm_output PID_Calc(speed_pid, target_speed, actual_speed); // 设置PWM占空比 Set_PWM_Duty(pwm_output); }三、PID的应用场景三个字母控制世界PID算法诞生于1911年至今仍是控制领域的王者几乎无处不在无人机悬停姿态PID控制热水器恒温温度PID控制汽车定速巡航速度PID控制3D打印机位置PID控制工业机器人关节位置PID控制下期我们将深入讲解纯比例控制P的能做和不能做的事以及PID参数整定的实用技巧。代码说明该实现采用位置式PID适合大多数嵌入式控制场景包含积分抗饱和和输出限幅功能防止积分饱和和输出过冲采样周期Ts需要根据实际控制频率设置例如10ms中断则Ts0.01参数整定是PID应用的关键需要根据具体系统进行调试

相关新闻

终极指南:如何让Adobe Flash在2021年后继续运行 - FlashPatch完整教程

终极指南:如何让Adobe Flash在2021年后继续运行 - FlashPatch完整教程

2026/9/29 5:40:25

终极指南:如何让Adobe Flash在2021年后继续运行 - FlashPatch完整教程 【免费下载链接】FlashPatch FlashPatch! Play Adobe Flash Player games in the browser after January 12th, 2021. 项目地址: https://gitcode.com/gh_mirrors/fl/FlashPatch FlashPa…

12个实用技巧:彻底解决磁盘空间不足问题的完整文件管理指南

12个实用技巧:彻底解决磁盘空间不足问题的完整文件管理指南

2026/9/28 20:50:51

12个实用技巧:彻底解决磁盘空间不足问题的完整文件管理指南 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 你是否经常面对磁盘空间不足…

如何调试Bluetooth-jammer-esp32:串口监控与故障排除指南

如何调试Bluetooth-jammer-esp32:串口监控与故障排除指南

2026/9/29 5:53:48

如何调试Bluetooth-jammer-esp32:串口监控与故障排除指南 【免费下载链接】Bluetooth-jammer-esp32 Bluetooth jamming esp32 with nrf24l01 项目地址: https://gitcode.com/gh_mirrors/bl/Bluetooth-jammer-esp32 调试Bluetooth-jammer-esp32设备是确保蓝牙…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/29 22:00:59

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/28 16:01:49

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/28 2:15:29

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/29 19:20:49

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/28 3:58:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/28 3:47:14

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/28 16:01:48

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/28 5:05:21

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/28 16:01:48

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…