**I Introduction:**

In 2009 I spent a lot of time in a First Chief Delphi forum thread with some motor experts figuring out why a JAGUAR controller was linear in speed with duty cycle and a Victor was non_linear. An example of this phenomenon is shown here for a Vex 269 motor being driven by several types of controllers. Data is from my Excel H_bridge model. All controllers have basically the same design except for the PWM frequency. The extremes are for the JAGUAR is 15k hz and the Victor 884 is 120 hz.

Turns out that the motor time constant tau = L/R (motor inductance/motor resistance) relative to the PWM pulse period T is key to the phenomenon. I call the ratio of these lamda = T/(L/R).

I developed some analytical models for this forum which can predict the waveforms and average currents with good accuracy for various types of controllers and I want to show the basic mathematical derivation in this post. I have updated the equations to include the Vex controller which has a PWM frequency near 1250 hz which is in between the JAGUAR and the Victor 884.

It is assumed that the reader has a basic knowledge of how an H bridge works. If not, there are many good references on the internet and I might suggest the following:

The type of H bridge that I am assuming is often called a high side switcher or asynchronous sign magnitude H bridge. Basically, for a given motor direction, two switches are used while the others remain open.

General note.. clicking on any figure will expand it to maximum size.

On the high side switcher, a lower switch is closed and the upper switch is driven by a PWM waveform and opens and closes with period T and duty cycle D.

When the PWM pulse is high, the ON current flows from the battery through the motor as shown.

When the PWM pulse is low, the OFF phase current flows through the diode as shown.

**II H bridge Equivalent Circuit**

The equivalent circuit for one motor direction of the H bridge is just a switch and a battery in series with system resistance R_s and a motor (This is modeled as an inductor , resistor R , voltage source = V_bemf in series) as shown in the “Simplified DC motor switching model.”

There is also a diode that is across the motor to allow current to flow when the switch is opened. The switch opens and closes with a PWM drive with duty cycle D and period T.

(click figure to expand)When the switch is closed current increases exponentially from its last value toward a steady state value of i_ss_on. When the switch is opened, current decays through the diode toward i_ss_off. If it reaches zero then current stops and remains at zero until the next on pulse.

.

We can write the differential equations for these two phases. It is important to note that these equations are for the controller direction that puts a positive voltage across the motor. When the motor is commanded in the opposite direction some sign changes must be made to the equations. Where ever you see a V_b and a V_d simply change the signs and the equations will be correct for the current. The steady state speeds also require replacing i_free with -i_free. These will be added in the software implementation by using the sign(command) which tests the sign of the command. Duty is always positive and for Vex is defined as D = abs(command/127) where the command ranges between -127 and + 127.

**III ON phase Current**

When the switch is closed, the voltage across the motor V_m = -V_d > 0 so the diode is reversed biased and i_d = 0 . Using Ohms law and the fact that i = i_L ( no current is flowing through the diode in this phase) gives

0 = V_b – V_bemf – V_L – i*(R +R_s).

But the voltage in the inductor V_L = L*di/dt So we have a differential equation

di/dt = ( V_b – V_bemf – i*(R +R_s) )/L

In the steady state, di/dt–>0 so the steady state current

**i_ss_on = (V_b – V_bemf)/(R +Rs**)

Putting it in terms of motor time constant

**di/dt = (i_ss_on – i)/tau_on where tau_on = L/(R_s + R)** .

The ON closed form solution of the differential equation can be shown to be

**i_on = i_0*exp(-t/tau_on) + i_ss_0n *(1 – exp(-t/tau_on)) **

where i_0 is the initial current.

At t = DT the maximum occurs and using the substitution lamda = T/tau_on we can write

**i_max = i_o*exp(-lamda*D) + i_ss_on*(1 – exp(-lamda*D)) **

**IV OFF phase current**

When the switch is opened current in the motor coil finds a path through the diode.

i_L = i_diode

0 = V_bemf + V_L + i_L*R + V_d

Substituting for V_L = L*di_L/dt gives the differential equation

**di_L/dt =- (V_bemf + V_d + i_L*R)/L** and

**i_ss_off = -(V_d + Vbemf)/R** when di_L/dt –> o.

The OFF closed form solution is

**i_off = i_max* exp(- t’/tau_off) + i_ss_off *(1 – exp(- t’/tau_off))**

where again tau_off = L/R . Here i_max is the maximum current of the ON phase which occurs at the exact point that the switch opens or at t = D*T so ** i=max is the initial current** for the OFF phase. t’ is the time from the switch opening. I. E. t’ = t – D*T for t> DT.

