Go Down

### Topic: Controlling an animatronics bust (Read 10166 times)previous topic - next topic

#### Retroplayer

#60
##### Feb 12, 2013, 02:37 am
Thanks to both of you. I will take another crack at it tomorrow and read that article.

With the little bit of understanding I have, I was trying high values for P thinking it would do exactly as you describe compared to D. Usually a ratio of 1/4 to 1/8th. Even at 255P, it still oscillated like crazy.

Am I right in thinking this way:

P is the amount of force applied to the motor in proportion to the error
I is the a function of time (not 100% sure beyond that)
D is rate change/time which helps determine when it is getting closer to closing the position and allows me to stop

If I can truly wrap my head around these concepts, I know I can come up with a custom PID that uses these components and gives me exactly what I want. It doesn't help that the majority of articles I am reading have to do with chemical processes and don't seem analogous to what I am trying to do. Also, it doesn't seem that I have true linear control over the motors. I am really surprised... this is something I figured would be so common that I could find all kinds of examples and information.

Trust me, I have been reading hundreds and hundreds of pages. I am an electrical engineer so the math is not above my head. It just seems like they are all explaining it to someone that already knows it trying to be too academic.

Arrrgh!!

#61
##### Feb 12, 2013, 02:43 am
Most algorithms involve increasing P until it oscillates.  Once you have that set P to half that.  Then increase I and D to get better speed or control.  Read that quick wiki page and you should get a good idea of what you want.

#### Retroplayer

#62
##### Feb 18, 2013, 03:31 amLast Edit: Feb 18, 2013, 03:35 am by Retroplayer Reason: 1
Alright, I finally have some code that works. It isn't perfect, but it does what I need it to do. I got rid of the I term, and am doing PD only control.

This is just with one motor at the moment. I am still going to have the issue of dealing with multiple motors (but I think I have that figured out on paper) and with needing a psuedo PWM routine because I will not have enough PWM pins. I got the shift-registers, but I haven't played with them yet. Here is the the code:
Code: [Select]

#define fPin 5 //Causes increasing values of position
#define rPin 6 //Causes decreasing values of position
#define pot A0

volatile byte currpin;

float P, I, D, output;

float Kp = .8;
float Kd = 2.4;

int setpoint = 0;
int currpos = 0;
int lastpos = 0;

int val = 0;

void setup(){

Serial.begin(9600);
pinMode(fPin, OUTPUT);
pinMode(rPin, OUTPUT);

}

void loop(){

char c = 0;
int speed;

if(Serial.available()){

if(c == 't' || c == 'T'){ //Set target position

setpoint = Serial.parseInt();
if(setpoint >255){
setpoint=255;
}
if(setpoint < 0){
setpoint = 0;
}

}

if(c == 's' || c == 'S'){ //Stop if it is going crazy

analogWrite(fPin,0);
analogWrite(rPin,0);
}
}

computePID(setpoint);

if(output < 0){
currpin = fPin;
speed = -1 * output;
speed = speed + 40; //Add an offset because motor will not move at PWM less than 38
if(speed < 50) speed = 0;
speed = constrain(speed, 0, 255);
analogWrite(currpin,speed);

} else{
currpin = rPin;
speed = output;

speed = speed + 40;
if(speed < 50) speed = 0;
speed = constrain(speed, 0,255);
analogWrite(currpin,speed);
}

}

float computePID(int point){
int error;

currpos = map(currpos, 0, 1023, 0, 255);

error = point - currpos;
P = error * Kp;
D = Kd * (currpos - lastpos);

output = (P - D);
output = constrain(output, -255, 255);

lastpos = currpos;

return output;

}

Technically, with P set so low, I am not positive I am even using P. Anything higher than 1 causes oscillation. Any D values lower, causes the motor to hum. The position that it lands on is +-2 my setpoint

Go Up

Please enter a valid email to subscribe