Proportional Motor Control In A Microcontroller


Proportional motor control is useful in many applications.  Control theory describes

proportional control as…

Pout = Kp*error( t )

Where Pout is your drive signal, Kp is your proportional gain, and error( t ) is the error signal.  Here’s an example of how this translates to a microcontroller application that isn’t using floating point numbers.

With high level languages most microcontrollers can implement floating point numbers, but at times it can be useful to simplify values to make use of integers only, so that’s what we’ll do here.   Let’s imagine we have two potentiometers, one controlled by the user, and the other connected to a motor representing motor position.  A microcontroller is reading these values and converting them to a motor drive signal.

error( t ):
The error signal is often described by a set point minus a process variable.  The set point is your control signal (where you want your feedback signal to be).  Out set point is a voltage from a potentiometer (analog control signal).  Our process variable is a voltage from a potentiometer connected to the motor’s output shaft (analog feedback signal).  If our microcontroller can read both of these voltages with 12-bit resolution then error( t ) = Vpot – Vmot, and both voltages are represented by a 12-bit value from 0-4095 (4095 = max voltage, 0 = 0V).

You can see that if…

Vpot = Vmot then (Vpot – Vmot) = error( t ) = 0
Vpot = 4095 and Vmot = 0 then error( t ) = 4095
Vpot = 0 and Vmot = 4095 then error( t ) = –4095

So we have a 12-bit error signal that has a sign value that relates to the direction the motor should turn.  Minus means the motor should be driving the Vmot pot to a lessor value, plus means the motor should be driving the Vmot pot to a greater value (Minus reverse, plus forward).

In this example Pout is a 10-bit  pulse-width-modulated signal.  So our output is a value from 0-1023, with 1023 being full “on” and 0 being full “off” (therefore 768 is 75% “on”).  Pout must also incorporate a directional component, where a negative number correlates to a reversed motor.  Changing motor direction can be done by adjusting the drive signals to an H-bridge so the PWM signal is applied to 1/2 of the bridge for reverse or the other half for forward.  In pseudo code this would look something like this:

if Pout < 0 then
make motor direction reverse
Pout = absolute value of Pout
make motor direction forward
end if

motor drive signal = Pout

The proportional gain term is used to convert the error( t ) signal from a 12-bit signed signal (-4095 to 4095) to a 10-bit signed signal (-1023 to 1023) appropriate for the PWM output.   For this example its simplest form would be  Kp = 0.25.  You can see this by looking at the extremes.

Pout = Kp*error( t ) => 1023 = 0.25*4095 and -1023=0.25*-4095.

But we’re not using floating point numbers.  So we need to break our Kp term into two steps, a Kp multiplier and a Kp divider.    This is still pretty easy, you just divide by 4 by setting Kp multiplier = 1 and Kp divider = 4, in fact you don’t even need the mutliplier.

But what happens if you need more gain.  You might have a motor that only runs when the drive signal is over 20%, or some other arbitrary value.  Let’s assume you need a Kp = 0.673.  You can achieve this by setting Kp multiplier to 673, and Kp divider to 1000.  So you can still achieve the desired proportional gain using integers.

You can avoid using floating point math in microcontrollers and still perform fractional math useful for proportional control systems.  This can reduce the length of communication strings, and shorten code run times.

Speak Your Mind