当前位置: 首页 > news >正文

程序代码篇---PID简介

P:比例

含义:输出量的大小与输入误差信号大小成比例关系的一种(类似一元一次函数)控制

结果:将输出量稳定在目标值附近

弊端:存在残差(仅仅使用比例控制无法将残差消除到零)

简单介绍:

P调节也可以叫做偏差调节,通过与目标之间的偏差控制大小

注意实际应用中需要乘以比例参数KP,原因:实际应用中输入和输出的单位有时差很多

I:积分

含义:输出量的大小与输入误差信号的积分值成比例关系的一种控制

结果:消除残差

简单介绍:

I调节也可以叫做累计偏差调节,一直达不到目标(由于部分原因导致系统存在影响目标结果的输出,及可能存在静态偏差),这个时候考虑利用偏差,及将所有偏差累积起来乘以比例系数KI,注意比例系数尽量取小(正因为小,所有偏差累加起来就会变大,但不至于过大),消除静态误差

D:微分

含义:输出量的大小与输入误差信号的微分值成比例关系的一种控制
结果:在系统稳定后,如果存在干扰信号,使系统在最短的时间内回到稳定状态。

简单介绍:

D调节也可以叫做近期偏差调节。

---

相比PID的闭环控制,还存在没有反馈(一股脑向着目标冲击)的开环控制。

PID的衍生:串级PID、前馈PID

---

无PID控制:

#include <OneWire.h>
#include <DallasTemperature.h>// 定义温度传感器和加热器控制引脚
#define ONE_WIRE_BUS 4    // DS18B20温度传感器连接的GPIO引脚
#define HEATER_PIN 5      // 加热器控制引脚(连接继电器模块)// 温度控制参数
#define TARGET_TEMP 33.0  // 目标温度: 33摄氏度
#define HYSTERESIS 0.5    // 滞后值,防止继电器频繁切换// 初始化OneWire和DallasTemperature库
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);float currentTemp = 0.0;   // 当前温度
bool heaterState = false;  // 加热器状态void setup() {// 初始化串口通信Serial.begin(115200);// 初始化温度传感器sensors.begin();// 初始化加热器控制引脚pinMode(HEATER_PIN, OUTPUT);digitalWrite(HEATER_PIN, LOW);  // 初始关闭加热器Serial.println("温度控制系统启动中...");Serial.print("目标温度: ");Serial.print(TARGET_TEMP);Serial.println(" °C");
}void loop() {// 读取温度currentTemp = readTemperature();// 打印当前温度Serial.print("当前温度: ");Serial.print(currentTemp);Serial.println(" °C");// 温度控制逻辑temperatureControl();// 每2秒读取一次温度delay(2000);
}// 读取温度传感器数据
float readTemperature() {sensors.requestTemperatures();  // 发送温度转换命令return sensors.getTempCByIndex(0);  // 获取第一个传感器的温度(摄氏度)
}// 温度控制逻辑
void temperatureControl() {// 如果当前温度低于目标温度减去滞后值,打开加热器if (currentTemp < (TARGET_TEMP - HYSTERESIS) && !heaterState) {digitalWrite(HEATER_PIN, HIGH);heaterState = true;Serial.println("加热器已开启");}// 如果当前温度高于目标温度,关闭加热器else if (currentTemp > TARGET_TEMP && heaterState) {digitalWrite(HEATER_PIN, LOW);heaterState = false;Serial.println("加热器已关闭");}
}

代码说明:

  1. 硬件需求:

    • ESP32 开发板
    • DS18B20 温度传感器
    • 继电器模块(用于控制加热器)
    • 加热器设备
  2. 工作原理:

    • 使用 DS18B20 数字温度传感器采集温度数据
    • 通过继电器模块控制加热器的开关状态
    • 采用带滞后的开关控制策略,避免继电器频繁切换
  3. 控制逻辑:

    • 当温度低于 32.5°C(33°C - 0.5°C)时,开启加热器
    • 当温度达到或超过 33°C 时,关闭加热器
    • 0.5°C 的滞后值用于防止继电器在目标温度附近频繁开关
  4. 引脚定义:

    • DS18B20 连接到 GPIO4
    • 继电器模块连接到 GPIO5
    • 可根据实际接线情况修改引脚定义

