Arduino PID整定

news2024/11/25 2:18:16

Arduino PID整定

Tuning an Arduino PID


Introduction to Tuning an Arduino PID

例如,我们可能想把一箱水加热到华氏 100 度。 我们需要能够在不同的条件下实现这一目标,例如房间的环境(周围)温度。 此外,我们可能会不时将冷水放入水箱,或将热水取出。 我们需要控制器作出反应,使温度尽快恢复到设定点,并保持在设定点。 我们不希望出现波动。 一个简单的温度开关就可以做到这一点。 请记住,我们的目标是提供足够的输出,将温度保持在我们想要的位置。 在本文,我们将以加热过程为例。 这将是一个使用独立(传统)PID 公式的前向作用过程。) 我们将使用启发式方法进行调整,对于大多数使用 Arduino 的人来说,这通常是最简单的方法。

PID Terminology

At this point, let’s discuss the different terms you need to be familiar with when tuning a PID loop.现在,让我们来讨论一下在调整 PID 循环时需要熟悉的不同术语。

General Termiology

Process Varialble (Input) — This is the feedback we get from the system. This could be temperature or pressure, etc, depending on the process. The feedback can provide anywhere from 0 to 5 volts to an analog input pin. We just need to know the scaling. For example: 0v might represent a temperature of 50 degrees. Likewise, 5v might represent a temperature of 150 degrees. In this example, our input will be A0 (Analog Input 0). In the Arduino, a 0v signal will give us a 0 on the analog input channel. 5v will give us a value of 1023. In other words, with this setup, a value of 0 to 1023 represents the value of 50 to 150 degrees.

Control Variable (Output) — This is the output that the Arduino sends from a PWM pin. If you need a true analog output, you will need to set up a low pass filter with a capacitor and resistor. Basically, if you convert the pin to true analog output, then the Arduino will send a value of 0 to the output to get 0v through the low pass filter. A value of 255 would give you 5v out of the low pass filter.

过程变量(输入)–这是我们从系统中获得的反馈。这可能是温度或压力等,具体取决于过程。反馈可为模拟输入引脚提供 0 至 5 伏的电压。我们只需要知道比例。例如:0 伏可能代表 50 度的温度。同样,5 伏可能代表 150 度的温度。在这个例子中,我们的输入将是 A0(模拟输入 0)。在 Arduino 中,0V 信号将在模拟输入通道上显示 0。5v 信号将产生 1023 的值。换句话说,在这种设置下,0 至 1023 的值代表 50 至 150 度。 控制变量(输出) - 这是 Arduino 从 PWM 引脚发送的输出。如果需要真正的模拟输出,则需要用电容器和电阻器设置一个低通滤波器。基本上,如果您将引脚转换为真正的模拟输出,那么 Arduino 将向输出发送一个 0 值,以便通过低通滤波器获得 0 伏电压。如果数值为 255,则低通滤波器的输出电压为 5V。

SetPoint — This is the value we desire the process variable (input) to be.

Error — This is the difference between the SetPoint and the Process Variable (Input). In other words, this is the difference between where we are, and where we want to be.设定点 - 我们希望过程变量(输入)达到的值。 误差 - 设定点与过程变量(输入)之间的差值。 换句话说,这就是我们所处的位置与我们希望达到的位置之间的差值。

P, I, and D Terminology

Proportional

We base the output from proportional solely on the amount of error (and our gain). The higher our gain is, the more output we will have for a given error. If we are at the set point, then there is no error. Therefore, there is no output. In a non-integrating process, this means that your process variable will drop. The process variable will continue to drop until there is enough error to provide enough output to make up for your losses.我们的比例输出完全基于误差量(和我们的增益)。 增益越高,给定误差下的输出就越大。 如果我们处于设定点,则没有误差。 因此,也就没有输出。 在非积分过程中,这意味着过程变量将下降。 过程变量将继续下降,直到有足够的误差来提供足够的输出以弥补损失。

Integral

