Files
Flow_Controller/scripts/Readme.md
2026-06-08 00:45:38 +02:00

8.2 KiB
Raw Blame History

Panel

Install kikit

Install kikit:

pipx install --system-site-packages kikit

KiKit Fixture Processor

Processing script for KiKit panelizes PCBs and draws a fixture sketch and positions the whole panel for easy CNC processing.

The script:

  • Draws fixture reference geometry
  • Centres the finished panel inside a predefined fixture frame
  • Adds mechanical alignment pin holes
  • Moves the finished panel to the origin (0, 0)

The resulting output is intended for repeatable CNC manufacturing workflows where drilling, routing, and UV exposure all share the same physical fixture and alignment holes.

Check the kikit panelization examples.


Usage

# Panelize the PCB using the preset defined in `myPreset.json`.
kikit panelize \
    -p myPreset.json \
    ../Flow_Controller.kicad_pcb \
    panel/Flow_Controller_Panel.kicad_pcb

The new panel/Flow_Controller_Panel.kicad_pcb file will contain the panelized PCB with the following feature specified in myPreset.json. E.g.: Grid of 1 x 2 with space 2.1 mm, new mounting holes and fiducials.

    "layout": {
        "type": "grid",
        "rows": 1,
        "cols": 2,
        "hspace": "2.1mm",
        "vspace": "2.1mm"
    }

See all values in default.json

Exporting gcode files from KiCad

Adapt milling and drilling parameters in millproject. Look up pcb2gcode/wiki for help.

nano millproject

Make sure to set mirror-axis in the millproject to half of your board width!!!

Run the export by providing the .kicad_pcb file as a first argument:

# Input layers/filenames and all milling/drilling parameters are taken from the config file: 'millproject'.
docker run --rm -i -t \
    -u "$(id -u):$(id -g)" \
    -v "$(pwd):/data" \
    ptodorov/pcb2gcode

The script will first generate gerber files in the gerbers directory and then generate gcode files in the gcode directory.

Launch the gSender program.

  • Load the gcode/drill.ngc file for drilling holes.
  • Load the gcode/outline.ngc file for milling the board outlines.
  • Load the gcode/back.ngc file if you want to mill the isolation traces.
  • Load the gcode/front.ngc file if you want to mill the isolation traces.

Milling tip: Increase the thermal spoke and trace width

When routing for milling, use the widest traces possible. 1mm, 2mm and wider, the machine doesn't care, but later you won't be soldering leads to small fragile strips of copper. You can use copper pours for routing too.

Set up the entire back side as one big GND pour. Then, increase the thermal spoke width to be larger than 1mm. This avoids small features and gives more room for error if a larger drill is used for the holes.

Thermal spoke width

MSLA PCB Exposure: KiCad → Photon Mono 4

Convert KiCad PCB layers to .pm4n files for direct UV exposure on an Anycubic Photon Mono 4 (9024×5120 px, 17 µm/px).


Files

File Purpose
export.sh Main entry point — exports Gerbers from KiCad, converts to .pm4n
gerber_to_pm4n.py Python converter (Gerber → RLE → pm4n binary surgery)
Dummy.pm4n Template file for your specific printer.

Setup

1. Create the Dummy.pm4n

Open CHITUBOX_Basic slicer, select printer Anycubic Photon Mono 4, slice any tiny STL (a 1×1×0.05 mm box), and save as Dummy.pm4n in the same directory as export.sh.

This file is reused for every job — it carries the correct LCD resolution metadata.

2. Install dependencies

python3 -m venv .venv
source .venv/bin/activate
pip install pygerber Pillow numpy

Or activate the venv once and put source .venv/bin/activate in your shell profile.


Usage

./export.sh [OPTIONS] <path/to/board.kicad_pcb>

Options