使用时,确保已安装 OneWire 和 DallasTemperature 库,这两个库可以通过 Arduino 库管理器搜索安装。根据实际硬件连接情况,可能需要调整引脚定义。

有PID控制:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>// 定义引脚
#define ONE_WIRE_BUS 4    // DS18B20温度传感器连接的GPIO引脚
#define HEATER_PIN 5      // 加热器控制引脚(连接继电器)// 温度控制参数
#define TARGET_TEMP 33.0  // 目标温度: 33摄氏度
#define CONTROL_PERIOD 5000  // 控制周期(毫秒),例如5秒// 初始化传感器
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);// PID参数
double Setpoint, Input, Output;
// 根据实际系统调整这些参数
double Kp = 50.0, Ki = 0.2, Kd = 10.0;// 创建PID对象
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);float currentTemp = 0.0;
unsigned long periodStartTime = 0;
bool heaterState = false;
unsigned long heaterOnTime = 0;void setup() {Serial.begin(115200);// 初始化传感器sensors.begin();// 初始化加热器引脚pinMode(HEATER_PIN, OUTPUT);digitalWrite(HEATER_PIN, LOW);// PID初始化Setpoint = TARGET_TEMP;myPID.SetOutputLimits(0, 100);  // 输出限制在0-100%(占空比)myPID.SetMode(AUTOMATIC);periodStartTime = millis();Serial.println("开关型加热器PID温度控制系统启动");Serial.print("目标温度: ");Serial.print(TARGET_TEMP);Serial.println(" °C");Serial.print("控制周期: ");Serial.print(CONTROL_PERIOD/1000);Serial.println(" 秒");
}void loop() {unsigned long currentMillis = millis();// 读取温度(每1秒读取一次)static unsigned long lastReadTime = 0;if (currentMillis - lastReadTime >= 1000) {lastReadTime = currentMillis;currentTemp = readTemperature();Input = currentTemp;myPID.Compute();  // 计算PID输出}// 控制周期内的加热器控制unsigned long elapsedTime = currentMillis - periodStartTime;// 计算本周期内应该开启的时间(毫秒)heaterOnTime = (Output / 100.0) * CONTROL_PERIOD;// 控制逻辑if (elapsedTime < heaterOnTime && !heaterState) {// 需要开启加热器digitalWrite(HEATER_PIN, HIGH);heaterState = true;} else if (elapsedTime >= heaterOnTime && heaterState) {// 需要关闭加热器digitalWrite(HEATER_PIN, LOW);heaterState = false;}// 控制周期结束,重置计时if (elapsedTime >= CONTROL_PERIOD) {periodStartTime = currentMillis;printStatus();  // 打印本周期状态}
}// 读取温度传感器数据
float readTemperature() {sensors.requestTemperatures();return sensors.getTempCByIndex(0);
}// 打印状态信息
void printStatus() {Serial.print("当前温度: ");Serial.print(currentTemp);Serial.print(" °C, 目标: ");Serial.print(Setpoint);Serial.print(" °C, 输出占空比: ");Serial.print(Output);Serial.print("%, 加热时间: ");Serial.print(heaterOnTime/1000.0);Serial.println(" 秒");
}

