██████╗ ██████╗██████╗ ██╔══██╗██╔════╝██╔══██╗ ██████╔╝██║ ██████╔╝ ██╔═══╝ ██║ ██╔══██╗ ██║ ╚██████╗██████╔╝ ╚═╝ ╚═════╝╚═════╝
██████╗ ██╗ █████╗ ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗███╗ ██╗██████╗ ██╔══██╗██║ ██╔══██╗╚██╗ ██╔╝██╔════╝ ██╔══██╗██╔═══██╗██║ ██║████╗ ██║██╔══██╗ ██████╔╝██║ ███████║ ╚████╔╝ ██║ ███╗██████╔╝██║ ██║██║ ██║██╔██╗ ██║██║ ██║ ██╔═══╝ ██║ ██╔══██║ ╚██╔╝ ██║ ██║██╔══██╗██║ ██║██║ ██║██║╚██╗██║██║ ██║ ██║ ███████╗██║ ██║ ██║ ╚██████╔╝██║ ██║╚██████╔╝╚██████╔╝██║ ╚████║██████╔╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝
🎯 A complete 230 VAC → 5 V / 500 mA isolated-flyback power supply whose entire KiCad project — schematic, PCB, DRC rules, and BOM — is code-generated from a single Python file and machine-checked for 6 mm mains isolation, without ever opening KiCad.
🪫 Hand-drawing a mains power supply in a schematic editor is slow, and on an off-line SMPS the dangerous mistakes are the quiet ones — a primary-to-secondary gap that's a millimetre too small. Here the netlist, the board placement, and the 6 mm reinforced-isolation barrier all come from one authoritative
design.py, and a validator proves the isolation and connectivity every build.
This is a non-earth-referenced off-line SMPS. The entire primary side is at lethal mains potential whenever it is plugged in.
- The primary side sits at ≈325 VDC on the bulk caps (up to ~375 V at 265 VAC).
- Bench-test only through an isolation transformer. Do not probe the primary side powered.
- Keep the board fully enclosed in any final product.
- Bulk caps hold charge after unplug — R3 bleeds them in a few seconds; verify with a meter before touching.
- Primary↔secondary isolation is ≥ 6 mm (reinforced, IEC 62368-1) and enforced on DRC by
hardware/psu_5v_flyback.kicad_dru.
This design is shared for education and reference. Building and operating mains hardware is done at your own risk — see the warranty disclaimer.
.
├── tools/ Python generators + validator (the real source)
│ ├── design.py ★ single source of truth — 37 parts, 22 nets, placement
│ ├── gen_sch.py → hardware/psu_5v_flyback.kicad_sch
│ ├── gen_pcb.py → hardware/psu_5v_flyback.kicad_pcb
│ ├── gen_project.py → .kicad_pro (net classes) + .kicad_dru (≥6 mm isolation rule)
│ ├── gen_bom.py → hardware/bom.csv
│ └── validate.py 7 structural checks — runs without KiCad
├── hardware/ ⚙ GENERATED KiCad 6 project (open in KiCad 7/8/9)
│ ├── psu_5v_flyback.kicad_sch / .kicad_pcb / .kicad_pro / .kicad_dru
│ └── bom.csv
├── docs/
│ ├── specs/2026-07-07-230vac-5v-flyback-psu-design.md full engineering rationale
│ └── renders/ schematic.png · pcb_layout.png · KiCad-computed netlist
├── datasheets/ vendor PDFs — git-ignored (copyright); see datasheets/README.md
├── build.sh regenerate the whole project, then validate
└── requirements.txt kiutils==1.4.8
| Path | What it is | Tracked? |
|---|---|---|
tools/*.py |
Design definition, generators, validator | ✅ source |
hardware/*.kicad_*, bom.csv |
KiCad project | ✅ generated from tools/design.py |
docs/specs, docs/renders |
Rationale + exported images/netlist | ✅ |
datasheets/*.pdf |
Third-party vendor datasheets | 🚫 git-ignored — get them here |
venv/, __pycache__/, *-backups/, *.kicad_prl |
Local env, caches, KiCad per-user state | 🚫 git-ignored |
Everything in
hardware/is a build artifact. Never hand-edit it — changetools/design.pyand re-run./build.sh.
design.py holds every component (ref, value, MPN, footprint, pin→net map, board position) as
plain data. Each generator consumes that one structure, so the schematic, PCB, and BOM can never
disagree — the netlist is correct by construction.
| Tool | Emits | How it works |
|---|---|---|
design.py |
(imported by all) | 37 components, 22 nets, and a deterministic left→right placement (primary left of the barrier, secondary right, T1/U3/C11 bridging). |
gen_sch.py |
*.kicad_sch |
Places each part as a box symbol and drops a global net label exactly on every pin tip — KiCad connects by name, so there is no fragile inter-symbol wiring. |
gen_pcb.py |
*.kicad_pcb |
Stamps each pad with its net, adds the board outline, milled barrier slots + hazard silkscreen, and primary/secondary ground pours on both layers. |
gen_project.py |
*.kicad_pro, *.kicad_dru |
Assigns Primary/Secondary net classes and writes a custom DRC rule requiring ≥ 6 mm primary↔secondary clearance (loaded automatically by KiCad). |
gen_bom.py |
bom.csv |
Groups identical parts, tagging each line primary/MAINS or secondary. |
validate.py |
(exit 0/1) | The 7 checks below — proves the output without KiCad. |
What validate.py checks (all currently passing):
- Both files parse through
kiutils(⇒ KiCad-loadable). - No single-pin nets.
- A net label sits exactly on every one of the 88 schematic pin tips.
- Every PCB pad net matches
design.py. - Min primary↔secondary copper gap ≥ 6 mm (measured 6.02 mm).
- No footprint courtyards overlap.
- All footprints fit inside the 93 × 48.5 mm board.
Isolated flyback, secondary-side regulated, around the STMicroelectronics VIPer06HN off-line converter with an off-the-shelf Myrra 74001 E16 transformer. Topology adapted from ST app-note AN4410, with added mains protection (fuse + MOV + HV bleeder). Signal flow, left → right:
PRIMARY (mains-referenced, LETHAL) | ISOLATION | SECONDARY (isolated 5 V, touch-safe)
============================================== | >= 6 mm | =========================================
| |
230 VAC --> F1 fuse --> R1 inrush --> BR1 rect --> HVDC ~325 V |
| | T1 |
RV1 MOV surge C1 / C2 bulk, L1 EMI | Myrra | D2 --> C8 --> L3 --> C9/C10 --> J2 (+5 V / GND)
R3 bleeder | 74001 E16 | (Schottky rectifier + LC output filter)
| flyback |
U1 VIPer06HN primary switch | 4 kV | feedback (isolated):
DRAIN=7/8 VDD=2 COMP=5 LIM=R4 | >= 6 mm | R6 / R7 divider --> U2 TS432 (TL431)
RCD clamp D1 + R2 || C3 across T1<->DRAIN | | R8 --> U3 opto LED
aux winding --> D3 --> L2 --> C4/C5 --> VDD | U3 opto | U3 transistor --> COMP (closes the loop)
D4 18 V VDD clamp | C11 Y-cap | C11 2.2 nF Y2 across PGND <-> SGND
- Primary nets (hazardous):
ACL ACL_F ACL_R ACN HVDC HV PGND DRAIN CLAMP AUX VDDF VDD COMP COMPX LIM - Secondary nets (safe):
SEC VO_R VOUT SGND FBMID FBK OPTOA - Bridging the barrier by design:
T1(transformer),U3(optocoupler),C11(Y-cap).
Full rationale — part choices, VDD/turns math, drain-voltage margin, DCM peak current — is in
docs/specs/2026-07-07-230vac-5v-flyback-psu-design.md.
Prerequisites: Python 3.10+ and (to open the board) KiCad 7, 8, or 9.
git clone https://github.com/AkashVarma007/pcb-playground.git
cd pcb-playground
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
./build.sh✅ Verify — the last lines of ./build.sh should read:
ok min primary->secondary copper gap = 6.02 mm (U3.4 <-> U3.1)
...
RESULT: ALL CHECKS PASSED
Then open the board:
# open hardware/psu_5v_flyback.kicad_pro in KiCad (double-click, or:)
kicad hardware/psu_5v_flyback.kicad_pro✅ Verify — the schematic shows 37 parts and the PCB opens with the primary/secondary ground
pours and the !! MAINS - ISOLATION BARRIER !! silkscreen.
To change the circuit, edit tools/design.py — never the KiCad files — then regenerate:
./build.sh # regenerate schematic + pcb + project + bom, then validate
python3 tools/validate.py # (run from tools/) just re-run the 7 checks
python3 tools/design.py # print the full pin-level netlist| Task | Where |
|---|---|
| Add / change a part, pin map, or value | COMPONENTS list in tools/design.py |
| Change board size / placement strategy | compute_placement() in tools/design.py |
| Change the isolation distance or net classes | CREEPAGE_MIN, PRIMARY_NETS, SECONDARY_NETS in design.py; rules in gen_project.py |
| Add a footprint shape | FP_BUILDERS in tools/gen_pcb.py (+ FP_SIZE in design.py) |
| Add a schematic symbol shape | SYM_PINS in tools/gen_sch.py |
The generators are deterministic apart from KiCad element UUIDs, so re-running build.sh always
reproduces an equivalent, validated project.
Honest state of the project:
- ✅ Machine-verified: complete 37-part schematic with full 22-net connectivity; net-assigned PCB with ground pours and a DRC-enforced 6 mm barrier (measured 6.02 mm); all 7 checks pass.
⚠️ Not yet opened in KiCad in this repo's history. KiCad could not be installed in the build environment, so the files were validated structurally (viakiutils), not loaded. Open them and run ERC + DRC before trusting them; report any load error.⚠️ The board is placed but not routed. Ground pours, ratsnest, and the 6 mm rule are in place; mains routing was deliberately not auto-generated blind — finish it in KiCad under DRC.⚠️ Verify two footprints against their datasheets before fab: the Myrra 74001 (E16) pin geometry and the RMB6S/MB6S bridge (MBS) pad layout & pin order — both flagged in the spec.⚠️ Bench-tune the RCD clamp (R2/C3) and loop compensation (R5/C6/C7, C12) on the first prototype; passive values are inherited from AN4410 and the transformer differs slightly.
Released under the MIT License — © 2026 Akash Varma. See LICENSE.
The software is provided "as is", without warranty of any kind. This includes the hardware design: building and operating mains-connected equipment is done entirely at your own risk.
Third-party datasheets are not redistributed here and remain © their manufacturers
(see datasheets/README.md).
Contributions and reports welcome — see CONTRIBUTING.md,
SECURITY.md, and the Code of Conduct.
One design.py in · a validated, isolated mains PSU out.

