Skip to content
copperhead.sh
Get started

Examples / TI op amp handbook / Basic amplifiers

Noninverting amplifier

SBOA092B page 53, The Non-Inverting Amplifier: EI on the non-inverting input, RO from the output to the inverting input and RI from there to ground.

E_O / E_I = (R_O + R_I) / R_I = 1 + R_O / R_I
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/noninverting_amplifier.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 names the two resistors and gives them no values, so the program chooses them and records the choice (values): 10 kΩ and 90 kΩ, for a gain of +10. The claim is a parameter, a_v = 10, and one constraint holds it to the parts:

require(equals(self.a_v, total(1 * ratio, over(self.r_out.resistance, self.r_in.resistance))))

out/simulation.txt:

RunMeasuredClaimed
gain, operating point, E_I = 1 V1010 (a_v), holds
bandwidth, gain at 1 kHz1010 (a_v), holds
bandwidth, -3 dB point997.6 kHznot a claim

Here the noise gain is the signal gain, 10, so the 10 MHz op amp closes near 1 MHz. That corner is the op amp’s, not a claim of the handbook.

Terminal window
fang check examples/ti_opamp_handbook/basic_amplifiers/noninverting_amplifier/noninverting_amplifier.py
python examples/regenerate.py ti_opamp_handbook/basic_amplifiers/noninverting_amplifier # needs ngspice
examples/ti_opamp_handbook/basic_amplifiers/noninverting_amplifier/noninverting_amplifier.py
"""The non-inverting amplifier, SBOA092B page 53.
Show 13 more lines
E_O / E_I = (R_O + R_I) / R_I = 1 + R_O / R_I
E_I goes in at the + input. R_O and R_I divide the output down to the -
input, and the loop holds the - input at E_I, so the current E_I / R_I in R_I
is the current in R_O and the output stands E_I R_O / R_I above E_I. The
handbook derives it by letting the open-loop gain go to infinity.
The figure names the two resistors and gives them no values, so `values`
records the pair chosen here: 10 kOhm and 90 kOhm, a gain of +10. The bench
drives E_I with 1 V and reads E_O, then sweeps the frequency: the noise gain
is the signal gain here, 10, so a 10 MHz op amp closes near 1 MHz.
"""
import sys
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 Parameter, System, kOhm, require
from fang.parts import Resistor
from fang.rationale import Chooses, Cites
from fang.simulation import ACSweep, OperatingPoint
from handbook import (
Bench,
Claim,
Ground,
OpAmp,
Run,
Terminal,
equals,
over,
ratio,
total,
)
class NoninvertingAmplifier(System):
"""E_I on the + input; R_O from the output to the - input, R_I from there to ground."""
figure = Cites(
"E_O / E_I = (R_O + R_I) / R_I = 1 + R_O / R_I",
document="SBOA092B, Handbook of Operational Amplifier Applications",
locator="page 53, The Non-Inverting Amplifier",
)
values = Chooses(
"What are R_I and R_O?",
selected="10 kOhm and 90 kOhm, for a gain of +10",
alternatives=[
{
"option": "10 kOhm and 100 kOhm, as in the inverting example",
"reason": "gives 11, a gain nobody reads off at a glance",
},
{
"option": "leave them unknown",
"reason": "a gain nobody can compute is not a claim anything can check",
},
],
rationale=(
"the figure names the resistors and gives no values",
"a decade of gain keeps E_O far inside the swing for a 1 V drive",
),
)
a_v = Parameter("1", default=10 * ratio, description="E_O / E_I")
e_in = Terminal()
e_out = Terminal()
e_in_return = Terminal()
e_out_return = Terminal()
r_in = Resistor(resistance=10 * kOhm)
r_out = Resistor(resistance=90 * kOhm)
amp = OpAmp()
ground = Ground()
def architecture(self):
self.e_in.probe >> self.amp.non_inverting.signal
self.amp.inverting.signal >> self.r_out.p1
self.r_out.p2 >> self.amp.output.signal
self.amp.output.signal >> self.e_out.probe
self.amp.inverting.signal >> self.r_in.p1
self.r_in.p2 >> self.ground.node
self.e_in_return.probe >> self.ground.node
self.e_out_return.probe >> self.ground.node
def constraints(self):
require(
equals(self.a_v, total(1 * ratio, over(self.r_out.resistance, self.r_in.resistance)))
)
BENCH = Bench(
page=53,
title="The Non-Inverting Amplifier",
runs=[
Run(
"gain",
OperatingPoint(),
drive={"e_in": "DC 1"},
measure={"gain": "v({e_out.1}) / v({e_in.1})"},
claims=[Claim("gain", "a_v", within=0.001)],
),
Run(
"bandwidth",
ACSweep(points=20, start="10", stop="10meg"),
drive={"e_in": "DC 0 AC 1"},
measure={
"gain_1k": "find vm({e_out.1}) at=1k",
"f_3db": "when vdb({e_out.1})=17 fall=1",
},
claims=[Claim("gain_1k", "a_v", within=0.001)],
units={"f_3db": "Hz"},
note=(
"The -3 dB point is not a handbook claim: it is the op amp's, "
"10 MHz over a noise gain of 10."
),
),
],
)

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

out/netlist.txt
GND1 Ground -
R1 10 kOhm -
R2 90 kOhm -
TP1 Terminal -
TP2 Terminal -
TP3 Terminal -
TP4 Terminal -
U1 OpAmp -
Net-(GND1-Pad1) GND1.1 R1.2 TP2.1 TP4.1
Net-(R1-Pad1) R1.1 R2.1 U1.IN-
Net-(R2-Pad2) R2.2 TP3.1 U1.OUT
Net-(TP1-Pad1) TP1.1 U1.IN+

Every check that ran, and every one left undecided.

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

What the elaborated graph contains, by entity kind.

out/graph.txt
1 block
8 component
16 connection
1 constraint
1 decision
1 evidence
3 interface
12 pin
12 port
55 total
snapshot sha256:711a679e7230d16e189c92026cff39c5a9cc64137f4a00248d48baa3054fbfa9

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

Terminal window
fang build examples/ti_opamp_handbook/basic_amplifiers/noninverting_amplifier/noninverting_amplifier.py