c++ 电机不移动

e37o9pze  于 2023-05-30  发布在  其他
关注(0)|答案(1)|浏览(101)

我已经成功地控制我的电机位置使用PD控制器。但是我有一些编程相关的问题。
下面是我的代码:

#define encoder0PinA_M1  2
#define encoder0PinB_M1  22
int EnablePin = 8;
int PWMPin1 = 3;
int PWMPin2 = 11;

volatile signed int encoder0Pos = 0;
unsigned long LastTime;
signed int Input;
signed int Scaled_PID;
float PID_Output, Scaled_PID1;
signed int ErrorSum,ErrorDiff,Error,LastError;
float kp=6;
float ki=0;
float kd=1;
int SampleTime = 10;
int TimeChange;
unsigned long Now;

void setup()
{
  pinMode(encoder0PinA_M1, INPUT);
  //digitalWrite(encoder0PinA_M1, HIGH);      
  pinMode(encoder0PinB_M1, INPUT);
  pinMode(EnablePin, OUTPUT);
  pinMode(PWMPin1, OUTPUT);
  pinMode(PWMPin2, OUTPUT);
  //digitalWrite(encoder0PinB_M1, HIGH);      
  attachInterrupt(0, doEncoder, CHANGE);  
  Serial.begin (9600);
  Serial.println("start");                
}

void PID()
{
  Now = millis();
  TimeChange = Now - LastTime;
  if(TimeChange >= SampleTime)
  {
    Error =  Input - encoder0Pos;
    ErrorSum = ErrorSum + Error;
    ErrorDiff = Error - LastError;

    PID_Output = kp * Error + ki * ErrorSum + kd * ErrorDiff;

    LastError = Error;
    LastTime = Now;

  }
}

void speedlimitforward()
{
  if (PID_Output >= 15)
  {
    PID_Output= 15;
  }
  if(PID_Output <= -15)
  {
    PID_Output=-15;
  }
  Scaled_PID = PID_Output+15;
  digitalWrite(EnablePin, HIGH);
  analogWrite(PWMPin1,Scaled_PID);

}

void speedlimitbackward()
{
  if (PID_Output >= 20)
  {
    PID_Output= -20;
  }
  if(PID_Output <= -20)
  {
    PID_Output= 20;
  }
  Scaled_PID = PID_Output+20;
  digitalWrite(EnablePin, HIGH);
  analogWrite(PWMPin2,Scaled_PID);
}



void loop()
{
  Input=50;
  PID();
  speedlimitforward();
}

void doEncoder()
{
  if (digitalRead(encoder0PinA_M1) == digitalRead(encoder0PinB_M1))
  {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }

}
如果你看一下我的代码,我已经将Input声明为全局变量,并在loop()中给予Input一个值(在这段代码中有50个计数)。此代码工作正常,电机在接近50个编码器计数时停止。
但是当我将上面代码中的循环更改为下面给出的代码时,我的电机不会移动。我希望它移动到50计数等待一段时间,然后返回到0计数:

void loop()
{
  Input=50;
  PID();
  speedlimitforward();

  delay(2000);
  Input=0;
  PID();
  speedlimitbackward();

  delay(2000);
  Input=-100;
  PID();
  speedlimitbackward();

 }
bttbmeg0

bttbmeg01#

  • 如果你问same question in other places并得到一个答案,我认为你应该回到这里回答你自己的问题并标记为已回答,否则人们会在上面花时间。
  • 问题显然出在delay(2000)上,如果您查看代码,就会明白原因所在。当你只有一条指令时,会发生的是循环开始,检查时间,看看电机是否必须移动,基于多长时间已经过去。因此,如果你放了一个延迟,下一次循环运行时,时间将已经完全花在等待上,电机将不会移动。
  • 你能做的就是跟踪电机的工作,并根据它来移动它。例如,保留一个名为movement_completed的变量,并为其分配一个值,该值由移动函数在完成移动时返回。只有在这个变量被设置后,才能继续下一组动作。

我认为这里的主要问题是,你必须记住loop()是不断被调用的,它不是只运行一次的东西。你需要清楚地理解为什么你的马达在第一个代码中停止(然后你就会明白为什么它在第二个代码中不动)。

相关问题