【问题标题】:Converting circuits to C将电路转换为 C
【发布时间】:2012-11-04 11:22:44
【问题描述】:

有人知道如何将前馈运算放大器 PID 循环转换为 C 代码吗?我正在尝试进行这样的转换,老实说,不知道从哪里开始。我可以通过 ADC 获得所有输入值、电压、电流等,但编码前馈 PID 对我来说有点新鲜。有什么想法吗?

【问题讨论】:

  • 您确定“PID”是您问题的正确标签吗?它当前的描述完全是关于“进程 ID”。也许你的问题可以更详细一点。
  • 此上下文中的 PID 可能是 proportional-integral-differential controller。运算放大器是operational amplifier。所以,正如标题所暗示的,这个问题在某种程度上与如何用 C 语言编写一个带有前馈环路的运算放大器的模拟有关。自从我上次想到这些术语以来,我已经有足够长的时间了。关于如何解决问题的线索。
  • @JonathanLeffler 我的第一个想法是简单地创建一个对函数、其导数和积分求和的函数......这不是一个解决方案吗?
  • @H2CO3:通过——我需要比近 30 年来想的更努力地思考运算放大器的特性,并且我们需要知道前馈回路的特性是连接的,并且……通常,我们需要的信息比我们拥有的要多得多。然后会有如何编码的问题。有用于电路仿真的完整语言,尽管它们可能更常用于微芯片工作,而不是我将其描述为“宏芯片”(或分立设备而不是芯片)。
  • 我认为这首先在“s域电路分析”中进行了描述,然后结果可以用例如离散化。双线性变换到 z 域。从那时起,c 算法就很容易了。 PID 中的 P 表示将输入放大系数 K。D 表示从输入流中获取连续样本,将它们与权重 b1、b2、b3 相乘(例如最后取 3 个样本),I 表示反馈循环,其中一个添加到结果 N电路的最后结果再次具有一些权重 a1,a2,a3。

标签: c simulator control-theory


【解决方案1】:

您正在谈论用软件替换非线性控制系统的硬件。我认为您唯一的希望是编写硬件模拟。

我对 PID 一无所知,但通过 Google 快速搜索发现:

http://www.cds.caltech.edu/~murray/books/AM05/pdf/am06-pid_16Sep06.pdf

它具有描述理想 PID 控制系统的方程式和图表。您可以从编写实现这些方程式的代码开始。

我稍微考虑了一下您的问题后,在我看来这可能是一个常见问题。我在 Google 上搜索了“离散 PID 控制器仿真”,找到了 Simulink、Matlab 和 Python 的答案,以及更多参考书籍。

您可能想从 Python 秘诀开始。 Python 比 C 更容易和更快,如果你使用 SciPy,你可以绘制你的结果并确保你得到你想要的数字。一旦你让它在 Python 中工作,然后如果需要移植到 C。

http://code.activestate.com/recipes/577231-discrete-pid-controller/

【讨论】:

  • 谢谢!我会调查一下。我正在对电压波进行采样,因此我的输入来自 ADC,我必须模拟运算放大器 PID,并且我需要使用 te utput 来控制设备。不过,我肯定会检查出来的。谢谢!!!
  • 我真的很感激纯软件的人确实提出来解决电子/电气问题:) 用于分析的模拟和在现实世界中使用的模拟有一定的局限性。在将代码编译到嵌入式系统时,一大问题是语言的选择。我认为这个问题应该在一些嵌入式论坛而不是在这里提出。
【解决方案2】:

电路

看起来你想用 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 in 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.

我强烈建议您使用this source 的电路进行学习。

尽管设置起来有点乏味,但从数学上来说分析起来要简单得多,因为您可以直接将其与标准数学形式而不是理想形式联系起来。

最后,Vout 用于控制电机或任何需要控制的东西。而Vin是过程变量电压。

在 C(海?)中弄湿你的脚之前

我假设您正在从某种模数转换器读取信号。如果不是,那么您将不得不将信号模拟为输入。

如果我们使用标准格式,

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

PIDoutput = 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 秒。

现在前馈系统的输出是,

FeedForwardOutput = Kf * Vin;

在哪里 Kf = 前馈系统的比例常数。

因此,我们使用 PID 控制器的前馈系统的总输出将是,

Output = FeedForwardOutput + PIDoutput;

查看link 以进一步了解带有 PID 控制器的前馈系统。

用 C 绘图

我发现this 用 C 语言编写了出色的 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 >>> 单循环的代码执行时间(远大于 )。在这种情况下,我们可以取消计时器并使用延迟功能。

【讨论】:

  • 哇!!大量信息!谢谢!!首先,我通过 TI 320F28335 DSP 处理器中内置的 12 位 ADC 读取电平。你画的电路的ansi版本是我必须转换成代码的。不幸的是,我没有时间或零件来建造和研究另一个,否则,我会全力以赴!!!另外-为了澄清,我的采样频率是 40kHz,所以每 25us。
  • 另外,我的电路上没有 Rf... 那么是什么决定了常数 Kp、Ki 和 Kd? Kf 是从哪里来的?这些常数可以自动随电压变化还是固定不变直到改变?这东西有点令人困惑..但你的解释有点亮,谢谢!!
  • 我从来没有在那个处理器上工作过,但我怀疑它能给你一个比 1ms 更好的循环执行时间,忘记 25us。也许我们可以尝试使用 double 而不是 float 并优化代码。我强烈建议您尝试使用 100Hz 的采样率。关于其他问题,我会修改答案。
  • 在我编辑之前,我想知道一些事情你确定你是在设计混合前馈 PID 控制器还是只是 PID 控制器(在反馈模式下工作)?如果它只是 PID 控制器,那么我们不需要 FeedForwardOutput,因此方程中没有 Kf。其次,必须有一个 Rf,如果它不在电路上,它可能是 Vin 的源电阻。没有 Rf 意味着无限增益并且输出会饱和,请确认。 (顺便说一句,第二张图更容易分析,ASCII 艺术相当复杂,数学上)。
  • TI 芯片是一个运行频率为 150MHz 的 32 位浮点处理器。所以澄清一下,我不是在设计,它已经由其他人完成了。我正在将其转换为 C 代码,电路就像上面绘制的 ASCII 艺术版本。但是,我想知道如何对它们进行编码,但是现在,如果时间紧迫,我只需要 PID 控制器。此时不需要前馈。我确实找到了 Rf,很抱歉没有早点看,它实际上在原理图的另一页上。再次感谢您的帮助,他们不会在学校教这个......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多