We calculate integral based on time and error. Let’s say, we set the Ki tuning parameter to 0.1 repeats per second. For the time being, let’s also assume that we have 10% error. To understand this easier, let’s also say that the process variable is not changing. Our error remains at 10% for now regardless of the output.

Since we have 0.1 repeats per second, after 10 seconds, we will have 1 full repeat. Remember, our error remained at 10. In other words after 10 seconds, we will add 10% to the output. If we assume we started with Kp=1, then the output from proportional is 10% also. Basically, this means that after 10 seconds, our output would increase to 20%. After 20 Seconds, our output would be 30%, and so on. If our setting was .05 repeats per second, then we make the integral less aggressive. After 20 seconds, we would only have 1 full repeat, which means it takes 20 seconds to get to a total of 30% output (counting proportional).

我们根据时间和误差计算积分。 比方说,我们将 Ki 调整参数设置为每秒重复 0.1 次。 同时,假设误差为 10%。 为了更容易理解,我们也假设过程变量没有变化。 由于每秒重复 0.1 次,10 秒后我们将有 1 次完整的重复。 请记住,我们的误差仍然是 10。 换句话说,10 秒后,我们的输出将增加 10%。 如果我们假设开始时 Kp=1,那么比例输出也是 10%。 基本上,这意味着 10 秒后,我们的输出将增加到 20%。 20 秒后,我们的输出将达到 30%,以此类推。 如果我们的设置是每秒重复 0.05 次,那么积分的强度就会降低。 20 秒后,我们将只有 1 次完整的重复,这意味着需要 20 秒才能达到总输出的 30%(按比例计算)。

Derivative

Finally, we have derivative. We base derivative on the rate of change of error. However, since most input values are a bit noisy, we don’t use derivative most of the time. This would cause excessive control action. The derivative setting is how far we look into the future to expect the error to be for a given slope. You can think of derivative as opposition to a change in the process variable. Keep in mind though, this opposition is in both directions. Derivative tries to prevent the process variable from falling so much, but also resists the process variable coming back up to the set point.

最后是导数。 我们的导数基于误差变化率。 不过,由于大多数输入值都有一定的噪声,我们在大多数情况下都不使用导数。 这会导致过度的控制动作。 导数设置是指在给定斜率的情况下,我们对未来误差的预期。 您可以将导数视为过程变量变化的对立面。 但请记住,这种对立是双向的。 导数试图阻止过程变量大幅下降,但同时也阻止过程变量回升到设定点。

Begin Tuning an Arduino PID

At this point, let’s take a look at a simple sketch that I put into the Arduino. Attached to the Arduino, I have a PID simulator that I put together with another Arduino build.现在,让我们来看看我在 Arduino 中安装的一个简单草图。 我在 Arduino 上安装了一个 PID 模拟器,这是我用另一个 Arduino 制作的。

