PID controller question

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

Hi there,

It's my first time of implementing a PID controller for DC servo motor speed control.

Untill now I used a custom control function that was just add or sub the constant value 1 from the target PWM. The feedback is an encoder.

Now due to physical problems I need to switch to a PID controller. Can anybody help or tip me to do this real ?

I have some questions such as:

1. The error is either positive or negative. Do I have to use signed or unsigned variables ?
2. The PWM is 10 bit. The read value from the encoder is 16Bit. How can I use the 16bit value at my PID equation while the resault is a 10bit PWM value.

I am a little bit confused.

Help please.

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

ad 1
Yes perhaps not the position but all the PID parts need to be.
ad 2
if you want to use 16 bit from an encoder you will need to make the calculations in 32bit (perhaps you can ge away with 24 it depends of the dynamics of the system ).
Then take the top 10 bit for the PWM output.

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

First thing PID is a fine algorithm but often insufficient.
To make it useful and usable include a feed forward path in the algorithm.

Decide in update rate of Your PID loop. Too quick and update rate and You may experience problems with numerical noise. Too long a sample interval and loop may become poorly controlled.

Determine the sample rate for Your system.

Sample the measured variable ( in this instance motor speed ),
sample speed setpoint and implement the proportional, derivative and integral parts of the algorithm based on current sample and previous sample values.

That is PID in a nutshell.

To tune it is quite another story.
Essentially start with all gain coefficients at some very small value.
Then slowly increase proportional gain coefficient until the loop starts to oscillate ( becomes unstable ).
At this point back off proportional gain to regain stability.

Add derivative gain to shape the response of the loop ( to a step change in setpoint ). Aim for some slight overshoot but no excessive derivative action. Excessive derivative gain may manifest itself as growling noise from the drive.

Repeat proportional derivative cycle a few times and then add a bit of integral component to try to minimise steady state error in speed. Note Excessive integral value will bring the loop into instability.

This may not be good enough in which case add to the algorithm a feed forward component.

Feed forward component is a scaled sample of setpoint.

Add feed forward component to the output of the PID loop.

To adjust set PID component gains to very small value.
Set FF ( feed forward ) gain to small value. Gradually increase FF gain until the motor runs at about the right no load speed.

Now go to PID loop and tune it as above.

To make this possible provide Yourself with a display / logging facility ( USB or RS232 to a monitor ) and look at the data as you start tuning things. Similarly structure Your program to allow external input interface to be able to set various gains and the sample time.

Hope this helps some

Yassou

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

Thank you guys.

I did it !!!

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

hahahaha....!!!

"Yassou" ignoramus !!!

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

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

Make sure Your integral component has tests for most positive valu and most negative value ( if working with integer variables ) to prevent going into integral windup
or rollover.

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

Also helpful, to avoid derivative kick, compute the D component as a difference of position and not as a difference of error.


Velocity = ( LastPosition - CurrentPosition );
DerivativeError = ( Velocity * DerivativeGain );