是否有Arduino PID代码的说明?

时间:2016-12-08 22:59:10

标签: c++ arduino

我有使用Arduino MegaPi板的Makeblock Ultimate 2.0套件。有一个Arduino PID示例。但是,没有解释命令是什么以及数字是什么。是否有手册或教程?提前谢谢。

示例程序如下:

/**
 * \par Copyright (C), 2012-2016, MakeBlock
 * @file    Me_Megapi_encoder_pid_speed_MAM.ino
 * @author  MakeBlock
 * @version V1.0.0
 * @date    11/27/2016
 * @brief   Description: this file is sample code for Megapi encoder motor device.
 *
 * Function Call List:
 *    1. uint8_t MeEncoderOnBoard::getPortB(void);
 *    2. uint8_t MeEncoderOnBoard::getIntNum(void);
 *    3. void MeEncoderOnBoard::pulsePosPlus(void);
 *    4. void MeEncoderOnBoard::pulsePosMinus(void);
 *    5. void MeEncoderOnBoard::setMotorPwm(int pwm);
 *    6. double MeEncoderOnBoard::getCurrentSpeed(void);
 *    7. void MeEncoderOnBoard::setSpeedPid(float p,float i,float d);
 *    8. void MeEncoderOnBoard::setPosPid(float p,float i,float d);
 *    7. void MeEncoderOnBoard::setPosPid(float p,float i,float d);
 *    8. void MeEncoderOnBoard::setPulse(int16_t pulseValue);
 *    9. void MeEncoderOnBoard::setRatio(int16_t RatioValue);
 *    10. void MeEncoderOnBoard::runSpeed(float speed);
 *    11. void MeEncoderOnBoard::loop(void);
 *
 * \par History:
 * <pre>
 * <Author>     <Time>        <Version>      <Descr>
 * Mark Yan     2016/07/14    1.0.0          build the new
 * MAM          10/27/2016    1.0.0          Renamed Me_Megapi_encoder_pid_speed_MAM.ino
 * </pre>
 */
#include <MeMegaPi.h>
MeEncoderOnBoard Encoder_1(SLOT1);
MeEncoderOnBoard Encoder_2(SLOT2);
void isr_process_encoder1(void)
{
  if(digitalRead(Encoder_1.getPortB()) == 0)
  {
    Encoder_1.pulsePosMinus();
  }
  else
  {
    Encoder_1.pulsePosPlus();;
  }
}
void isr_process_encoder2(void)
{
  if(digitalRead(Encoder_2.getPortB()) == 0)
  {
    Encoder_2.pulsePosMinus();
  }
  else
  {
    Encoder_2.pulsePosPlus();
  }
}
void setup()
{
  attachInterrupt(Encoder_1.getIntNum(), isr_process_encoder1, RISING);
  attachInterrupt(Encoder_2.getIntNum(), isr_process_encoder2, RISING);
  Serial.begin(115200);

  //Set PWM 8KHz
  TCCR1A = _BV(WGM10);
  TCCR1B = _BV(CS11) | _BV(WGM12);
  TCCR2A = _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS21);
  Encoder_1.setPulse(7);
  Encoder_2.setPulse(7);
  Encoder_1.setRatio(26.9);
  Encoder_2.setRatio(26.9);
  Encoder_1.setPosPid(1.8,0,1.2);
  Encoder_2.setPosPid(1.8,0,1.2);
  Encoder_1.setSpeedPid(0.18,0,0);
  Encoder_2.setSpeedPid(0.18,0,0);
}
void loop()
{
  if(Serial.available())
  {
    char a = Serial.read();
    switch(a)
    {
      case '0':
      Encoder_1.runSpeed(0);
      Encoder_2.runSpeed(0);
      break;
      case '1':
      Encoder_1.runSpeed(100);
      Encoder_2.runSpeed(-100);
      break;
      case '2':
      Encoder_1.runSpeed(200);
      Encoder_2.runSpeed(-200);
      break;
      case '3':
      Encoder_1.runSpeed(255);
      Encoder_2.runSpeed(-255);
      break;
      case '4':
      Encoder_1.runSpeed(-100);
      Encoder_2.runSpeed(100);
      break;
      case '5':
      Encoder_1.runSpeed(-200);
      Encoder_2.runSpeed(200);
      break;
      case '6':
      Encoder_1.runSpeed(-255);
      Encoder_2.runSpeed(255);
      break;
      default:
      break;
    }
  }
  Encoder_1.loop();
  Encoder_2.loop();
  Serial.print(     "Speed 1:\t");
  Serial.print(Encoder_1.getCurrentSpeed());
  Serial.print("    \t Speed 2:\t");
  Serial.println(Encoder_2.getCurrentSpeed());
}

