Test and measurement circuits for a physics lab bench, built bottom-up from a bootstrap PSU through the tiers laid out in docs/general_purpose_circuit_dependency.md. Spacetime research — experiments aimed at faster-than-light travel, with no fixed commitment to any one specific theory or approach — is the current driving objective and gets its own tier graph in docs/spacetime_circuits_dependency.md, but the general-purpose foundation underneath it — PSU tiers, protection, safety monitoring, signal conditioning, measurement tools — isn't specific to that goal and is meant to be useful on its own.
Each circuit gets its own top-level folder with a SPICE netlist, a
generated schematic, and a breadboard wiring guide. Power supplies are
grouped under power_supplies/; measurement/test tools are grouped under
measurement_tools/; signal-conditioning building blocks (references,
amplifiers) are grouped under signal_conditioning/; timing/waveform
generators are grouped under oscillators/; other circuit categories
(safety monitoring, etc.) get their own top-level folders as they're
built.
Each project can render a schematic.png from its .spice netlist.
schematic.png is not committed (see .gitignore) — it's a build
artifact, regenerated on demand:
# from the repo root
python tools/spice_to_schematic.py oscillators/ne555_astable/ne555_astable.spiceOutput is written as schematic.png in the same directory as the .spice
file. tools/spice_to_schematic.py uses schemdraw to parse SPICE R,
C, V, and D elements and render a schematic image.
Every circuit folder has an ngspice .spice netlist. Run with ngspice -b
to predict voltages and currents before building.
# from the repo root
ngspice -b measurement_tools/fuse_test_voltmeter/fuse_test_voltmeter.spice
ngspice -b measurement_tools/cd4066_switch_tester/cd4066_switch_tester.spice
ngspice -b power_supplies/psu_pico_rail/psu_pico_rail.spice
ngspice -b power_supplies/psu_ultralow_v1/psu_ultralow_v1.spice
ngspice -b power_supplies/psu_low_v2/psu_low_v2.spice
ngspice -b power_supplies/psu_3xaa/psu_3xaa.spice
ngspice -b power_supplies/psu_4xaa/psu_4xaa.spice
ngspice -b power_supplies/psu_medlow_usbc/psu_medlow_usbc.spice
ngspice -b signal_conditioning/voltage_reference_lm358/voltage_reference_lm358.spice
ngspice -b oscillators/ne555_astable/ne555_astable.spiceRun from the repo root. Each netlist prints an operating point at its nominal load, then sweeps the load resistor to show the V/I curve.
oscillators/ne555_astable/ (and any future circuit using a behavioral
macromodel rather than plain R/C/V/D elements) prints gmin/source-
stepping warnings during startup — expected for that kind of model, not a
sign the result is wrong; see that circuit's own README § Simulate for
why.
Printing an operating point documents what a circuit should do; it
doesn't check it. Every circuit folder also has a smoke_test.py that
runs its netlist and asserts against real thresholds: no node exceeding a
part's safe voltage, no resistor dissipating more than its rated wattage
(where the resistor is an actual physical part — some netlists use Rload
purely as a simulated stand-in for whatever gets attached later, which
isn't a smoke risk on its own), and a functional check that the circuit
actually does what it claims (a divider ratio within tolerance, a
buffered reference holding steady under load, a switch reading
unambiguously different when open vs. closed). tools/ngspice_runner.py
holds the shared ngspice-invocation/parsing logic every smoke_test.py
reuses.
# from the repo root
python measurement_tools/cd4066_switch_tester/smoke_test.py
python measurement_tools/fuse_test_voltmeter/smoke_test.py
python power_supplies/psu_low_v2/smoke_test.py
python power_supplies/psu_3xaa/smoke_test.py
python power_supplies/psu_4xaa/smoke_test.py
python power_supplies/psu_medlow_usbc/smoke_test.py
python power_supplies/psu_pico_rail/smoke_test.py
python power_supplies/psu_ultralow_v1/smoke_test.py
python signal_conditioning/voltage_reference_lm358/smoke_test.py
python oscillators/ne555_astable/smoke_test.pyOr run all of them at once with tools/run_all_smoke_tests.py, which
finds every smoke_test.py in the repo so this list doesn't have to be
kept in sync by hand:
# from the repo root
python tools/run_all_smoke_tests.pyExits non-zero on any failed check.
Each of these has been physically assembled and confirmed against its
main.py/smoke_test.py pass criteria on real hardware. Not committed
to a breadboard permanently — once a circuit's bench check passes and
nothing else currently under construction needs its wiring in place, its
parts go back to inventory; the netlist/breadboard.md/smoke_test.py stay
as the record for rebuilding it later, along with a breadboard.jpg
photo of the as-built jig where one was taken (see each circuit's own
README.md § Files).
| Folder | Circuit | Tier | Bench-tested |
|---|---|---|---|
power_supplies/psu_pico_rail/ |
Pico's own onboard 3.3V rail, ~100mA budget | interim bootstrap PSU | 2026-08 |
signal_conditioning/voltage_reference_lm358/ |
LM358 unity-gain buffer holds a resistor-divider reference steady under load | tier1 REF |
2026-08-27 — loaded reading within 0.23% of unloaded (±2% tolerance) |
measurement_tools/cd4066_switch_tester/ |
Pico-driven bring-up jig for one CD4066B analog switch — confirms it passes/blocks before trusting it in a later design | component validation (ahead of tier9 MUX) |
2026-08-28 — switch 1 (I/O A pin 1 / I/O B pin 2 / control pin 13) PASS on all 10 CD4066BCN units; switches 2–4 per chip not yet individually tested |
measurement_tools/fuse_test_voltmeter/ |
Pico ADC probe across a battery→fuse→resistor loop; arm switch (GP15) gates trip/reset detection so battery connect/disconnect isn't misread as a trip | bootstrap / concurrent measurement tool | 2026-08-28 — bench wiring has since diverged and trip detection is currently non-functional (no longer a blocker — polyfuses are now sorted via ammeter_10ohm/ammeter_1ohm below instead); see this circuit's own README § Current bench status for the full detail |
measurement_tools/ammeter_10ohm/ |
Pico reads current (not just voltage) through a polyfuse under test, via a 10Ω shunt + slide-switch shorting jumper | polyfuse validation (bootstrap tier) | 2026-08-30 — all 20 RXEF005 (50mA) polyfuses PASS (trip + reset confirmed per unit) |
measurement_tools/ammeter_1ohm/ |
Same approach as ammeter_10ohm scaled for 500mA: ~1Ω jumper-chain shunt (see resistance_measurement/) + 1N5817 reverse-polarity diode on the high side |
polyfuse validation (psu_low tier) |
2026-08-30 — all 20 RXEF050 (500mA) polyfuses PASS (trip + reset confirmed per unit) |
measurement_tools/resistance_measurement/ |
Voltage-divider jig (known 10Ω reference vs. unknown leg) for measuring a low-value resistance or checking continuity between two nodes | supporting tool for ammeter_1ohm; reused for continuity/troubleshooting checks (e.g. psu_4xaa) |
2026-08-30 — jumper-wire chain measured at ~1.005Ω, stable across repeated readings |
measurement_tools/raw_voltage_probe/ |
Plain averaged-voltage reader at GP26 — no resistance math, no divider assumptions; the calling circuit's own README supplies the target | general-purpose probe, split out of psu_4xaa 2026-09-07 for reuse |
2026-09-07 — confirmed reading ~0V correctly with the psu_4xaa divider unpowered; a non-zero (~2.75V) target reading is still pending that circuit's own validation |
power_supplies/psu_ultralow_v1/ |
Single AA + 50 mA polyfuse | psu_ultralow (bootstrap) |
2026-08-30 — component-level validation complete: RXEF005 polyfuse PASS via ammeter_10ohm/ (all 20 units), AA battery holder ready per docs/inventory.md. The assembled PSU itself has not been separately re-probed as its own demo build (see fuse_test_voltmeter/README.md's test-vs-demo distinction) |
Build order runs top to bottom: the voltmeter has to exist — and its own fuse-free sanity check has to pass — before it's trustworthy for sorting good polyfuses from bad, and a polyfuse has to be sorted good before it belongs in a PSU. See measurement_tools/fuse_test_voltmeter/README.md for the voltmeter self-check → bench-test-the-fuse-batch → demo-in-a-PSU sequence this drives.
| Folder | Circuit | Tier |
|---|---|---|
power_supplies/psu_low_v2/ |
2×AA + Schottky + 500 mA polyfuse | psu_low (RXEF050 polyfuse validated — see ammeter_1ohm/ above — and the wire-stripper blocker is resolved; not yet physically assembled) |
power_supplies/psu_3xaa/ |
3×AA + Schottky + 500 mA polyfuse | psu_system (between psu_low and psu_4xaa) |
power_supplies/psu_4xaa/ |
4×AA + Schottky + 500 mA polyfuse | psu_system (top of the plain-AA-series progression) |
power_supplies/psu_medlow_usbc/ |
5V USB-C + 500 mA polyfuse + bypass cap | psu_medlow |
power_supplies/psu_medlow_lm317/ |
SFE Breadboard Power Supply Kit — LM317 adjustable, 3.3V/5V-selectable | psu_medlow (alternative to psu_medlow_usbc; kit not yet ordered, not yet built — see docs/TODO-arcticoder.md) |
Each of these (except psu_medlow_lm317, an on-order kit with no netlist
of its own — see its own README) has a SPICE netlist, a generated
schematic, a breadboard wiring guide, and a smoke_test.py, but none have
been physically assembled with real components yet. The polyfuses they
depend on are no longer the blocker — both batches passed validation via
ammeter_10ohm/ammeter_1ohm above — so what remains is just the
physical build. Everything else in
docs/general_purpose_circuit_dependency.md /
docs/spacetime_circuits_dependency.md (safety monitoring, most of tiers
1–9) hasn't been worked out to netlist stage at all — folders for those
will show up here as they get one.
measurement_tools/fuse_test_voltmeter/,cd4066_switch_tester/, andsignal_conditioning/voltage_reference_lm358/are the circuits here with Pico firmware (main.py) checked in. For more capable Pico ADC work (filtering, calibration curves, noise characterization), see the siblingpico/repo'smeasurement_tools/gpio_analog_sensing/— that repo isn't limited to one project, so general-purpose Pico infrastructure lives there rather than being duplicated here.- Getting the physical Pico talking to this PC (WSL +
usbipddevice attach, MicroPython firmware, installing/usingmpremote) is documented once in the siblingpico/repo rather than duplicated here — see pico/README.md § Running on real hardware. Needed any time you run one of this repo'smain.pyscripts against real hardware instead of just simulating. - See
docs/orders.mdfor what's actually been ordered/received from AliExpress,docs/parts_reference.mdfor pinouts/specs on those parts, anddocs/inventory.mdfor the master parts/quantities list — shared with the siblingpico/repo, which keeps a one-line pointer back to this file atpico/docs/inventory.mdrather than its own copy (seedocs/kb/repo_docs_conventions.md).
measurement_tools/
fuse_test_voltmeter/ Pico ADC voltmeter, validates polyfuses via USB (built & bench-tested; trip/reset short test still pending)
fuse_test_voltmeter.spice
schematic.png (generated, gitignored)
breadboard.md
breadboard.jpg
main.py
smoke_test.py
README.md
cd4066_switch_tester/ CD4066B analog-switch bring-up jig (built & bench-tested)
cd4066_switch_tester.spice
schematic.png (generated, gitignored)
breadboard.md
breadboard.jpg
main.py
smoke_test.py
README.md
ammeter_10ohm/ 10Ω-shunt current-based polyfuse tester (built & bench-tested)
main.py
breadboard.jpg
README.md
ammeter_1ohm/ ~1Ω-shunt version for 500mA polyfuses (built & bench-tested)
main.py
breadboard.jpg
README.md
resistance_measurement/ voltage-divider jig for measuring an unknown low resistance (built & bench-tested)
main.py
breadboard.jpg
README.md
raw_voltage_probe/ plain averaged-voltage reader at GP26, no divider math (built & bench-tested; reused by psu_4xaa)
main.py
README.md
power_supplies/
psu_pico_rail/ Pico onboard 3.3V rail, ~100mA (interim, built & bench-tested)
psu_pico_rail.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_ultralow_v1/ single AA + 50 mA polyfuse (built & bench-tested — component-level)
psu_ultralow_v1.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_low_v2/ 2xAA + Schottky + 500 mA polyfuse (designed, not built)
psu_low_v2.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_3xaa/ 3xAA + Schottky + 500 mA polyfuse (designed, not built)
psu_3xaa.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_4xaa/ 4xAA + Schottky + 500 mA polyfuse (designed, not built)
psu_4xaa.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_medlow_usbc/ 5V USB-C + 500 mA polyfuse + bypass cap (designed, not built)
psu_medlow_usbc.spice
schematic.png (generated, gitignored)
breadboard.md
smoke_test.py
README.md
psu_medlow_lm317/ SFE breadboard PSU kit, LM317 3.3V/5V-selectable (not yet ordered, not built)
breadboard.md
README.md
signal_conditioning/
voltage_reference_lm358/ LM358 buffered voltage reference (built & bench-tested)
voltage_reference_lm358.spice
schematic.png (generated, gitignored)
breadboard.md
breadboard.jpg
main.py
smoke_test.py
README.md
docs/
history.md design conversation log
general_purpose_circuit_dependency.md general-purpose tier graph (PSU, protection, tiers 1-4/6/9, scope/logic-analyzer tiers M0-M5)
spacetime_circuits_dependency.md spacetime-specific tier graph (tiers 5/7/8)
TODO-arcticoder.md human TODO: single active/blocked/backlog checklist for both graphs above, plus personal action items
TODO-completed.md dated audit trail of TODO-arcticoder.md items once done — moved here, not deleted
inventory.md master component inventory (moved from pico/docs/inventory.md 2026-09-07)
orders.md AliExpress order log (received / on order)
parts_reference.md pinouts & specs for ordered parts without a datasheet on file
manuals/ converted (markitdown) part manuals; source PDFs gitignored
kb/ process notes for future LLM sessions, not end-user docs
tools/
spice_to_schematic.py generate schematic.png from a .spice file
ngspice_runner.py shared ngspice-invocation/parsing helper for smoke_test.py scripts
run_all_smoke_tests.py finds and runs every smoke_test.py in the repo