PID motor control

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 cant set motor speed.How can I do it.

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);
This topic has a solution.
Last Edited: Fri. Nov 8, 2019 - 04:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Emrah Duatepe wrote:
.If I change the speed like rpm=1000 and then rpm= 100.PID calculation produce very big negative value

You mean something like -900rpm ???

What where you expecting it to be?   Perhaps you could tell us more about your plant, and what PID parameters your using and your experience using PID controls.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ki=0.2 Kp=0,Kd=0;

Plant equation related between rpm and pwm  -> pwm=(2.083*rpm + 176.9)

 

System works good.But when I want to change speed and this diffference is big like first 1000 and then like 100 rpm in this case  

err = setRpm - rpm;
      pwm = (int16_t)pidObj->func.Calculate(pidObj,err);

This algorithm produce big negative value and I can't use negative value with pwm.Maybe I need a algorithm use set rpm down step by step like 1000.. 999...100 in this case probably I wont get negative value. How solution I need ,How proffesionals do it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Emrah Duatepe wrote:
with PID
What "PID" class is this? We see you call:

      pwm = (int16_t)pidObj->func.Calculate(pidObj,err);

but where is the definition of the class of which pidObj is an instance? Specifically what does Calculate() look like?

 

Presumably the idea is to make a smooth transition from what PWM is now to what it needs to be? Is the current PWM setting held as a member within the pidObj class?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Emrah Duatepe wrote:
Ki=0.2 Kp=0,Kd=0;

So if I understand this correctly, you are only using integral control for this?  Very odd, what is the application?

Normally one uses proportional control with some minor integral added in to reduce errors over time, dampening may or may not be needed depending on plant reaction time to controls.

Kp=1, Ki=0.01, Kd=0 to begin and limit the range of Ki output to a set limit.

 

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Emrah Duatepe wrote:
If I change the speed like rpm=1000 and then rpm= 100

So you're demanding an instantaneous, large reduction in the RPM ?

 

PID calculation produce very big negative value

So it's doing like in the old Westerns where they try to stop a runaway train by putting the locomotive into reverse ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys ,  this is inside pid function

 

static float Calculate(pid_t *obj, float err)
{
	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]);

	/* Update state */
	obj->var.state[1] = obj->var.state[0];
	obj->var.state[0] = err;
	obj->var.state[2] = out;

	return out;

}

and this is struct belong pid algorithm

struct 
	{
		float A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
		float A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
		float A2;          /**< The derived gain, A2 = Kd . */
		float state[3];    /**< The state array of length 3. */
		float Kp;               /**< The proportional gain. */
		float Ki;               /**< The integral gain. */
		float Kd;               /**< The derivative gain. */
	}var;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

So you're demanding an instantaneous, large reduction in the RPM ?

Yes I am demanding large reduction in the RPM and Motor should get new RPM slowly and with suitable speed.

Last Edited: Wed. Nov 6, 2019 - 05:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I change the rpm from 1000 to 100

err = setRpm - rpm; 

err = 100 - 1000 = -900 and this change caused a big err .

   pwm = (int16_t)pidObj->func.Calculate(pidObj,err);

and algorithm will create a big negative value to set motor speed for 100 and I cant use this negative value in appropriate way.Maybe you have better solutions for it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Emrah Duatepe wrote:

awneil wrote:

So you're demanding an instantaneous, large reduction in the RPM ?

Yes I am demanding large reduction in the RPM and Motor should get new RPM slowly and with suitable speed.

 

Oh. There's your mistake.

 

You should slowly lower your desired RPM from 1000 to 100 over the time you wish your RPM to slowly change.

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you get a negative value, then set it to zero.

Don't confuse the physical limits with math calculations.

 

If I'm sitting at the red light & calculate I need to accelerate to 200 mph in 4 seconds, it calculates my engine must produce 800HP

Since I only have 100HP engine, it hits its limit and takes its time getting to 200 mph.

 

This can cause integrator windup....so take a look at that term.

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Emrah Duatepe wrote:
Ki=0.2 Kp=0,Kd=0;

Emrah Duatepe wrote:
Yes I am demanding large reduction in the RPM and Motor should get new RPM slowly and with suitable speed.

Your PID values are all wrong for the action you desire, you have no P, large I and no D in your params, it sounds like you want P=1, i=0 and a large D to be a foot on the brake pedal so changes happen sloooowwwlllyyyyy.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

Last Edited: Wed. Nov 6, 2019 - 08:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Placing a clamp around the PWM is the right thing but you probably also want to clamp the value of the absolute integral term so you don't get "reset windup".

 

EDIT: and if I was doing this I would linearize about something so if that is 100 rpm, figure out what the associated steady-state PWM is then clamp symmetrically about that.   Another thing you can do is add a prefilter so that when you change from 100 rpm to 1000 rpm the set-point to the loop looks like 900*[1 - exp(-t/tau)].

Last Edited: Thu. Nov 7, 2019 - 01:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have read all writing, 

Maybe I need to change rpm slowly like Torby said or MattRW told 

 

MattRW wrote:
EDIT: and if I was doing this I would linearize about something so if that is 100 rpm, figure out what the associated steady-state PWM is then clamp symmetrically about that.   Another thing you can do is add a prefilter so that when you change from 100 rpm to 1000 rpm the set-point to the loop looks like 900*[1 - exp(-t/tau)].
  I didn't understand excatly this sentence maybe you can explain for me with more detail.How prefilter? Probably I don't have information sufficiently.

Also I got the Kp,Ki,Kd in Matlab PID Tuner.Also I tried different numbers but better is just Ki equals any number 0.08 and 0.5.  0.08 is too slow 0.02 is better.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Probably because of time difference in countries I couldn't respond quick.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pid with prefilter follows.   Think about making pfl = 1.0, 0,1., 0.01, ...

 

float pfx = 0.0;
float pfl = 0.01;

float filtered_set_point(float set_point) {
  pfx = (1.0 - pfl)*pfx + pfl*set_point;
  return pfx;
}

float kp = 0.0;
float ki = 1.0;
float kd = 0.0;

float pid(float error) {
  float command;
  /* ... */
  return command;    
}

void main() {
  float measurment;
  float set_point;
  float command;

  while (1) {
    measurement = get_measurement();
    set_point = get_set_point();
    set_point = filtered_set_point(set_point);
    error = set_point - measurement;
    command = pid(error);
    output_command(command);
  }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW  it didn't work actually I can't set the setPoint for any number that smaller then current rpm.I can set it higher value but if I try like 990 - 1000 = -10 in this case pwm getting negative.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looking at my code what does the filter do if pfl = 1.0?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW  it works now , probably I write a wrong value somewhere and when I try to fix something probably I change the wrong value.Now next question is If I force the motor reverse direction in this case PID show different response because of direction effect and encoder.For now I thank all of you a lot.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If your problem is solved could you please  mark the thread as solved.