/********************************************************
 * PID Basic Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_v1.h>

#define PIN_INPUT 0
#define PIN_OUTPUT 3

long CurrentMillis = 0;
long LastMillis = 0;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp = 5, Ki = 0, Kd = 0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup() {
  //initialize the variables we're linked to
  Input = analogRead(PIN_INPUT);
  Setpoint = 400;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  Serial.begin(9600);
}

void loop() {
  CurrentMillis = millis();
  Input = analogRead(PIN_INPUT);
  myPID.Compute();
  analogWrite(PIN_OUTPUT, Output);

  // Serial Plotter Data
  if ((CurrentMillis - LastMillis) > 500){
      Serial.print("Input:");
      Serial.print(Input);
      Serial.print(",");
      Serial.print("Output:");
      Serial.println(Output);
      Serial.print(",");
      Serial.print("MinValue:");
      Serial.print(0);
      Serial.print(",");
      Serial.print("MaxValue:");
      Serial.print(600);
      Serial.print(",");
      LastMillis = CurrentMillis;
    }
}

As you can see, Kp is 5, and I’ve set the other values at 0 for Ki and Kd temporarily.

Tuning the Arduino PID for Proportional

First, we need to find out the minimum value of Kp causes instability. The loop is unstable when it continues to oscillate. Let’s look at this on the serial plotter.首先,我们需要找出导致不稳定的 Kp 最小值。 当环路持续振荡时,它就是不稳定的。 让我们在串行绘图仪上看看这个问题。

img

As you can see, the loop is unstable, and the output is saturating at 255, which is the max value. Let’s reduce Kp to 2.正如您所看到的,环路不稳定,输出在最大值 255 时达到饱和。 让我们将 Kp 降为 2。

img
That helped, but we’re still unstable, and saturating again at times. Let’s try 1.这有所帮助,但我们仍然不稳定,有时会再次饱和。 让我们试试 1.
img

We’re fairly stable at 1, so let’s try 1.5:

img

As you can see, we went into constant oscillation. You can narrow this down further if you like, but we’ll run with this value. The definition of instability is when the process variable continues to oscillate with the same amplitude, or gets worse.

At this point, we need to write down the amount of time peak to peak, or trough to trough. It looks like this will be about 10 seconds.Additionally, since Kp is unstable at 1.5, we need to cut this in half. Our new Kp will be .75. Let’s see what our chart looks like with this new Kp.

如您所见,我们进入了持续振荡状态。 如果您愿意,还可以进一步缩小范围,但我们将使用这个值。 不稳定性的定义是过程变量以相同的振幅持续振荡,或振幅越来越大。 此时,我们需要写下峰值到峰值或谷值到谷值的时间。 此外,由于 Kp 在 1.5 时不稳定,我们需要将其减半。 新的 Kp 将是 0.75。 让我们看看使用新 Kp 后的图表效果。

img

Tuning an Arduino PID for Integral

Now that we found the value for Kp, the Integral is easy. For Ki, we’ll just take Kp divided by the natural period. This will be 0.75 / 10 seconds. Let’s try a Ki with 0.075, and let’s see if we get up to the setpoint.

Remember, our Set Point was 400.现在我们找到了 Kp 的值,积分就很容易了。 对于 Ki,我们只需用 Kp 除以自然周期。 这将是 0.75 / 10 秒。 记住,我们的设定点是 400。

img

Looks like we landed it!

Tuning an Arduino PID for Derivative

Now that we are confident, let’s see what will happen if we add derivative. To calculate derivative, we’ll take Kp * (1/8th of the natural period). In this case, that will be 0.75 * 1.25. Therefore, let’s try a Kd of 0.938.现在我们有信心了,让我们看看如果加上导数会发生什么。 计算导数时,我们取 Kp *(自然周期的 1/8)。 在这种情况下,就是 0.75 * 1.25。 因此,让我们试试 0.938 的 Kd 值。
img

As you can see, we did achieve the set point, and it appears to be stable. However, we do see a lot more control action, although small. If this was a valve, you would be performing more maintenance on the valve due to the constant control action. One solution is to dampen the PV by using an average. However, by doing this, you also simulate more process lag, and cannot tune your loop quite as tight.如您所见,我们确实达到了设定点,而且似乎很稳定。 不过,我们确实看到了更多的控制动作,尽管很小。 如果这是一个阀门,由于持续的控制动作,您需要对阀门进行更多的维护。 一种解决方案是使用平均值来抑制 PV。 不过,这样做也会模拟出更多的过程滞后,无法将环路调整得非常紧凑。

Summary

In short, increase Kp until your loop becomes unstable. At that point, record the natural period. Cut Kp in half, then use Kp / natural period for your Ki variable. If you use derivative, it will be Kp * (1/8th of the natural period). Please provide your feedback and corrections below. I’m sure there are some details of this post that need refined! There are other tuning methods out there using different procedures. You can just do a google search to find them, and choose whichever method works best for you!

For more information, visit the intermediate Arduino Page!

简而言之,增大 Kp 直到回路变得不稳定。此时,记录自然周期。将 Kp 减半,然后使用 Kp / 自然周期作为 Ki 变量。如果使用导数,则为 Kp *(自然周期的 1/8)。请在下面提供反馈和更正。我相信这篇文章中还有一些细节需要改进!还有其他使用不同程序的调谐方法。您只需在谷歌上搜索即可找到,然后选择最适合您的方法!如欲了解更多信息,请访问 Arduino 中级页面! - Ricky Bryce

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1926222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CoreIDRAW标注尺寸箭头怎么修改 CoreIDRAW标注尺寸数字怎么修改

*CorelDraw&#xff1a;数字创意的无限可能** 在数字艺术与设计领域&#xff0c;CorelDraw无疑是一款备受推崇的图形设计软件。它不仅为设计师、艺术家和创意工作者提供了强大的工具集&#xff0c;还以其直观易用的界面和卓越的性能赢得了广泛的赞誉。本文将深入探讨CorelDraw…

【Playwright+Python】系列之元素定位

一、常见元素定位 定位器是 Playwright 自动等待和重试能力的核心部分。简而言之&#xff0c;定位器代表了一种随时在页面上查找元素的方法&#xff0c;以下是常用的内置定位器。 1、按角色定位 按显式和隐式可访问性属性进行定位语法&#xff1a;page.get_by_role&#xff0…

力扣经典题目之->删除有序数组中的重复项讲解 的讲解与实现

一&#xff1a;题目 二&#xff1a;思路讲解 第一步&#xff1a;创建两个下标&#xff0c;一个是第一个元素的&#xff08;start0&#xff09;&#xff0c;一个是第二个元素的&#xff08;end1&#xff09; 第二步&#xff1a; a&#xff1a;end移动&#xff0c;直到遇到不等…

Dify中Jieba类的create()方法实现过程

本文主要介绍Dify中Jieba类的create()方法执行过程&#xff0c;重点是段&#xff08;segment&#xff09;的关键词的生成。 一.create方法流程概述 整个create方法的目的是为了处理一批文本&#xff0c;提取它们的关键词&#xff0c;并更新关键词表&#xff0c;以便于后续的关…

Spark 实现自定义加密

文章目录 Spark 实现自定义加密一、建立加密和解密的自定义函数二、在 Spark 环境下导入对象实现的方法&#xff0c;并在 SparkSession 中注册 UDF 函数三、在SparkSQL中调用函数 Spark 实现自定义加密 一、建立加密和解密的自定义函数 import java.nio.charset.{StandardCha…

STM32+三色LED智能调光系统源程序 易安卓APP 原理图

资料下载地址&#xff1a;STM32三色LED智能调光系统源程序 易安卓APP 原理图 三色LED手机智能调光系统概述&#xff1a; 利用开发的智能手机软件&#xff0c;对照明三色LED进行智能调光。包含的功能有&#xff0c;支持多手机同时连接服务端&#xff0c;互动调光。支持关…

【数据结构】顺序表的应用

目录 一.引言 二.顺序表概念 三.顺序表的实现 1.定义顺序表 2.顺序表初始化 ​编辑 3.检查空间&#xff0c;如果满了&#xff0c;进行增容 4.顺序表尾插 5.顺序表尾删 6.顺序表头插 7.顺序表头删 ​编辑 8.顺序表查找 9.顺序表在pos位置插入x 10.顺序表删…

深入探讨:CPU问题的深度分析与调优

引言 你是否曾经遇到过这样的情况:系统运行突然变慢,用户抱怨不断,检查后发现CPU使用率居高不下?这时候,你会如何解决?本文将详细解析CPU问题的分析与调优方法,帮助你在面对类似问题时游刃有余。 案例分析:一次CPU性能瓶颈的解决过程 某知名互联网公司在一次促销活动…

Dubbo基础知识

1、什么是 Dubbo &#xff1f; Dubbo是基于Java的高性能轻量级的RPC分布式服务框架&#xff0c;致力于提供透明化的RPC远程服务调用方案&#xff0c;以及SOA服务治理方案。现已成为Apache 基金会孵化项目。 2、为什么要使用Dubbo? 背景: 随着互联网的快速发展&#xff0c;Web应…

JAVA毕业设计147—基于Java+Springboot的手机维修管理系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的手机维修管理系统(源代码数据库)147 一、系统介绍 本项目分为用户、管理员、维修员三种角色 1、用户&#xff1a; 注册、登录、新闻公告、售后申请、申请列…

使用Samba或NFS实现文件共享

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、SAMBA文件共享服务 1987年&#xff0c;微软公司和英特尔公司共同定制了SMB&#xff08;Server Messages Block&#xff09;服务器消息块协议&am…

板级调试小助手(2)ZYNQ自定义IP核构建属于自己的DDS外设

一、前言 在上期文章中讲述了小助手的系统结构和原理。在PYNQ的框架开发中&#xff0c;我们一般可以将PL端当做PS端的一个外设&#xff0c;通过读写寄存器的方式来操作外设的功能&#xff0c;就类似于在开发ARM和DSP中操作外设一样&#xff0c;不同时的是&#xff0c;我们可以通…

关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划

之前&#xff1a;antdv 现在&#xff1a;g2plot https://g2plot.antv.antgroup.com/manual/introduction 录课内容&#xff1a;快速入门 图表示例&#xff1a; 选择使用比较广泛的示例类型&#xff0c;录课顺序如下&#xff1a; 1、折线图2、面积图3、柱形图4、条形图5、饼…

[Qt] Qt Creator中,新建QT文件时选择界面模版下的各选项

在Qt Creator中&#xff0c;新建文件时选择界面模版下的各选项具有特定的意义&#xff0c;这些选项主要帮助开发者根据项目需求快速生成不同类型的文件。以下是对这些选项的详细解释&#xff1a; 0. Qt Item Model 意义&#xff1a;列表模型是Qt中用于表示和操作数据的强大抽…

Ubuntu下载安装chrome浏览器

方法一&#xff1a;wget下载并安装 1、创建文件夹存安装包 cd /root/Downloads mkdir chrome 2、下载安装包到文件夹内 wget -c https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -P /root/Downloads/chrome 3、安装 cd chrome sudo dpkg -i go…

从0开始的STM32HAL库学习5

旋转编码计数器 修改中断代码 void EXTI0_IRQHandler(void) {/* USER CODE BEGIN EXTI0_IRQn 0 */if(__HAL_GPIO_EXTI_GET_FLAG(PB0_Pin)){if(HAL_GPIO_ReadPin(PB1_GPIO_Port, PB1_Pin)GPIO_PIN_RESET){count--;}/* USER CODE END EXTI0_IRQn 0 */HAL_GPIO_EXTI_IRQHandler…

【论文极速读】 可微分检索索引(Differential Search Index, DSI)

【论文极速读】 可微分检索索引&#xff08;Differential Search Index&#xff0c; DSI&#xff09; FesianXu 20240714 at WeChat Search Team 前言 最近从朋友处得知了DSI这个概念&#xff0c;所谓的可微分检索索引DSI&#xff0c;就是通过语言模型将检索过程中的索引和召回…

virtualbox的ubuntu默认ipv4地址为10.0.2.15的修改以及xshell和xftp的连接

virtualbox安装Ubuntu后&#xff0c;默认的地址为10.0.2.15 我们查看virtualbox的设置发现是NAT 学过计算机网络的应该了解NAT技术&#xff0c;为了安全以及缓解ip使用&#xff0c;我们留了部分私有ip地址。 私有IP地址网段如下&#xff1a; A类&#xff1a;1个A类网段&…

持续学习的综述: 理论、方法与应用(三:泛化分析)

前文连接&#xff1a;持续学习的综述: 理论、方法与应用&#xff08;一&#xff09; 前文连接&#xff1a;持续学习的综述: 理论、方法与应用&#xff08;二&#xff1a;理论基础&#xff09; 泛化分析 目前持续学习的理论研究主要是在增量任务的训练集上进行的&#xff0c;假…

Java面试题:MVCC

MVCC 保证事务的隔离性 排它锁: 一个事务获取了数据行的排他锁,其他事务就不能再获取该行的其他锁 MVCC: 多版本并发控制 维护一个数据的多个版本,使读写不存在冲突 具体实现依靠 隐藏字段 mysql中隐藏了三个隐藏字段 db_trx_id:最近修改事务 db_roll_ptr:指向上一个…