**V Approximation for Vex motors**

The time constants for the ON and OFF phases are slightly different due to the addition of Rs during the switch ON phase. I.e. tau_on = L/(R+Rs) and tau_off = L/R. For the Vex motors, Rs << R so the following equations will use the approximation tau= L/R = tau_on =tau_ off.

**VI Final Current Value, i_final**

During the OFF phase the current will decay to a final value of current. The point in time where it reaches it final value will be defined t’(final) = D’T . Substituting t’ = D’T and lamda = T/tau into i_off equation gives

**i_final = i_max*exp(- lamda*D’) + i_ss_off*(1 – exp(-lamda*D’)**

**VII Initial current i_0**

A steady state solution requires that

**i_0 = i_final**

otherwise after a cycle is completed the next initial condition will be different from the initial condition for the last cycle.

Using this equality and substituting i_max into the i_final equation gives

i_0 =( i_o*exp(-lamda*D) + i_ss_on*(1 – exp(-lamda*D))*exp(-lamda*D’) + i_ss_off*(1 – exp(-lamda*D’)

Solving for i_0 gives

**i_0 = ( i_ss_on*(1 – exp(-lamda*D))*exp (-lamda*D’) + i_ss_off*(1 – exp(-lamda*D’))/(1 – exp(-lamda*D)*exp(-lamda*D’))**

(Click to expand figures)

Recall as shown in this figure, the current can be continuous or discontinuous.

**Case A: Continuous current **

If the diode conducts during the whole OFF phase then steady state current requires i_0 = i_final and

D’ = 1-D . That is i_final occurs exactly at the end of the period. Substituting for D’ and i_final in the i_o equation gives

**i_0 = ( i_ss_on*(1 – exp(-lamda*D))*exp (-lamda*(1-D))+ i_ss_off*(1 – exp(-lamda*1-D)))/(1 – exp(-lamda*D)*exp(-lamda*(1-D)))**

**Case B: Discontinuous current**

In Case B, the current tries to reverse sign during the OFF phase but is clamped to zero by the diode for the remainder of the PWM period. So both the final and initial currents are zero in the steady state.

**i_final = i_0 = 0**

With this constraint, we can solve the i_0 equation for D’ at the point where the waveform reaches 0.

0 = i_ss_on*(1 – exp(-lamda*D))*exp (-lamda*D’) + i_ss_off*(1 – exp(-lamda*D’)

exp(-lamda*D’) = -i_ss_off/(i_ss_0n*((1-exp(-lamda*D) - i_ss_off))

and taking the ln of both sides

D’ = – ln( -i_ss_off/(i_ss_on*((1 – exp(-lamda*D) – i_ss_off)* lamda)

Or in terms of i_max,

** D’ = - ln( -i_ss_off/(i_max – i_ss_off)* lamda)**

**VIII AVERAGE CURRENT PER CYCLE – i_avg**

Our primary interest in developing current equations is to determine an expression that can be used to control the long-term behavior of a motor relative to a slow PTC fuse or setting a the steady state speed for a robot. What we want is the equivalent DC current over a cycle which is the average current per cycle. This is computed by integrating the area under the current response and dividing by a cycle time. If the times are normalized to the controller period T then the average current

i_avg = Area_on + Area_off

where Area_on and Area_off are the areas under their respective current responses in the ON and OFF phases. By integrating the i_on with respect to t and normalizing to the period T gives

Area_on = i_ss_on*D – (i_ss_on – i_0)*(1 – exp(-lamda*D)/lamda

Similarly for the off phase we have the same form except i_o for the off phase = i_max.

Area_off = i_ss_off*D – (i_ss_off – i_max)*(1 – exp(-lamda*D’)/lamda

Believe it or not , the second term in the Area_on equation cancels the second term in the Area_off equation. Both these terms can be related to i_max – i_0 by using the fact that i_o = i_final. With some substitutions and math manipulations it can be shown that:

(i_ss_on – i_0)*(1 – exp(-lamda*D) = -(i_ss_off – i_max)*(1 – exp(-lamda*D’) = i_max – i_o.

This leaves

**i_avg = i_ss_on*D + i_ss_off*D’ **

We can substitute for i_ss_on and i_ss_off and get i_avg in terms of voltages.

**i_avg = (V_b – V_bemf)*D/R – (V_d + V_bemf )*D’/R **

For a given D , D’ can vary from 0 to 1 – D depending upon the value of D and lamda. The current waveforms take on essentially three shapes: rectangular, triangular or exponential saw tooth shapes depending on how D’ is characterized.

**XI Vamfun rectangular approximation lamda>>1 , D’= 0.**

Under this condition the motor responds very quickly with respect to the PWM pulse. It essentially reaches I_ss_on and stays there for the duration of the ON pulse and quickly decays to zero during the OFF phase. Thus the current waveform approaches a** rectangular shape** and so we can compute i_avg accurately with this formula when D’ = 0 :

**i_avg = (V_b – V_bemf)*D/R **

This leads to a steady state speed vs duty that is inversely proportional to duty. We know that the free speed of a motor occurs when i_avg = i_free. Rearranging the current equation with this equality gives

**V_bemf(steady state) = V_b – i_free*R/D for D>= i_free*R/V_b**

**= 0 for D < i_free*R/V_b **

which says that if the current doesn’t exceed i_free then the drag torque holds the motor speed to zero.

This figure shows a typical rectangular waveform produced by a Victor 884 controller ( PWM frequency = 120 hz , lamda = 30) controlling a Vex 269 motor. (click to expand)

This curve was generated with a Labview program I wrote which is a simple integration of the L R response to various duty cycle inputs.

**X Vamfun triangular approximation lamda <<1 , D’ = 1 – D**

This approximation occurs when the PWM frequency is much higher than the motor response frequency and many PWM cycles occur in one tau for the motor. Both the ON and OFF phase waveforms are approximated by linear slopes and the **waveform is triangular**. The approximate formula becomes

i_avg = (V_b – V_bemf)*D/R – (V_d + V_bemf )*(1-D)/R or collecting D terms

**i_avg = (V_b +V_d)*D/R – (V_d + V_bemf)/R **

This leads to a linear steady state speed vs duty when i_avg = i_free. I. E.

**V_bemf(steady state) = (V_b + V_d) *D - i_free*R – V_d **

**for D > (i_avg*R + V_d)/(V_b +V_d)**

else

**V_bemf = 0.**

This equation becomes the* standard DC motor current model when V_d = o* .

This linear speed response would be typical of a Vex 269 being driven by a TI JAGUAR controller that operates with a PWM frequency of 15 kHz which makes lamda = .24 . The JAGUAR controller is used in First robotic competitions. It produces a typical triangular waveform as shown here (click to expand figure):

**XI Non extreme lamda produces exponential saw tooth**:

This figure shows an example of an exponential saw tooth waveform produced by Vex controller (PWM frequency 1250 hz , lamda = 3) driving a Vex 269 motor with a .3 duty. (click to expand)

Notice that the first trace which is the motor voltage has three distinct levels. During the ON phase it equals V_b. During the off phase while the diode is conducting it equals -V_d and when the current goes to zero it then reads the back emf voltage V_bemf. During this period some controllers actually sample V_bemf to estimate motor speed without encoders. If the diode always conducts like the previous figure, then the controller must periodically use a special pulse to sample V_bemf.

**XII Computational Proceedure:**

Ok, we have lots of formulas and here are the steps to put them to use.

0) Gather inputs: V_b,V_bemf,V_d, lamda, R, command

1) Compute the input duty D and direction dir

D = abs(command/127)

dir = sign(command)

2) Compute i_ss_on and i_ss_off from known voltages.

**i_ss_on = (V_b*dir – V_bemf)/R**

**i_ss_off = -(V_d*dir + V_bemf)/R**

3) Compute i_0 and test if current is continuous or discontinuous.

**i_0 = ( i_ss_on*(1 – exp(-lamda*D))*exp (-lamda*(1-D))+ i_ss_off*(1 – exp(-lamda*1-D)))/(1 – exp(-lamda*D)*exp(-lamda*(1-D)))**

If the sign(i_0) is opposite the sign (i_ss_on). I.e.

if( sign(i_0) *sign(i_ss_on) < 0 ) then current is discontinuous and set i_o = 0.

4) Compute i_max

**i_max = i_o*exp(-lamda*D) + i_ss_on*(1 – exp(-lamda*D)) **

5) Compute D’

if(discontinuous) then

**D’ = – ln( -i_ss_off/(i_max – i_ss_off)* lamda)**

else

**D’ = 1-D **

6) Compute i_avg

**i_avg = i_ss_on*D + i_ss_off*D’ **

Thats it. See link below for a RobotC implementation of these equations.

**Related Links:**

Vex 269 Current data based upon Excel Hbridge Model

smart-software-monitor-keeps-ptc-fuses-from-tripping

Vex threads: