pprender - render a breadboard wiring diagram from a real KiCad schematic
pprender
[-o FILE] [--kicad-cli CMD]
[--config FILE] [--use-computed]
[--require-config] [--debug] [--quiet]
SCHEMATIC
pprender {--help|--version}
pprender reads a real KiCad schematic (SCHEMATIC, a .kicad_sch file), runs it through auto_layout.py’s own netlist-to-placement engine (the same engine kicad_layout.py’s own KiCad-side schematic generator uses), and draws the result as an SVG breadboard wiring diagram using breadboard_lib.py’s own drawing primitives.
Before drawing anything, pprender runs two real checks against the computed placement: a connectivity check (every net’s own real members must form one genuinely connected path in the layout, not just share a component) and a board-bounds check (every component’s own assigned row range must fit within ROWS_PER_HALF, the real number of holes a breadboard half actually has). If either check finds a real problem, rendering is skipped entirely and the failures are reported on standard output — rendering an invalid placement risks an unhandled crash rather than a clean report (see ResearchJournal.org ’s own 2026-08-14 entry).
Hierarchical schematics (a root sheet referencing one or more real sub-sheet files) are followed automatically, by kicad-cli(1) itself, during netlist export — provided every real sheet file is still physically present alongside the root. A missing sibling sheet file is silently dropped from the exported netlist with no warning (a real, confirmed kicad-cli(1) behavior, not a bug in this program); see ResearchJournal.org ’s own 2026-08-18 TestSchemes entry for the full account.
The real, physical board a circuit is laid out on is resolved in order: an explicit --config file; failing that, $PACKPAY_BREADBOARD_CONFIG ; failing that, a breadboard.conf next to SCHEMATIC; failing that, ./breadboard.conf. If none of these resolves to a real file, a small, single-sector default is used instead (see breadboard_config(5)). Whichever config is resolved (or the default, if none is) is checked directly against the real circuit before rendering: if it is not already adequate, pprender escalates automatically to a computed configuration: the classic board first (1 sector, 5 rows per half, 63 columns), then 2 sectors, then further boards added one at a time (each tried with 1 sector, then 2), and more than 5 rows per half only as the last resort; a configuration the user gives is the base unit and is always tried first — see LibraryReference.org ’s own auto_layout.py section for compute_optimal_config() itself). When a real config file WAS resolved but proved inadequate, the computed alternative is proposed rather than silently substituted, unless --use-computed was given.
-h, --help
Show a usage summary and exit.
-o FILE, --output FILE
Write the rendered SVG to FILE instead of the default, auto_layout_render.svg.
--kicad-cli CMD
The kicad-cli(1) command to invoke for netlist export. Defaults to $KICAD_CLI if that environment variable is set, otherwise plain kicad-cli on $PATH — the same convention this project’s own Makefile already uses, so a single KICAD_CLI= setting covers both make check and this program.
--config
A real breadboard_config(5) config file describing the target board or assembly — highest priority, overriding the default lookup described above.
--use-computed
Use the computed configuration (escalating sector count until the circuit genuinely fits) even when a real config file was resolved and would otherwise have been proposed as an alternative instead.
--require-config
Error out rather than silently falling back to a computed configuration when neither --config nor the default lookup resolves to a real file.
--max-components N
Override this project’s own real, default component-count limit ( breadboard_config.py’s own DEFAULT_MAX_COMPONENTS constant, currently 150) — see that constant’s own docstring for the full, real rationale. Raising it above the real, existing default prints a real, direct warning to standard error, but still proceeds.
--version
Show this project’s own current version (read from VERSION) and exit.
--debug
In addition to the two checks’ own output, print every placed passive’s own real column, row, and placement reason (which net and which already-placed member it attached to, and whether it needed relocating for room — see FutureResearch.org ’s own "row-assignment" item), plus the list of any components that ended up genuinely unplaced.
--quiet
Suppress the two checks’ own explanatory header lines (what each check verifies and why), and the "here’s a configuration that might suit this circuit better" proposal described above. Any real failure found, and the final render result, are still printed — this silences routine narration only, never a real problem.
The jumpers are drawn in the colour that the build instructions name for them (see ppbuild_instructions(1)): ground black, the supply on the rail red, a second supply orange, and every other net a colour of its own. A white wire is drawn with a grey outline so that it shows on the board.
|
0 |
The schematic was loaded, both checks passed, and the SVG was written successfully. | ||
|
1 |
The schematic could not be loaded (missing file, or a kicad-cli(1) failure), the connectivity or board-bounds check found a real problem (rendering skipped), rendering itself failed, or the circuit’s own real component count exceeds whichever --max-components limit is in effect (see above), or the circuit cannot be drawn on the board at all (no free column within reach for a far lead, and the diagram layout cannot help either): a message says so and suggests a larger board. | ||
|
2 |
Invalid command-line usage (e.g. no SCHEMATIC given). |
Render a schematic to the default output file:
pprender power.kicad_sch
Render against a specific, real board or assembly config, rather than whatever the default lookup would resolve to:
pprender --config breadboard1.conf power.kicad_sch
Render to a specific path, with full placement diagnostics, using a downloaded KiCad AppImage rather than a system install:
pprender
--debug -o power_breadboard.svg --kicad-cli \
"/opt/KiCad.AppImage kicad-cli"
power.kicad_sch
PACKPAY_PHYSICAL_ANCHORS
On unless set to 0: a dual-row DIP is drawn where its footprint puts its pins, two in each column (see ppbuild_instructions(1)). Set to 0 for the diagram layout.
PACKPAY_FAR_LEAD_SIDES
On unless set to 0: a far lead is drawn, nearest first on either side, in a column of its half that already holds its own net (see ppbuild_instructions(1)).
PACKPAY_ANCHOR_REFINE
On unless set to 0: the order of the anchors is refined by a local search on the distance between anchors that share a net (see ppbuild_instructions(1)). Set to 0 for the earlier order.
PACKPAY_MIN_ANCHOR_SPACING
The smallest number of columns between two anchors (default 2). On a board too narrow for the default spacing of 6, a tighter spacing is tried, down to this value, before another sector or board is added; a board that fits at the default is untouched. 6 or more switches this off.
PACKPAY_SHRINK_GUARD
On unless set to 0: a tighter spacing is accepted only if it is drawn without refusing it and with no hole collision (a lead on a lead or a wire). Label overlaps do not count.
PACKPAY_PHYSICAL_HEADERS
On unless set to 0: a single-row pin header is drawn as a thin body around one row of holes, with a square at pin 1 (see ppbuild_instructions(1)). Set to 0 for the diagram layout.
A part that stands where its footprint puts its pins (a header, a DIP) occupies the strips of its pins, rail pins included, and a lead of another net is never put in one. A DENSE circuit can leave a far leg no short-free column; then the command says so on the error output, "the physical layout of this circuit cannot be made without shorting two nets", and runs again with PACKPAY_PHYSICAL_ANCHORS=0 set, which lays the circuit out as a diagram (one column per pin). The same happens if two nets are found sharing a strip after the drawing. A circuit with no such part is not affected, and nothing changes when the variable is already 0.
ppnetlist(1), ppbreadboard_config(1), breadboard_config(5), kicad-cli(1), README , FutureResearch.org and ResearchJournal.org in packpay’s own documentation set (see Index.org).
Péter Felecan <pfelecan@gmail.com>, with development assistance from Claude (Anthropic).
Copyright © 2026 Péter Felecan. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.