Multiple inputs for PID controller

Hello everyone,

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 try to run the loop below, motor does not move:

void loop()
{
  Input=50;
  PID();
  speedlimitforward();
  
  delay(2000);
  Input=0;
  PID();
  speedlimitbackward();
  
  delay(2000);
  Input=-100;
  PID();
  speedlimitbackward();
  
 }

How to use multiple value of Input in this code??

I am using this motor along with arduino mega and this motor controller

Can someone suggest something? I don't seem to figure out the reason. :confused:

Well using delay(2000) is going to make motor control impossible, so lose that for starters.

Not sure why the motor doesn’t move at all. Suggest you post entire sketch, not a snippet,
because the problem is never where you think it is… Trust us on that!

Hi MarkT,

First code is the complete code which works fine. Motor stops at 50 counts. After stopping the motor at 50 i want to move it back to 0 and then to -100.

Second code is the part I changed in code 1 to achieve the target mentioned above. When I put all of it together, it does not work. That is moving from 50->0->-100. Individually it works fine.

And yes you were right about delays. I have changes it. Thanks.

Your PID code uses TimeChange = Now - LastTime; . Seeing as there is a 2000ms delay in your new code, perhaps your values are overflowing? TimeChange is going to be 2000, it's a multiplier, and you are using ints with a limit of ±16k in a few places.