# Gas station without pumps

## 2013 February 15

### Seventeenth day of circuits class: inductors and gnuplot tutorial

Filed under: Circuits course — gasstationwithoutpumps @ 22:25
Tags: , , , , , ,

I started today with the physics formulas for the field in a solenoid and for the voltage as the field changes.  We ended up with the $V=\mbox{constant} \frac{\partial I}{\partial t}$, with a rather messy constant, which I declared that we would call inductance and symbolize with an L.  I also told the students that they wouldn’t need to know how to compute L from first principles, since this wasn’t a physics class.  We then looked at what would happen if we put a sinusoid into an inductor, and got the classic $Z=j \omega L$ for inductors, which I told the students to memorize.

We then got out laptops to do a hands-on tutorial on gnuplot.   I walked them through using gnuplot to plot the impedance of an inductor, then what happens if we put a resistor in series or in parallel (talking them through the DC and ∞ frequency asymptotes before we looked at each plot).  We figured out the corner frequency $\omega=R/L$, which I did not point out is equivalent to an $L/R$ time constant.  We did high-pass and low-pass voltage dividers, then started looking at inductors and capacitors in parallel or in series. We did the algebra for the infinite impedance of  an LC parallel circuit when $\omega^2=LC$.  We ended the modeling of inductor circuits with an R || L || C circuit, which they had correctly reasoned would have 0 impedance at 0 Hz and ∞ Hz, and a maximum of R at $\omega= \sqrt{LC}$.

Here is the script that was built as we did the exploration:

set logscale x
set xlabel "frequency [Hz]"
unset key

set logscale y
set ylabel "impedance [ohms]"

j=sqrt(-1)
Zc(f,C) = 1/(j*2*pi*f*C)  # f= frequency [Hz], C=cap [farads]
Zl(f,L) = j*2*pi*f*L

Zpar(z1,z2) = z1*z2/(z1+z2)
divider(Zup,Zdown) = Zdown/(Zup+Zdown)

set xrange[1:1e6]
set yrange[*:*]

# plot impedance of 1 milliHenry in parallel with 10ohms
# plot 10, abs(Zl(x,1e-3)), abs(Zpar(Zl(x, 1e-3),10))

# set ylabel "gain"
# plot abs(divider(Zl(x,1e-3),10))

# plot impedance of 1 milliHenry in parallel with 1uF
# plot abs(Zc(x,1e-6)), abs(Zl(x,1e-3)), abs(Zpar(Zl(x, 1e-3),Zc(x,1e-6)))

# plot impedance of 1 milliHenry in series with 1uF
#plot abs(Zc(x,1e-6)), abs(Zl(x,1e-3)), abs(Zl(x, 1e-3)+Zc(x,1e-6))

# set ylabel "gain"
# plot abs(divider(Zc(x,1e-6),Zl(x,1e-3)))

# plot impedance of 1 milliHenry in parallel with 1uF and 10 ohms
plot abs(Zc(x,1e-6)), abs(Zl(x,1e-3)), abs(Zpar(10,Zpar(Zl(x, 1e-3),Zc(x,1e-6))))


I then switched tracks back to modeling the loudspeaker. If you want to try your hand at modeling the data, it is available on the class web site as 10W-loudspeaker-47ohm-more.data, but Windows users may have to cut and paste from the browser and use a different file name, since Windows is very fussy about having an extraneous carriage-return character on every line and not allowing arbitrary extensions (try .txt instead of .data).

I copied the boilerplate (definitions of j, Zl, Zc, Zpar, and divider) into the loudspeaker gnuplot script we’d been working on, and started trying to model the loudspeaker. We had left off last time modeling it as a constant resistance of 8 ohms, so we tried adding an inductor. (I managed to get them to tell me that the inductor had to be in series, because it was increasing the impedance.) Even without doing any fitting, we had a good initial model (8Ω in series with 100µH):

First hand approximation to model for loudspeaker: 8Ω in series with 100µH.

After that we did a quick look at the resonance peak, which (with a little prompting) they recognized as being like the LC parallel circuit and needing to be in series with the model so far.  I estimated values of L and C for them by zooming in to determine the frequency of the peak (around 148Hz, so ω around 865kHz, or LC=1.16E-6 sec)—we started with 1mH and 1000µF as being in the right ballpark for LC.  That gave us a huge spike of infinite impedance, and I gradually got them to remember the R||L||C  curve we had before.  Again, I helped them out by zooming in and noting that the peak was around 23Ω, about 15Ω more than the baseline.

The resulting model had too narrow a peak in not quite the right place, so we did a fit and got a very nice result:

Rnom            = 7.52275 Ω    (nominal resistance)
Lhi             = 0.000328722 H  (series inductance)

Resonance peak (all three in parallel and the result in series with Rnom and Lhi):
Ls              = 0.00297396 H
Cs              = 0.000386845 F
Rs              = 15.609 Ω

Very nice fit of the resonance peak for the loudspeaker.

The script that we used for doing the fit:

set logscale y
set ylabel "impedance [ohms]"

Rknown = 47.171

j=sqrt(-1)
Zc(f,C) = 1/(j*2*pi*f*C)  # f= frequency [Hz], C=cap [farads]
Zl(f,L) = j*2*pi*f*L

Zpar(z1,z2) = z1*z2/(z1+z2)
divider(Zup,Zdown) = Zdown/(Zup+Zdown)

Ls=1e-3
Cs=1e-3
Rs=15
Rnom=8
Lhi=1e-4
fit abs(Rnom+Zl(x,Lhi)+Zpar(Rs,Zpar(Zl(x,Ls),Zc(x,Cs)))) \
'10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown) \
via Ls,Cs,Rs,Rnom,Lhi

