-1

I have had success in controlling position of my motor using PD controller. However I have some programming related problem.

Here is my code:

#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--;
  }

}

If you look at my code, I have declared Input as global variable and in loop() I give a value to Input (50 counts in this code). This code works fine and motor stops at close to 50 encoder counts.

But when I change the loop in above code to the code given below my motor does not move. I want it to move to 50 count wait for sometime and come back to 0 count :

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

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

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

 }
Jonas
  • 121,568
  • 97
  • 310
  • 388
  • 1) This is not C. Arduino is not C. 2) `volatile` does not guarantee atomic access. 3) This is no debugging service. Use the debugger. 4) Using floating point on Arduino is most likely a bad idea. Use scaled integers. – too honest for this site Aug 11 '16 at 00:46

1 Answers1

1
  • If you ask the same question in other places and get an answer, I think you should come back here and answer your own question and mark it as answered, otherwise people are going to spend time on it.

  • The problem is clearly the delay(2000), and if you look at the code you'll see why. When you only have one instruction what happens is that the loop starts, checks the time and see if the motor has to move, based on how long has passed. So if you put a delay, the next time the loop runs, the time will already be entirely spent waiting and the motor will not move.

  • What you can do is keep track of what the motor is doing, and move it based on that. For example, keep a variable called something like movement_completed and assign to it a value that is returned by the movement functions when they have, well, completed the movement. Only after that variable is set, go on with the next set of movements.

I think that the main problem here is that you have to remember that loop() is being constantly called, it's not something that runs just once. You need to have a clear understanding of why your motor stops with the first code (then you'll understand why it doesn't move with the second).

ChatterOne
  • 3,381
  • 1
  • 18
  • 24
  • @Dhav1991 not sure why you ask here on stackoverflow, if you know about the real arduino forum at http://forum.arduino.cc – datafiddler Aug 11 '16 at 14:19