1 个答案:

答案 0 :(得分:3)

我试图快速搜索是否有任何在线内容可能是您错过了我找不到MeMegaPi库的源代码(https://github.com/Makeblock-official/Makeblock-Libraries/tree/master/makeblock/src

他们还会将您转回MegaBlocks网站以获取更多信息,我猜您已经这样做了。所以我将解释一下这里发生了什么,但是将来使用API​​会要求你阅读源代码,如果你不熟悉它可能有点令人生畏C / C ++。无论如何这里是:

MeEncoderOnBoard Encoder_1(SLOT1);
MeEncoderOnBoard Encoder_2(SLOT2);
void isr_process_encoder1(void)

首先,我们分别为MeEncoderOnBoard Encoder_1和MeEncoderOnBoard Encoder_2实现了对SLOT1和SLOT2的编码器实例化。 SLOT1和SLOT2是设备上连接1和连接2(/src/MePort.h)的别名(某种多针电缆,我猜)。这些编码器也会编码动作,我们很快就会看到。

void isr_process_encoder1(void)
{
  if(digitalRead(Encoder_1.getPortB()) == 0)
  {
    Encoder_1.pulsePosMinus();
  }
  else
  {
    Encoder_1.pulsePosPlus();;
  }
}
void isr_process_encoder2(void)
{
  if(digitalRead(Encoder_2.getPortB()) == 0)
  {
    Encoder_2.pulsePosMinus();
  }
  else
  {
    Encoder_2.pulsePosPlus();
  }
}

然后我们为这些编码器制作中断例程isr_process_encoder#s 1和2。对于两者,我们正在读取端口B(连接插槽上的引脚)并在它们称为脉冲位置的位置上执行递增/递减(取决于端口B上的值)。

void setup()
{
  attachInterrupt(Encoder_1.getIntNum(), isr_process_encoder1, RISING);
  attachInterrupt(Encoder_2.getIntNum(), isr_process_encoder2, RISING);
  Serial.begin(115200);

在setup()中,我们将中断例程附加到编码器,并告诉它们在上升信号中断时触发。在两个编码器都设置了中断处理程序后,我们在arduino设备上启动串行通信,波特率为115200.

  //Set PWM 8KHz
  TCCR1A = _BV(WGM10);
  TCCR1B = _BV(CS11) | _BV(WGM12);
  TCCR2A = _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS21);

接下来的4行代码有点神奇。推理(如评论所示)是将PWM速率设置为8KHz,我假设是电机。 _BV显然是arduino如何在低级别设置位值(在这里做出很大的猜测)?实际上对此并不太确定,但我相信做这个的人做了他们的功课。

  Encoder_1.setPulse(7);
  Encoder_2.setPulse(7);
  Encoder_1.setRatio(26.9);
  Encoder_2.setRatio(26.9);
  Encoder_1.setPosPid(1.8,0,1.2);
  Encoder_2.setPosPid(1.8,0,1.2);
  Encoder_1.setSpeedPid(0.18,0,0);
  Encoder_2.setSpeedPid(0.18,0,0);
}

现在......不可否认,我不知道setPulse,setRatio,setPosPid或setSpeedPid中的数字代表什么......我希望您的PID电机的某些文档可用,因为这对我来说也很神奇。然而,这些函数调用只是在Encoder对象上设置这些属性(希望我有更多话要说:[)...

void loop()
{
  if(Serial.available())
  {
    char a = Serial.read();
    switch(a)
    {

接下来我们有主程序循环。首先,我们检查是否有可以收听的串行连接。如果是,那么我们从串行连接中读取一个字节。如果我们读取的字节对应于任何情况,我们会根据需要在编码器上设置速度。

  Encoder_1.loop();
  Encoder_2.loop();

在此切换块之后,我们在编码器上执行loop()调用。根据消息来源,这实际上是一个更新步骤,我们的设置实际上被转发到我们正在与之通信的设备(我已经假设它是一对电机)。

  Serial.print(     "Speed 1:\t");
  Serial.print(Encoder_1.getCurrentSpeed());
  Serial.print("    \t Speed 2:\t");
  Serial.println(Encoder_2.getCurrentSpeed());
}

最后,我们打印出电机的速度,然后循环程序继续这样做[Read-&gt; Update-&gt; Print] cycle

抱歉,我无法为此提供更多帮助,但这是我能给你的全部。祝你好运,我希望你能找到文件!我回到了无聊的非嵌入式编程工作中去工作;)