Lhi=abs(Lhi)
fit abs(Rnom+Zl(x,Lhi)+Zpar(Rs,Zpar(Zl(x,Ls),Zc(x,Cs)))) \
'10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown) \
via Ls,Cs,Rs,Rnom,Lhi

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), \
abs(Rnom+Zl(x,Lhi)+Zpar(Rs,Zpar(Zl(x,Ls),Zc(x,Cs))))


Unfortunately, the fit was done with the window zoomed in and no explicit xrange command, and rerunning the script on a fresh gnuplot does not produce this nice result.
We can fix the problem by doing a fit for everything but Lhi in a narrow window, then fitting Lhi:

fit [100:300] abs(Rnom+Zl(x,Lhi)+Zpar(Rs,Zpar(Zl(x,Ls),Zc(x,Cs)))) \
'10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown) \
via Ls,Cs,Rs,Rnom

fit abs(Rnom+Zl(x,Lhi)+Zpar(Rs,Zpar(Zl(x,Ls),Zc(x,Cs)))) \
'10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown) \
via Lhi


We then get the nice plot that the students saw in class:

Fit for the model developed in class.

The model we developed in class for the 10W loudspeakers that the students bought in their parts kits.

That is where we ran out of time in class, and pretty much exactly where I wanted to get to today. When I got home this evening, though, I wanted to explore fitting the higher frequencies better, since the high-frequency fit is terrible. My approach was to add another RLC resonance peak around 25kHz, then try to optimize it. After I was done, I noticed that the standard error on the capacitor for the high-frequency resonance was bigger than 200%, so I tried eliminating it from the model, and I got just about as good a fit with one fewer parameter. The initial fit is poor, but the following script steps you through the successive fits (type return to gnuplot after each pause to go on to the next script):

set logscale x
set xlabel "frequency [Hz]"
unset key

set logscale y
set ylabel "impedance [ohms]"

Rknown = 47.171

j=sqrt(-1)
Zc(f,C) = 1/(j*2*pi*f*C)  # f= frequency [Hz], C=cap [farads]
Zl(f,L) = j*2*pi*f*L

Zpar(z1,z2) = z1*z2/(z1+z2)
divider(Zup,Zdown) = Zdown/(Zup+Zdown)

Rnom=7.7
Lhi=4e-5

Ls=4e-3
Cs=5e-4
Rs=15.5

Lex=2e-4
Rex=30

set xrange [*:*]

model(f) = abs(Rnom+Zl(f,Lhi)+Zpar(Rs,Zpar(Zl(f,Ls),Zc(f,Cs))) + Zpar(Rex,Zl(f,Lex)))

fit [100:300] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Ls,Cs,Rs

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Ls,Cs,Rs"

fit [*:1000] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rnom, Rs

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Rs,Rnom"

fit [1000:*]  log(model(x))\
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Lhi

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Lhi"

fit [1000:*] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rex, Lex

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Rex,Lex"

fit [*:1000] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rnom, Rs, Ls, Cs
plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Rnom,Rs,Ls,Cs"

fit [1000:*]  log(model(x))\
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Lhi
plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Lhi"

fit [100:300] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Ls,Cs,Rs
plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Ls,Cs,Rs, narrow range"

fit [*:1000] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rnom, Rs, Ls, Cs
plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Ls,Cs,Rs,Rnom with wider range"

fit [*:*] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rex,Lex,Lhi

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Rex,Lex,Lhi"

fit [*:*] log(model(x)) \
'10W-loudspeaker-47ohm-more.data' using 1:(log($3/$2*Rknown)) \
via Rnom,Rs,Ls,Cs

plot '10W-loudspeaker-47ohm-more.data' using 1:($3/$2*Rknown), model(x)
pause -1 "fitted Rnom,Rs,Ls,Cs"


The improved model that matches the measured magnitude of the impedance better at high frequencies.

The final fit with a narrow peak for the mechanical resonance of the mass and spring of the loudspeaker cone, around 148Hz, and an extra inductor and resistor to fit the high-frequency behavior.

I do not plan to teach the students about the “Q” of resonant circuits, since the only inductor they will deal with in the class is this loudspeaker, and the only time they need to model it as an inductor is for the class-D amplifier. That lab handout has been difficult for me to get started on—I hope to get it done during the coming long weekend, but I’m beginning to think that I should swap labs 7 and 8, so that the pressure-sensor instrumentation amplifier comes before the class-D power amp. I’ll try to write up both this weekend and see which makes more sense to do first.

1. […] thing I tried in class yesterday (disguised as a gnuplot tutorial) was to build up a model a little at a time to match measured […]

Pingback by Teaching students to build and use models « Gas station without pumps — 2013 February 16 @ 11:45

2. […] I came up with a cute trick for using gnuplot’s fit to optimize the network given the loudspeaker model that I had developed, and wrote that up.  Here is the gnuplot code for designing the Zobel […]

Pingback by All weekend and handouts still not written « Gas station without pumps — 2013 February 18 @ 12:21

3. […] varying as a power of frequency) and it looks like a better fit with fewer parameters than the linear model I had been using.  I’m considering rewriting the class-D amplifier handout to use that model instead.  […]

Pingback by Twentieth day of circuits class | Gas station without pumps — 2013 February 25 @ 17:42

4. […] Seventeenth day of circuits class: inductors and gnuplot tutorial, I introduced two linear circuit models for the JAMO 30466/30462 loudspeakers that we’re […]

Pingback by Better model for loudspeaker | Gas station without pumps — 2013 February 26 @ 11:35

5. […] complicated loudspeaker model. I did decide to switch from the linear model I had been using to a model with a frequency-dependent inductor, and I updated and released the handout for the […]

Pingback by Twenty-first day of circuits class | Gas station without pumps — 2013 February 28 @ 20:53

Create a free website or blog at WordPress.com.