Option Default Description
--layers L,L,... Front,F.Mask KiCad layer names to process
--invert L,L,... (none) Layers to invert the image for
--mirror L,L,... (none) Layers to mirror X for
--exposure N 60 Exposure time in seconds
--dummy FILE ./Dummy.pm4n Path to dummy template
--out DIR ./output Output directory
--dpmm N 58.824 Render resolution (native = 17 µm/px)
--pos X,Y centred Board position in mm from top-left

Examples

Typical: top copper, positive-working resist (Bungard standard)

./export.sh \
    --layers Front \
    --invert Front \
    --mirror Front \
    --exposure 60 \
    panel/Flow_Controller_Panel.kicad_pcb

--invert: Bungard presensitized is positive-working — UV removes resist, so the background must be exposed (white) and traces must block UV (dark). The Gerber is positive (copper=white), so inversion is needed.

--mirror: the board sits copper-side-down on the FEP, so the image must be flipped so the pattern reads correctly through the board.

Multiple layers (e.g. copper + soldermask)

./export.sh \
    --layers Front,F.Mask \
    --invert Front,F.Mask \
    --mirror Front,F.Mask \
    --exposure 60 \
    panel/Flow_Controller_Panel.kicad_pcb

Quick test at lower resolution (faster render)

./export.sh --dpmm 30 --layers Front --invert Front --mirror Front panel/Flow_Controller_Panel.kicad_pcb

Using gerber_to_pm4n.py directly

python3 gerber_to_pm4n.py Dummy.pm4n output/gerbers/Flow_Controller_Panel-Front.gbr \
    --invert --mirror --exposure 60

Output structure

output/
├── gerbers/
│   ├── Flow_Controller_Panel-Front.gbr
│   └── Flow_Controller_Panel-F_Mask.gbr
└── pm4n/
    ├── Flow_Controller_Panel-Front.pm4n          ← copy to USB, print on Mono 4
    ├── Flow_Controller_Panel-Front.preview.png   ← visual check before printing
    ├── Flow_Controller_Panel-F_Mask.pm4n
    └── Flow_Controller_Panel-F_Mask.preview.png

Invert and mirror logic

Setting When to use
--invert Positive-working resist (standard Bungard): UV removes resist → background must be white (exposed), traces black (masked)
no --invert Negative-working resist: UV hardens resist → traces must be white
--mirror Board placed copper-side down on FEP (normal for this workflow)
no --mirror Board placed copper-side up

When in doubt: check the .preview.png before printing. Traces should appear dark on a white background for standard Bungard positive-working boards.


Exposure calibration

Start at 60 s and bracket in ±15 s steps. Typical range for Bungard presensitized at 405 nm is 30120 s depending on board age and storage conditions.

A correctly exposed board after development will show:

  • Clear copper traces (resist intact, blue/green tint)
  • Bare copper in etched areas (resist removed, shiny copper)

Troubleshooting

kicad-cli: command not found — add KiCad to PATH:

export PATH="/usr/lib/kicad/bin:$PATH"

Or on Flatpak:

alias kicad-cli='flatpak run --command=kicad-cli org.kicad.KiCad'

Expected Gerber not found — KiCad's layer→filename mapping:

Layer Filename stem
F.Cu Front
B.Cu Back
F.Mask F_Mask
B.Mask B_Mask
F.SilkS F_Silkscreen

Image looks wrong in preview — check invert/mirror flags. Open .preview.png: for positive-working resist, traces = dark, background = white.

UVtools PCB Exposure freezes on per-item invert checkbox — known v6 bug at 46 MP. Use the global invert checkbox at the bottom of the dialog instead, or use this script pipeline entirely.


First print checklist

Open the .pm4n in Chitubox to visually verify before printing. Check the .preview.png — traces should appear black on white background (background = UV exposed = resist removed = etched away; traces = dark = resist kept = copper stays) Start with --exposure 60 and bracket from there — Bungard presensitized at 405nm typically lands between 30120s depending on board vintage and storage.