【问题标题】:PID feedback & Position Controller with DC motor/encoder带直流电机/编码器的 PID 反馈和位置控制器
【发布时间】:2013-06-21 13:58:17
【问题描述】:

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

我计算 RPM 的想法是:

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

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

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

【问题讨论】:

    标签: c embedded avr avr-gcc motordriver


    【解决方案1】:

    您的速度计算计时器和您的 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

    【讨论】:

    • +1 阅读您的答案总是很高兴。您的描述几乎是全面的
    • 我真的很感激。谢谢
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 2018-02-20
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    相关资源
    最近更新 更多