Arrow Electronics Components Online

PID控制器基础和教程:Arduino中的PID实现

Arduino01 11月 2023
更智能、更安全的汽车互联解决方案
AuthorJeremy S Cook
查看所有文章

对于从事工业控制的人来说,比例、积分、微分(PID)理论可能是一个熟悉的概念。对大多数人来说,这个术语完全陌生,但您可能比想象中更熟悉它。当您在汽车中踩油门踏板时,您不仅考虑距离理想速度有多远——这是PID的比例部分——还考虑到您的车辆如何加速以及诸如坡道之类的条件。
 
对于从事工业控制的人来说,比例、积分、微分(PID)理论可能是一个熟悉的概念。对大多数人来说,这个术语完全陌生,但您可能比想象中更熟悉它。当您在汽车中踩油门踏板时,您不仅考虑距离理想速度有多远——这是PID的比例部分——还考虑到您的车辆如何加速以及诸如坡道之类的条件。
 
这些更为微妙的效果是I和D项在数学上考虑的。在这个示例中,它们会防止汽车的速度在上限和下限之间波动,并且我们可以将同样的概念应用于各种控制情况。虽然基于上限的控制可以大致到达目标区域,但您的系统会趋向于表现得有些不稳定。

PID方程

我们可以通过以下方程式用数学表达PID控制。P、I和D由这里相加的三个项表示。Kp、Ki和Kd是调整系统对每个因素反应的常数:

PID Equation

我们还可以分别将 Ki 和 Kd 替换为 1/Ti 和 Td。这种变化使方程与其物理意义有更好的关系,并使单位正确地转化为一个无单位的数值:

PID Equation Replacement

我们还可以变换方程以提取Kp值,并将其应用于整个方程,这就是标准形式。此形式的一个优点是可以一次调整整个方程的整体Kp常数:

PID Transpose

所有这些看起来可能有点吓人,甚至对于一个拥有工程学位的人来说也是如此。好消息是,你不必翻出你的动态系统的建模与分析教科书来理解这里的内容。而且,尽管了解微积分从来不会有坏处,但你甚至不必能做微积分。
 
分解第一个方程式,我们在方程左侧得到 u(t)——无单位的控制器输出——通过在等号右侧加入三个数学元素:P、I 和 D。每个元素前面都有一个常数 K 值(Kp、Ki 和 Kd),这表示每个元素作为u(t)形成时的权重,或特定时间的控制输出。我们可以单独调整每个 K 值以提高系统性能,我们将在下面进一步解释:
 
比例(P—Kp)
 
这个方程式中的第一个也是最重要的项是 e(t)。因此,它之前的 Kp 值通常大于方程式中的其他 K 值。在这里,e(t) 只是某个时间点的即时误差——受控设备的实际值减去期望值。将这个结果乘以 Kp ,即可得出其对整体控制器输出的贡献。
 
积分(I—KI)
 
这个方程式中的第二项与时间相关的综合误差有关。它是设备所经历的所有误差的总和:
每次控制器计算 u(t) 时,它都会将瞬时误差加到一个累积总和中。
 
然后这个数值乘以 Ki 并加入到 u(t) 中。
 
考虑一种情况,一种力将电机固定在原位,并阻止其在正常条件下返回设定点。随着其超出规格的时间越来越长,I 项将继续增加,最终克服这种力或达到电机能力的极限。
 
微分(D—Kd)
 
这个方程中的第三项与误差变化的速度有关:
 
理论上,如果你在这个方程中只有一个 D 项,并且你的过程持续保持错误的值,这项将保持为零,并不会对正确的输出做出贡献。另一方面,如果另外两个项之一试图让设备的输出过快地恢复到位,微分可以帮助缓解这一效果。
 
虽然基于微积分的这个概念表达可能很有用,但PID控制的现实情况要比最初看起来的神奇简单得多。从实际角度来看,我们只使用加法、减法和乘法来计算输出,考虑到误差以及读数之间的时间。事实上,我们使用气动系统来实现早期形式的PID控制,通过机械手段输入每个“项”。

  1. 控制器读取瞬时误差。
  2. 从中减去之前的瞬时读数。
  3. 将所得值乘以 Kd 来计算其对 u(t) 的贡献。

Arduino PID控制器教程

在许多情况下,将一个专用的 PID 控制器直接接入你的系统是比较方便的,但你也可以使用 Arduino 或类似的开发板自行实现。你甚至可以编写你自己的 PID 算法。在代码中,可以按照如下方式表示各个项:

  • P:instanteneousError = setpoint – input;
  • I:cumulativeError += error * elapsedTime;
  • D:rateOfError = (error – errorLastCalculation) / elapsedTime

要获得所需的输出,将每一项分别乘以对应的 K 值,然后将它们相加即可。另一方面,如果你不想重复造轮子,可以直接使用Brett Beuregard 的 PID 库。这个库会帮你处理底层细节,让你可以专注于根据需要调节 P、I 和 D 的常数值。

Arduino Nano

为了展示PID理论的实际应用,我从工具箱中拿出了一个Arduino Nano Every,以及:

  • 电机驱动板
  • 红外传感器
  • 从Hubsan H107C无人机拆下的电机
我为电机打印了一个面包板安装座,以及一个“风扇”,它在50%的时间内阻挡光线,以避免在旋转时遗漏脉冲。电机驱动器是输入到(否则不受控的)电机,而反馈是基于脉冲之间的时间。   当我最终 完成了代码 并获得了3D打印部件后,我能够以比使用恒定PWM(脉宽调制)输出操作电源按钮更复杂的方式控制电机。

PID Routine Code

值得注意的代码片段包括使用中断例程注册每个脉冲,因为阻塞设备旋转,并使用 millis() 计算脉冲之间的时间。我在代码的第一部分中,在函数外设置了 PID,如下:
 
PID myPID (&difference, &driverOut, &setPoint,Kp,Ki,Kd, DIRECT)
 
KpKiKd在代码中的这行之前定义,&difference 控制 &driverOut,其中 &setPoint 由串行监视器修改。我们可以操作这个数学运算,将时间差转换为 RPM,但因为这个特定的驱动器在输入被拉低时启动,PID 设置以 DIRECT 输出的形式工作。随着模拟输出升高(电机关闭),脉冲之间的延迟也会增加。

PID Routine OLD

PID例程的早期版本。注意CH1读取输入脉冲,而CH2则通过PID例程计算输出—低脉冲是电机的输入。
 
这个简单的PID控制器示例是由手头的部件驱动的(包括新的Arduino Nano Every)和一个我稍微熟悉的电机。但我能够展示如何在各种情况下应用PID控制,即使没有所有的事实。不论是电机控制、烤箱的温度控制,还是平衡机器人,只需一点点PID设置和调试,就能给你无限的实验选择。

文章标签

文章
全球
Arduino S.r.l.

相关新闻文章