Go Down

Topic: PID Library MISHAP!(Pls Help longTime problem) (Read 1 time) previous topic - next topic

NI$HANT

Thanks! Mr.John, One more question I'm setting the setpoint of the PID value to the counts that are taken up by the encoder like 9 so I think when the PID sees the value counted isn;t 9 then it will strive to achieve that position by rotation forward or reverse to get hold to that position but mine isn;t working like that??

The following is the completed code:

Code: [Select]
#include <PID_v1.h>

#define encoder0PinA 2
#define encoder0PinB 3
volatile unsigned int encoder0Pos = 0;
// Motor control 1 is connected to the Digital PIN 5
const int MotorControlPin1 = 5;
// Motor control 2 is connected to the Digital PIN 6
const int MotorControlPin2 = 6;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

void setup() {
  pinMode(encoder0PinA, INPUT);
  pinMode(encoder0PinB, INPUT);
  Setpoint = 4;
// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE); 
  myPID.SetMode(AUTOMATIC);
  Serial.begin (19200);
}
void loop(){
  Input = encoder0Pos;
  myPID.Compute();
  if (Output > 0)
     {
     // Output is positive so set MotorControlPin2 (Direction) to HIGH
     digitalWrite(MotorControlPin2, HIGH);
     // When Direction is HIGH, a LOW on MotorControlPin1 (PWM Speed) causes the motor to run
     analogWrite(MotorControlPin1, 255 - constrain((int)Output, 0, 255));
     }
  else
    {
    // Output is negative so set MotorControlPin2 (Direction) to LOW
    digitalWrite(MotorControlPin2, LOW);
     // When Direction is LOW, a HIGH on MotorControlPin1 (PWM Speed) causes the motor to run
     analogWrite(MotorControlPin1, constrain((int)-Output, 0, 255));
    }
}
void doEncoderA(){
  // look for a low-to-high on channel A
  if (digitalRead(encoder0PinA) == HIGH) {
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == LOW) { 
      encoder0Pos = encoder0Pos + 1;         // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }
  else   // must be a high-to-low edge on channel A                                       
  {
    // check channel B to see which way encoder is turning 
    if (digitalRead(encoder0PinB) == HIGH) {   
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
  Serial.println (encoder0Pos, DEC);         
  // use for debugging - remember to comment out
}
void doEncoderB(){
  // look for a low-to-high on channel B
  if (digitalRead(encoder0PinB) == HIGH) {   
   // check channel A to see which way encoder is turning
    if (digitalRead(encoder0PinA) == HIGH) { 
      encoder0Pos = encoder0Pos + 1;         // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }
  // Look for a high-to-low on channel B
  else {
    // check channel B to see which way encoder is turning 
    if (digitalRead(encoder0PinA) == LOW) {   
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
}
"Real Men can Accomplish  Anything"
-  Website  
- skype : nishants5  

????? ???? !

NI$HANT

#11
Sep 28, 2012, 04:51 pm Last Edit: Sep 28, 2012, 05:05 pm by NI$HANT Reason: 1
I have somewhat small success with the following code  but still the hard grip of the motor at a particular position is not there, which parameter of the kp,ki or kd I must modify or what changes in the programme must be made?

BEHAVIOUR: Now the motor seems to catch up a position but moves pretty fast from one point to another , the distance between these two points is too less.

PLEASE! watch - Video>> http://www.youtube.com/watch?v=ZqvvoGbZobg

Code: [Select]
#include <PID_v1.h>

#define encoder0PinA 2
#define encoder0PinB 3
volatile unsigned int encoder0Pos = 0;
// Motor control 1 is connected to the Digital PIN 5
const int MotorControlPin1 = 5;
// Motor control 2 is connected to the Digital PIN 6
const int MotorControlPin2 = 6;
double KD,KP,KI,lastError,sumError;

void setup() {
 pinMode(encoder0PinA, INPUT);
 pinMode(encoder0PinB, INPUT);
// encoder pin on interrupt 0 (pin 2)
 attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
 attachInterrupt(1, doEncoderB, CHANGE);  
 Serial.begin (19200);
}
void loop(){
 int val; //= analogRead(14);
int target = map(212, 0, 1023, 0,12 );// set the seek to target by mapping the potentiometer range to the encoder max count
int error = encoder0Pos - target; // find the error term = current position - target
// generalized PID formula
//correction = Kp * error + Kd * (error - prevError) + kI * (sum of errors)

// calculate a motor speed for the current conditions
int motorSpeed = 10 * error;//kp
motorSpeed += 5 * (error - lastError);//kd
motorSpeed += 10 * (sumError);//ki
// set the last and sumerrors for next loop iteration
lastError = error;
sumError += error;
if (motorSpeed > 0)
    {
    // Output is positive so set MotorControlPin2 (Direction) to HIGH
    digitalWrite(MotorControlPin2, HIGH);
    // When Direction is HIGH, a LOW on MotorControlPin1 (PWM Speed) causes the motor to run
    analogWrite(MotorControlPin1, 255 - constrain((int)motorSpeed, 0, 255));
    }
 else
   {
   // Output is negative so set MotorControlPin2 (Direction) to LOW
   digitalWrite(MotorControlPin2, LOW);
    // When Direction is LOW, a HIGH on MotorControlPin1 (PWM Speed) causes the motor to run
    analogWrite(MotorControlPin1, constrain((int)-motorSpeed, 0, 255));
   }
}
void doEncoderA(){
 // look for a low-to-high on channel A
 if (digitalRead(encoder0PinA) == HIGH) {
   // check channel B to see which way encoder is turning
   if (digitalRead(encoder0PinB) == LOW) {  
     encoder0Pos = encoder0Pos + 1;         // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;         // CCW
   }
 }
 else   // must be a high-to-low edge on channel A                                      
 {
   // check channel B to see which way encoder is turning  
   if (digitalRead(encoder0PinB) == HIGH) {  
     encoder0Pos = encoder0Pos + 1;          // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;          // CCW
   }
 }
 Serial.println (encoder0Pos, DEC);          
 // use for debugging - remember to comment out
}
void doEncoderB(){
 // look for a low-to-high on channel B
 if (digitalRead(encoder0PinB) == HIGH) {  
  // check channel A to see which way encoder is turning
   if (digitalRead(encoder0PinA) == HIGH) {  
     encoder0Pos = encoder0Pos + 1;         // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;         // CCW
   }
 }
 // Look for a high-to-low on channel B
 else {
   // check channel B to see which way encoder is turning  
   if (digitalRead(encoder0PinA) == LOW) {  
     encoder0Pos = encoder0Pos + 1;          // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;          // CCW
   }
 }
}
"Real Men can Accomplish  Anything"
-  Website  
- skype : nishants5  

????? ???? !

johnwasser

I suspect that your PID parameters are WAY off. You should probably read up on PID tuning.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Go Up