在C中编程PID循环


11

我是一名电气工程师,对数字世界充满了兴趣,并且在我学习的过程中不断学习。我正在对TI处理器进行编程以执行PID(比例-积分-微分)循环,如下图所示:

来自Wikipedia的PID回路图像

我还将描述它:

负反馈运算放大器,非反相端子接地。通过负极端子输入。反馈回路是一个与电阻并联的RE串联电路,所有与电容并联的串联电路。

有人知道如何将此电路转换为C代码吗?我对此不满意,可以使用帮助。


您可以链接到图片,然后有人会帮助您将该链接转换为实际图片。
Joachim Sauer

2
您自己发布的链接提供了用于处理此问题的基本伪代码。如果您不介意C#,这是C#中pid循环的示例
尼尔,

1
尼尔是对的。我几乎在TI的C语言中实现了该循环。一个提示:使用恒定时间循环,并将固定因子dt分解为常数,而不是在循环中进行额外的除法和乘法。
AShelly

1
@Neil是我在修订版2中添加的链接,因为我不知道什么是PID循环,而且我怀疑很多其他人也没有。

@MichaelT,嗯,我很抱歉。
尼尔,

Answers:


18

电路

好的,当我看到这个问题时,我刚刚在这里创建了一个帐户。无法编辑您的问题,以便我可以纠正您的错字。我相信您的意思是RC串联电路而不是RE并联(如果是的话,我不清楚这是什么意思)

似乎您要使用C模拟的模拟电路看起来像这样

                         Ci
                  |------| |--------------|
                  |           Rp          |
                  |----/\/\/\/\-----------|
                  |          Rd    Cd     |
           Rf     |----/\/\/\---| |-------|
Vin o----/\/\/\---|                       |
                  |    |\                 |
                  |    | \                |
                  |----|- \               | 
                       |   \              |
                       |    \-------------|---------o  Vout
                       |    /
                       |   /
                       |+ /
                   ----| /
                  |    |/
                  |
                  |
               ___|___ GND
                _____
                 ___
                  _

LEGEND:
  Vin is the input signal.
  Vout is the Output.
  Rp controls the propotional term ( P in PID) 
  Ci controls the Integral term ( I id PID)
  Rd and Cd controls the differential term ( D in PID)
  Rf is the gain control, which is common to all of the above controllers.

(我忍不住要画这个的冲动,因为我想告诉您电气/电子工程师过去是如何在论坛和电子邮件中交流而没有图片的……以及为什么我们只喜欢快递,固定宽度的字体)

我必须承认,在将系统的比例常数,积分常数和微分常数分别调节至所需值时,您所使用的电路易于设置,但数学上却非常复杂。

我强烈建议您使用此来源的电路进行研究。

尽管设置起来有些繁琐,但从数学上讲,它的分析要简单得多,因为您可以将其直接与标准数学形式(而不是理想形式)联系起来。

最后,Vout可以控制电动机或任何需要控制的东西。Vin是过程可变电压。

在用C弄湿脚之前(海上?)

我假设您正在读取某种模拟到数字转换器的信号。如果没有,那么您将必须模拟信号作为输入。

如果使用标准表格,

假设循环运行时间足够短(一个缓慢的过程),我们可以使用以下函数来计算输出,

output = Kp * err + (Ki * int * dt) + (Kd * der /dt);

哪里

Kp = Proptional Constant.
Ki = Integral Constant.
Kd = Derivative Constant.
err = Expected Output - Actual Output ie. error;
int  = int from previous loop + err; ( i.e. integral error )
der  = err - err from previous loop; ( i.e. differential error)
dt = execution time of loop.

最初的“ der”和“ int”为零。如果在代码中使用延迟功能将环路频率调整为1 KHz,则dt为0.001秒。

用C绘图

我在C语言中找到出色的PID PID代码,尽管它没有涵盖它的每个方面,但是它还是一个不错的代码。

//get value of setpoint from user
while(1){
  // reset Timer
  // write code to escape loop on receiving a keyboard interrupt.
  // read the value of Vin from ADC ( Analogue to digital converter).
  // Calculate the output using the formula discussed previously.
  // Apply the calculated outpout to DAC ( digital to analogue converter).
  // wait till the Timer reach 'dt' seconds.
}

如果处理速度较慢,则可以使用较低的频率,以使dt >>>代码的执行时间达到单循环(远大于)。在这种情况下,我们可以取消使用计时器,而使用延迟功能。


6
Ascii图使我震惊。+1
l46kok

1
链接“此源”不起作用
Ccr

噢,很遗憾听到这样的消息:(..我在共享的while循环示例代码中已经解释了这个概念。我对如何处理这种情况没有经验,也许有些编辑可以用正确的消息(
无效

2
缺少的“此源”可能在这里可用:educypedia.karadimov.info/library/piddocs.pdf
David Suarez,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.