Skip to content
copperhead.sh
Get started

Examples / TI op amp handbook / References

Isolated standard cell

SBOA092B page 51, Isolated Standard Cell: a standard cell Eref on the non-inverting input of a follower. The text's point is that a low-impedance meter (it names 20 kΩ per volt) can then read the cell without drawing current from it.

E_O = Eref, and the cell supplies no current
the schematic, drawn by copperhead from the circuit's netlist
The schematic, drawn by copperhead from the circuit's netlist

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/isolated_standard_cell.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, fang's own projection
The interconnect view, fang's own projection

The interconnect view is fang’s own projection. It names the parts as the program does, so it reads against the code below.

The figure gives the cell no value and draws no meter, so the program records two choices: cell, a saturated Weston cell at 1.0183 V, and load, 20 kΩ on the output (a 20 kΩ/V meter on its 1 V range). The parameters are the output (e_out = Eref), the meter’s current (i_load = Eref / 20 kΩ, 50.915 µA) and the cell’s current (i_cell = 0).

out/simulation.txt:

RunMeasuredClaimed
loaded, E_O1.0183 V1.0183 V (e_out), holds
loaded, meter current50.91 µA50.92 µA (i_load), holds
loaded, cell current1e-18 A0 (i_cell) ± 1 nA, holds

The meter’s 51 µA comes from the op amp’s output. Without the follower it would come from the cell. The model’s inputs are 1 TΩ apart and draw no bias current, which is why the cell’s current is 10^-18 A; a real FET-input part draws picoamps, which is why the claim is held to 1 nA.

Terminal window
fang check examples/ti_opamp_handbook/references/isolated_standard_cell/isolated_standard_cell.py
python examples/regenerate.py ti_opamp_handbook/references/isolated_standard_cell # needs ngspice
examples/ti_opamp_handbook/references/isolated_standard_cell/isolated_standard_cell.py
"""The isolated standard cell, SBOA092B page 51.
Show 16 more lines
E_O = Eref, and the cell supplies no current
A standard cell is a voltage reference that is spoiled by drawing current
from it, and the handbook's point is that a follower in front of it lets a
low-impedance meter (it names 20 kOhm per volt) read the cell without loading
it: the meter's current comes from the op amp's output, and the cell sees only
the + input.
The figure draws the cell and gives it no value, and draws no meter, so the
program decides both. `cell` records a saturated Weston cell, 1.0183 V.
`load` puts a 20 kOhm resistor on the output: a 20 kOhm/V meter on its 1 V
range, the load the text warns about. The claims are that the output is Eref
with the load on it, that the load's current (51 uA) comes from the output,
and that the cell's own current stays at zero.
"""
import sys
from decimal import Decimal
from 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 fang.lang import A, Parameter, System, V, kOhm, require, uA
from fang.parts import Resistor
from fang.rationale import Chooses, Cites
from fang.simulation import OperatingPoint
from handbook import Bench, Cell, Claim, Ground, OpAmp, Run, Terminal, equals, over
class IsolatedStandardCell(System):
"""The cell on the + input, the output fed back to the - input, a meter on the output."""
figure = Cites(
"Prevent damage to standard cells induced by drawing current from them "
"with low impedance (20 KOhm / Volt) measuring devices.",
document="SBOA092B, Handbook of Operational Amplifier Applications",
locator="page 51, Isolated Standard Cell",
)
cell = Chooses(
"What is Eref?",
selected="a saturated Weston standard cell, 1.0183 V",
alternatives=[
{
"option": "a 1.2 V bandgap reference",
"reason": (
"the page is about standard cells, whose EMF is spoiled by "
"current; a bandgap has an output stage of its own"
),
},
],
rationale=(
"the figure labels the cell Eref and gives no value",
"the Weston cell is the standard cell the text has in mind",
),
)
load = Chooses(
"What does the output drive?",
selected="20 kOhm to ground: a 20 kOhm/V meter on its 1 V range",
alternatives=[
{
"option": "nothing",
"reason": (
"an unloaded follower says nothing about where the meter's "
"current comes from, which is the point of the circuit"
),
},
],
rationale=(
"the text names 20 kOhm/V measuring devices as what damages the cell",
"the figure draws the output terminals and no meter",
),
)
e_out = Parameter("V", default=1.0183 * V, description="the output, which is Eref")
i_load = Parameter("A", default=Decimal("50.915") * uA, description="what the meter draws")
i_cell = Parameter("A", default=0 * A, description="what the cell supplies")
e_ref = Cell(voltage=1.0183 * V)
amp = OpAmp()
r_load = Resistor(resistance=20 * kOhm)
out = Terminal()
out_return = Terminal()
ground = Ground()
def architecture(self):
self.e_ref.p1 >> self.amp.non_inverting.signal
self.e_ref.p2 >> self.ground.node
self.amp.output.signal >> self.amp.inverting.signal
self.amp.output.signal >> self.out.probe
self.out.probe >> self.r_load.p1
self.r_load.p2 >> self.ground.node
self.out_return.probe >> self.ground.node
def constraints(self):
require(equals(self.e_out, self.e_ref.voltage))
require(equals(self.i_load, over(self.e_out, self.r_load.resistance)))
# The cell's only connection besides ground is the + input, which the
# ideal op amp draws nothing through.
require(equals(self.i_cell, 0 * A))
BENCH = Bench(
page=51,
title="Isolated Standard Cell",
runs=[
Run(
"loaded",
OperatingPoint(),
measure={
"e_out": "v({out.1})",
"i_load": "v({out.1}) / 20e3",
"i_cell": "-i(v1)",
},
claims=[
Claim("e_out", "e_out", within=0.001, unit="V"),
Claim("i_load", "i_load", within=0.001, unit="A"),
Claim(
"i_cell",
"i_cell",
within=1e-9,
absolute=True,
unit="A",
note=(
"Held to 1 nA, absolute. The model's inputs are 1 TOhm "
"apart and draw no bias current, so it measures near "
"zero; a real FET-input part would draw picoamps. "
"Without the follower the meter would draw its 51 uA "
"from the cell."
),
),
],
units={"e_out": "V", "i_load": "A", "i_cell": "A"},
),
],
)

The parts, then the nets and the pads on them.

out/netlist.txt
GND1 Ground -
R1 20 kOhm -
TP1 Terminal -
TP2 Terminal -
U1 OpAmp -
V1 1.0183 V -
Net-(GND1-Pad1) GND1.1 R1.2 TP2.1 V1.-
Net-(R1-Pad1) R1.1 TP1.1 U1.IN- U1.OUT
Net-(U1-PadIN+) U1.IN+ V1.+

Every check that ran, and every one left undecided.

out/checks.txt
3 checks, 0 failed, 0 undecided

What the elaborated graph contains, by entity kind.

out/graph.txt
1 block
6 component
14 connection
3 constraint
2 decision
1 evidence
3 interface
10 pin
10 port
50 total
snapshot sha256:417c3f76b39a5186c91dd50d48b80b612bfaf7aceee4630512281d722bfeeaae

All of it, including the KiCad netlist, is in examples/ti_opamp_handbook/references/isolated_standard_cell/out/. Rebuild it with:

Terminal window
fang build examples/ti_opamp_handbook/references/isolated_standard_cell/isolated_standard_cell.py