代码说明:

  1. 工作原理:

    • 采用固定控制周期(例如 5 秒),在每个周期内根据 PID 计算的输出值决定加热器开启的时间比例
    • 例如,若 PID 输出为 60%,控制周期为 5 秒,则加热器在本周期内开启 3 秒,关闭 2 秒
    • 通过这种方式,实现了对加热功率的近似比例控制
  2. 参数调整建议:

    • CONTROL_PERIOD:控制周期,太短会导致继电器频繁动作,太长会导致控制精度下降,建议 5-10 秒
    • Kp:比例系数,初始可设为 50,根据响应调整
    • Ki:积分系数,初始可设为 0.1-0.5
    • Kd:微分系数,初始可设为 5-20
  3. 调试方法:

    • 先将系统加热到接近目标温度
    • 观察温度曲线,若震荡严重则减小 Kp
    • 若温度稳定后与目标有偏差则增大 Ki
    • 若响应太慢可适当增大 Kp 或减小 Kd

这种控制方式兼顾了开关型加热器的特性和 PID 控制的优势,既能避免继电器过于频繁地切换,又能实现比简单开关控制更精确的温度调节。

核心算法解析

  1. PID 控制公式
    代码中实现的核心公式是:

    输出 = Kp×误差 + Ki×∫误差dt - Kd×(输入变化率)
    

    其中用输入变化率代替了误差变化率,这是为了避免设定值突变时产生的微分冲击。

  2. 关键技术点

    • 积分限幅:防止积分项累积过大导致的 "积分饱和" 现象
    • 输出限幅:确保输出在执行器的有效范围内
    • 时间处理自动计算采样周期,适应不同调用频率
    • 方向控制:支持正作用和反作用控制,适应不同类型系统
  3. 使用流程

    • 创建 PID 对象并指定输入、输出、设定值指针
    • 设置 PID 参数 (Kp, Ki, Kd)
    • 设置输出范围和控制方向
    • 切换到自动模式
    • 定期调用 Compute () 方法进行计算

这个实现是工业界广泛使用的 PID 控制算法的标准实现,包含了所有必要的功能和保护机制,适用于温度控制、电机速度控制等多种场景。

http://www.dtcms.com/a/292464.html

相关文章:

  • 《计算机“十万个为什么”》之 MQ
  • 卷积神经网络:LeNet模型
  • STM32-GPIO理论部分1
  • 如何将iPad中的视频传输到电脑(6种简单方法)
  • 如何构建FunASR的本地语音识别服务
  • 出货奥地利,稳石氢能AEM氢户储应用方案撬动欧洲市场。
  • 智能文本抽取在法院卷宗管理的技术实现及优势
  • 记录解决问题--使用maven help插件一次性上传所有依赖到离线环境,spring-boot-starter-undertow离线环境缺少依赖
  • windows下nvm的安装及使用
  • 清华大学顶刊发表|破解无人机抓取与投递难题
  • 2025年COR SCI2区,基于多种配送模式的无人机自主配送车辆路径问题,深度解析+性能实测
  • 无人机吊舱与遥控器匹配技术解析
  • 【matlab】无人机控制算法开发与应用流程
  • 从差异到协同:OKR 与 KPI 的管理逻辑,Moka 让适配更简单
  • 进程优先级切换调度-进程概念(6)
  • Linux笔记1——简介安装
  • 高可用架构模式——数据集群和数据分区
  • Kafka监控体系搭建:基于Prometheus+JMX+Grafana的全方位性能观测方案
  • -----------------------------------事务--------------------------
  • 【SpringAI实战】实现仿DeepSeek页面对话机器人
  • 风能革新!5大理由选Canopen转Profinet网关
  • 基于python django深度学习的中文文本检测+识别,可以前端上传图片和后台管理图片
  • Oracle使用小计
  • VUE2 项目学习笔记 ? 语法 v-if/v-show
  • C# 11.0 新特性 u8 后缀
  • 【数学建模|Matlab】Matlab「基础知识」和「基础操作」
  • halcon处理灰度能量图
  • Android FFMPEG-播放器画面适配
  • 深入理解程序链接机制:静态链接、ELF加载与动态库实现原理
  • 三步构建智能办公体系