1
\$\begingroup\$

I am trying to recreate the Bode plot and phase margin calculations of ST Application Note 2823 "Current source for LED driving based on the L5973AD".

  • The analysis there (p17) gives: FC as 36 kHz and ζM as 84°
  • My calculations produce: FC as 36110.825275 and ζM as 82.552834°

My question: 1) have I done this correctly? 2) How do I evaluate if these values are "good"?

This is the circuit (p7), but understood as L5973AD (datasheet), with fsw of 500 kHz.

enter image description here
(image from application note given above)

Following the main formula (eq. 9) I'm building it up in SymPy and substituting values right at the end.

$$ G_{loop} = A_{ota} \cdot G_{pwm} \cdot G_{pwr} \cdot \alpha_{led} \tag{9} $$

We do each part: $$ A_{ota} = \frac{G_{m}}{C_{5} \cdot s + C_{EA} \cdot s + \frac{1}{R_{5} + \frac{1}{C_{4} \cdot s}} + \frac{1}{R_{o}}} \tag{15} $$

$$ G_{pwr} = \frac{1}{\left(\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}\right) \cdot \left(DCR + L \cdot s + \frac{1}{\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}}\right)} \tag{14} $$ $$ \alpha_{led} = \frac{R_{1} \cdot R_{sense}}{\left(R_{1} + R_{6}\right) \cdot \left(R_{led} + R_{sense}\right)} \tag{13} $$

Substituting in (9) we get $$ G_{loop} = \frac{G_{m} \cdot G_{pwm} \cdot R_{1} \cdot R_{sense}}{\left(R_{1} + R_{6}\right) \cdot \left(R_{led} + R_{sense}\right) \cdot \left(\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}\right) \cdot \left(DCR + L \cdot s + \frac{1}{\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}}\right) \cdot \left(C_{5} \cdot s + C_{EA} \cdot s + \frac{1}{R_{5} + \frac{1}{C_{4} \cdot s}} + \frac{1}{R_{o}}\right)} \tag{99} $$

Sympy simplify gives

$$ G_{loop} = \frac{G_{m} \cdot G_{pwm} \cdot R_{1} \cdot R_{o} \cdot R_{sense} \cdot \left(C_{4} \cdot R_{5} \cdot s + 1\right) \cdot \left(C_{out} \cdot ESR \cdot s + 1\right)}{\left(R_{1} + R_{6}\right) \cdot \left(\left(DCR + L \cdot s\right) \cdot \left(C_{out} \cdot ESR \cdot s + C_{out} \cdot s \cdot \left(R_{led} + R_{sense}\right) + 1\right) + \left(R_{led} + R_{sense}\right) \cdot \left(C_{out} \cdot ESR \cdot s + 1\right)\right) \cdot \left(C_{4} \cdot R_{5} \cdot s + C_{4} \cdot R_{o} \cdot s + R_{o} \cdot s \cdot \left(C_{5} + C_{EA}\right) \cdot \left(C_{4} \cdot R_{5} \cdot s + 1\right) + 1\right)} \tag{9} $$

Constant values

# only values are given in fig 7 Substitute C4 = 6.8e-08 Substitute C5 = 3.3e-11 Substitute R5 = 330.0 Substitute C_EA = 3e-12 (p16, in eq 17) Substitute C_out = 1e-07 (p 15 in eq 14) Substitute DCR = 0.155 (not given, typ value guessed) Substitute ESR = 0.1 (not given, typ value guessed) Substitute G_m = 0.0023 (p16, in eq 17) Substitute G_pwm = 26.3 (p13, eq 10) Substitute L = 0.0001 (p15 in eq 14) Substitute R1 = 20000.0 (p8 eq 5) Substitute R6 = 6800.0 (p8 eq 5) Substitute R_led = 1.3 (p13, eq 11) Substitute R_o = 800000.0 (p16, in eq 17) Substitute R_sense = 1.5 (p8 eq 4) 

Now we have the single remaining s: $$ G_{loop} = \frac{54170.1492537313 \cdot \left(1.0 \cdot 10^{-8} \cdot s + 1\right) \cdot \left(2.244 \cdot 10^{-5} \cdot s + 1\right)}{\left(2.8 \cdot 10^{-8} \cdot s + \left(2.9 \cdot 10^{-7} \cdot s + 1\right) \cdot \left(0.0001 \cdot s + 0.155\right) + 2.8\right) \cdot \left(2.88 \cdot 10^{-5} \cdot s \cdot \left(2.244 \cdot 10^{-5} \cdot s + 1\right) + 0.05442244 \cdot s + 1\right)} $$

We extract the polynomial coefficients of s:

num, den = G_loop.as_numer_denom() numf = list(map(float, num.as_poly(s).coeffs())) denf = list(map(float, den.as_poly(s).coeffs())) 

And using Python's Control library doc

G = ct.tf(numf, denf) gm, pm, _, _ = ct.margin(G) 

G is this, polynomials of s:

 1.216e-08 s^2 + 1.216 s + 5.417e+04 --------------------------------------------------------------- 1.874e-20 s^4 + 1.644e-12 s^3 + 5.451e-06 s^2 + 0.161 s + 2.955 

Gain and phase margin:

gain margin 3143.446534 phase margin 82.552834 

Further functions give a frequency margin of 36110.825275 and a (visually) matching Bode plot.

enter image description here
Bode plot actually made with sympy.physics.control.lti.TransferFunction and .bode_plot

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Why not make comparative graphs use the same y-axis? \$\endgroup\$ Commented Oct 6 at 8:48
  • \$\begingroup\$ @Andyaka If you mean spacing of grid? because I don't (yet) know how to. \$\endgroup\$ Commented Oct 6 at 9:55
  • \$\begingroup\$ Very nice results but the formulas are almost impossible to follow, they do not obey a low-entropy form. For instance, check my PPT on slide 82 for the TF of the OTA in a type 2 compensation (\$r_0\$ is neglected though). As pointed out by Andy aka, you could import the data in your Mathcad sheet. Check my PPT where I show how to import SIMPLIS data in a Mathcad chart. It should also work with the program you've used. \$\endgroup\$ Commented Oct 6 at 18:48
  • \$\begingroup\$ @VerbalKint thank you for your comment. I'll read your links, and also see what I can do about those formulas (which are straight from the datasheet, through sympy, and then substituted). \$\endgroup\$ Commented Oct 7 at 16:40
  • \$\begingroup\$ No problem, I commend your analytical approach for determining the loop gain and phase for stability analysis : ) I remember looking into the stability of a boost LED driver in this article published on How2Power years ago. You can also easily model this converter with an averaged model, plenty to simulate in my latest LTspice files collection ZIP. \$\endgroup\$ Commented Oct 7 at 17:30

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.