Examples / TI op amp handbook / Current output
Deflection coil driver
SBOA092B page 82, Deflection Coil Driver: an inverting amplifier (R1 and R0, 10 kΩ each) whose feedback is taken from the top of R3 (10 Ω), with the floating load between the output and R3.
I / E_I = -R0 / (R1 R3) = -100 mA / VoltThe circuit
Section titled “The circuit”The schematic is drawn by copperhead’s
drafting engine from this circuit’s netlist, with KiCad’s own library symbols,
and it opens in KiCad as figure/deflection_coil_driver.kicad_sch.
The op amp is KiCad’s generic one, since the handbook’s are ideal, and each
terminal is a test point named as the program names it. KiCad reads back from
the sheet exactly the connections the circuit has; draw_figures.py refuses to write
one that does not.
The interconnect view is fang’s own projection. It names the parts as the program does, so it reads against the code below.
What the program says
Section titled “What the program says”The loop holds the top of R3 at -E_I R0 / R1, so R3 carries -E_I R0 /
(R1 R3). The load also carries the E_I / R1 that R0 takes from the same
node, so the coil current is -(R0 / (R1 R3) + 1 / R1) E_I = -100.1 mA per
volt, and that is the constraint. The figure draws R_L as a resistor; the
program makes it a coil, 10 mH in series with 5 Ω of winding (coil), whose
80 Hz corner is what a current drive is for.
What the simulation found
Section titled “What the simulation found”| Run | Measured | Claimed |
|---|---|---|
dc, E_I = 1 V | -100.1 mA/V | -100.1 mA/V (i_per_volt) ±0.1%, holds |
sine, 0.5 V peak at 1 kHz, peak to peak | -100.3 mA/V | -100.1 mA/V ±0.5%, holds |
sine, lag of the coil current behind the input | 27 ns | 0 ±1 µs, holds |
A voltage across the same coil at 1 kHz would drive a current lagging by 85 degrees, 236 µs. The loop drives 63 Ω of reactance with 3.4 V and the current keeps up; the 0.2% it gains in amplitude is the loop gain, a few hundred at 1 kHz once the coil divides what comes back.
Where the handbook is off
Section titled “Where the handbook is off”Slightly: -100 mA / Volt is the current through R3. The coil also carries E_I / R1, 0.1 mA per volt more, so the load current is -100.1 mA / Volt.
Running it
Section titled “Running it”fang check examples/ti_opamp_handbook/current_output/deflection_coil_driver/deflection_coil_driver.pypython examples/regenerate.py ti_opamp_handbook/current_output/deflection_coil_driver # needs ngspiceThe whole program
Section titled “The whole program”"""The deflection coil driver, SBOA092B page 82.Show 20 more lines
I / E_I = -R0 / (R1 R3) = -100 mA / Volt
The load floats between the op amp's output and R3 (10 Ohm) to ground, andR0 feeds the voltage across R3 back to the - input, so the loop holds thatvoltage at -E_I R0 / R1 and the current through R3 at -E_I R0 / (R1 R3),whatever the load is. The load also carries what R0 takes from the samenode, E_I / R1, so the load current is
I / E_I = -(R0 / (R1 R3) + 1 / R1) = -100.1 mA / Volt
The page drops the second term, which is a thousandth of the first here.
The load is a coil. The figure draws R_L as a resistor; the program makes itan inductance in series with its winding resistance and records the valuesin `coil`. The point of a current drive into a coil is that the currentfollows the input even where the coil's own L / R would make a voltage-drivencurrent lag, so the bench runs d.c. and then a 1 kHz sine, eleven times thecoil's corner, and measures how far the current lags the input."""
import sysfrom pathlib import Path
# The handbook's shared parts and bench live in the folder above the sections.sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from decimal import Decimal
from fang.lang import Ohm, Parameter, System, UnitLiteral, kOhm, mH, requirefrom fang.parts import Inductor, Resistorfrom fang.rationale import Chooses, Citesfrom fang.simulation import OperatingPoint, Transient
from handbook import ( Bench, Claim, Ground, OpAmp, Run, Terminal, equals, negative, over, product, ratio, total,)
#: A transconductance: the current out per volt in.mA_per_V = UnitLiteral("mA/V")
class DeflectionCoilDriver(System): """An inverting amplifier whose feedback is taken from a current-sense resistor."""
figure = Cites( "I / E_I = -R0 / (R1 R3) = -100 mA / Volt. Load must be 'floating', " "i.e. ungrounded.", document="SBOA092B, Handbook of Operational Amplifier Applications", locator="page 82, Deflection Coil Driver", )
coil = Chooses( "What is the load?", selected="a 10 mH coil with 5 Ohm of winding, as an inductor and a resistor in series", alternatives=[ { "option": "a plain resistor, as drawn", "reason": "a deflection coil is an inductance, and the reason to " "drive one with current is the lag its inductance causes", }, ], rationale=( "the figure names the load R_L and gives no value", "10 mH over 5 Ohm is a 2 ms time constant, an 80 Hz corner, so at " "1 kHz a voltage-driven current would lag by 85 degrees", "at 50 mA and 1 kHz the coil needs 3.2 V, inside the swing", ), )
i_per_volt = Parameter( "mA/V", default=Decimal("-100.1") * mA_per_V, description="coil current per volt: -(R0 / (R1 R3) + 1 / R1)", )
e_in = Terminal() r1 = Resistor(resistance=10 * kOhm) r0 = Resistor(resistance=10 * kOhm) r3 = Resistor(resistance=10 * Ohm) coil_winding = Resistor(resistance=5 * Ohm) coil_inductance = Inductor(inductance=10 * mH) amp = OpAmp() ground = Ground()
def architecture(self): self.e_in.probe >> self.r1.p1 self.r1.p2 >> self.amp.inverting.signal self.amp.inverting.signal >> self.r0.p1 self.amp.non_inverting.signal >> self.ground.node
# The coil floats from the output to the sense node. self.amp.output.signal >> self.coil_winding.p1 self.coil_winding.p2 >> self.coil_inductance.p1 self.coil_inductance.p2 >> self.r3.p1 self.r3.p1 >> self.r0.p2 self.r3.p2 >> self.ground.node
def constraints(self): require( equals( self.i_per_volt, negative( total( over(self.r0.resistance, product(self.r1.resistance, self.r3.resistance)), over(1 * ratio, self.r1.resistance), ) ), ) )
DROPPED = ( "The page prints -100 mA / Volt, the current through R3 alone; the coil " "also carries the E_I / R1 that R0 takes, 0.1 mA per volt more.")
BENCH = Bench( page=82, title="Deflection Coil Driver", runs=[ Run( "dc", OperatingPoint(), drive={"e_in": "DC 1"}, measure={ "i_per_volt": "i(l1) / v({e_in.1})", "e_out": "v({amp.OUT})", }, claims=[Claim("i_per_volt", "i_per_volt", within=0.001, unit="A/V", note=DROPPED)], units={"e_out": "V"}, ), Run( "sine", Transient(stop="5m", step="0.5u"), drive={"e_in": "SIN(0 0.5 1k)"}, measure={ "i_pp": "pp i(l1) from=3m to=5m", "e_pp": "pp v({e_in.1}) from=3m to=5m", "i_per_volt": "-i_pp / e_pp", "t_in": "when v({e_in.1})=0 rise=1 td=3.5m", "t_coil": "when i(l1)=0 fall=1 td=3.5m", "lag": "t_coil - t_in", "out_peak": "max v({amp.OUT}) from=3m to=5m", }, claims=[ Claim( "i_per_volt", "i_per_volt", within=0.005, unit="A/V", note="0.5% rather than 0.1%: at 1 kHz the op amp has 80 dB " "of gain left, and the coil's 63 Ohm of reactance against " "R3 divides what comes back, so the loop is a few hundred " "strong rather than a million", ), Claim( "lag", 0, within=1e-6, absolute=True, unit="s", note="a voltage across the same coil would drive a current " "lagging 85 degrees, 236 us at 1 kHz", ), ], units={"i_pp": "A", "e_pp": "V", "t_in": "s", "t_coil": "s", "out_peak": "V"}, note="0.5 V peak at 1 kHz. The coil current is inverted, so it " "falls through zero as the input rises through it; the lag is " "between the two crossings.", ), ],)The files it writes
Section titled “The files it writes”The parts, then the nets and the pads on them.
GND1 Ground -L1 10 mH -R1 5 Ohm -R2 10 kOhm -R3 10 kOhm -R4 10 Ohm -TP1 Terminal -U1 OpAmp -Net-(GND1-Pad1) GND1.1 R4.2 U1.IN+Net-(L1-Pad1) L1.1 R1.2Net-(L1-Pad2) L1.2 R2.2 R4.1Net-(R1-Pad1) R1.1 U1.OUTNet-(R2-Pad1) R2.1 R3.2 U1.IN-Net-(R3-Pad1) R3.1 TP1.1Every check that ran, and every one left undecided.
1 checks, 0 failed, 0 undecidedWhat the elaborated graph contains, by entity kind.
1 block 8 component 18 connection 1 constraint 1 decision 1 evidence 3 interface 15 pin 15 port 63 totalsnapshot sha256:86d15ad0efc75f7b9a8090d83c25bdf3698cd9a7b5edc6f0feb190f186610fc9All of it, including the KiCad netlist, is in
examples/ti_opamp_handbook/current_output/deflection_coil_driver/out/. Rebuild it with:
fang build examples/ti_opamp_handbook/current_output/deflection_coil_driver/deflection_coil_driver.py