c - 带直流电机/编码器的 PID 反馈和位置 Controller

标签 c embedded avr avr-gcc motordriver

我很难让 PID 反馈和定位同时运行。

我计算 RPM 的想法是:

  1. 启动计时器并使用中断对编码器脉冲进行计数。
  2. 使用一些简单的数学方法转换为 RPM。
  3. 重置使用的变量并重新开始。

我可以计算 RPM,但我只能在计算后调用我的 PID Controller (无论我想等待多长时间才能获得良好的分辨率。)这会导致代码非常困惑。是否有更简单的方法或我缺少的东西?

关于我的申请的信息: 我正在为带有直流电机/双磁编码器的 Atmel ATmega328P 编程,每转约 600 个脉冲(在齿轮箱之后)。我想调用 GoToTarget(#) 并让电机在更新 PID 参数时转到该位置。此外,它必须是双向的。

最佳答案

您的速度计算计时器和您的 PID 循环计时器应该是同一个东西 - 而不是分开的。

不要浪费时间和分辨率将脉冲计数转换为 RPM 速度;如果计时器是准确周期性的 - 并且它需要稳定的 PID - 那么脉冲计数直接成比例到速度,并且 PID 不关心单位 - 可以通过调整系数的值。如果您希望设定点速度采用实际单位,请将 那个 转换为等效的每 PID 周期脉冲数,而不是相反。

你的循环应该是这样的;

for(;;)
{
    WaitTimer() ;
    pulses = pulse_count - previous_pulse_count ;
    previous_pulse_count = pulse_count ;
    control = pid( pulses ) ;
    motor( control ) ;
}

然后您只需要一个中断来计算脉冲 - 它不需要执行任何计算,只需增加一个计数器 - 可能还有一个定时器中断,具体取决于 WaitTimer() 的实现以及它是否是多线程的。

另请注意,如果共享变量 pulse_count 不是原子变量,则需要在读取时禁用中断(最好包装在函数中),并且需要将其声明为 volatile

关于c - 带直流电机/编码器的 PID 反馈和位置 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17237173/

相关文章:

c - 如何在C中调试tcp套接字连接?

c - 在 C 中使用 printf_P 右对齐

c++ - 函数的隐式声明和类型冲突 - AVR

c - 在 C 中对 5 个数字的数组使用冒泡排序

c - VirtualDub 过滤器帧缓冲区 - 释放内存

c - 确定正则表达式是否只匹配固定长度的字符串

c - 使用 C 打开目录

linux - 无法让 tslib 与 FT5x06 一起工作

embedded - 8、16 和 32 位微 Controller 编程有什么区别?

c - AVR Butterfly UART - 无法接收数据