View previous topic :: View next topic |
Author |
Message |
Zek_De
Joined: 13 Aug 2016 Posts: 100
|
PID motor control |
Posted: Wed Nov 06, 2019 8:29 am |
|
|
Hi guys
Codes below control the motor speed with PID but I have a problem. If I change the speed like rpm=1000 and then rpm= 100. PID calculation produce very big negative value and this is why I can't set motor speed. How can I do it?
Code: |
rpm = bldcObj->func.Get_RPM(bldcObj);
//rpm = kalman1Dobj->func.Calculate(kalman1Dobj,rpm);
err = setRpm - rpm;
pwm = (int16_t)pidObj->func.Calculate(pidObj,err);
if(pwm>3000) pwm=3000;
else if(pwm<0) pwm=0;
bldcObj->func.Set_Duty_Cycle(bldcObj,pwm);
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Nov 07, 2019 6:06 am |
|
|
OK, no one's responded for awhile so...
1st, your code isn't complete. Code for any functions need to be posted.
2nd, only use unsigned integers for the 'math' as the PWM module only uses unsigned (0 -1023, if 10 bit).
3rd, always post PIC and compiler version.
4th, show us examples of the 'bad numbers' vs. what you think they should be. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Nov 07, 2019 7:03 am |
|
|
and if you look at any normal PID implementation there will be limit
tests to prevent 'wind up' when the code receives extreme values....
This actually sounds like extreme 'overshoot' which is normally caused
by having the D value too large. |
|
|
Zek_De
Joined: 13 Aug 2016 Posts: 100
|
|
Posted: Fri Nov 08, 2019 3:36 am |
|
|
Code: | rpm = bldcObj->func.Get_RPM(bldcObj);
//rpm = kalman1Dobj->func.Calculate(kalman1Dobj,rpm);
err = setRpm - rpm;
saturation=err;
if(err>3000) saturation=3000;
else if(err<0) saturation=0;
saturation=saturation-err;
pwm = (int16_t)pidObj->func.Calculate(pidObj,err,saturation);
bldcObj->func.Set_Duty_Cycle(bldcObj,pwm); |
and inside PID
Code: | static float Calculate(pid_t *obj, float err,float backCalc)
{
float out;
/* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
out = (obj->var.A0 * err) + (obj->var.A1 * obj->var.state[0]) + (obj->var.A2 * obj->var.state[1]) + (obj->var.state[2]) + (backCalc*err);
/* Update state */
obj->var.state[1] = obj->var.state[0];
obj->var.state[0] = err;
obj->var.state[2] = out;
return out;
} |
I add a new variable for algorithm because of back calculation
Kd=0,Kp=0,Ki=0.2
I changed the uint16 to int16_t, I didn't realised it but now still I got big negative value. I am still working on it. |
|
|
Zek_De
Joined: 13 Aug 2016 Posts: 100
|
|
Posted: Fri Nov 08, 2019 3:40 am |
|
|
y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] * x[n]*e[n]
x[n]*e[n] comes back calc using z transform. x[n] equals current limited value for pid. I couldn't write for a while sorry for that. |
|
|
Zek_De
Joined: 13 Aug 2016 Posts: 100
|
|
Posted: Fri Nov 08, 2019 6:27 am |
|
|
Actually I can't set it any new rpm that is lower than previous rpm. Just I can set it for higher rpm. Why it behaves like that ? |
|
|
|