Compare commits

..

2 Commits

Author SHA1 Message Date
cpu
e23a8ac222 added export_panel_outlines_gerber.py 2026-06-14 14:26:57 +02:00
cpu
c750849779 clean up 2026-06-14 14:07:32 +02:00
6 changed files with 93 additions and 31 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
output/ gcode/
gerbers/

View File

@@ -2,9 +2,9 @@ TODO: Add table of content
# Exporting gcode for CNC # Exporting gcode for CNC
## pcb2gcode ## pcb2gcode
Use CNC for drilling holes and milling board outlines. You can also use CNC for isolation traces milling. However, the best result will give you MSLA PCB exposure. TODO: Add link to the section Use CNC for drilling holes and milling board outlines. You can also use CNC for isolation traces milling. However, the best result will give you MSLA PCB exposure.
Adapt milling and drilling parameters in `millproject`. Look up [pcb2gcode/wiki](https://github.com/pcb2gcode/pcb2gcode/wiki) for help. Adapt milling and drilling parameters in the config file `millproject`. Look up [pcb2gcode/wiki](https://github.com/pcb2gcode/pcb2gcode/wiki) for help.
```bash ```bash
nano millproject nano millproject
``` ```
@@ -15,14 +15,15 @@ nano millproject
``` ```
Launch the `gSender` program. Launch the `gSender` program.
* Load the `output/gcode/drill.ngc` file for drilling holes. * Load the `gcode/drill.ngc` file for drilling holes.
* Load the `output/gcode/outline.ngc` file for milling the board outlines. * Load the `gcode/outline.ngc` file for milling the board outlines.
* Load the `output/gcode/back.ngc` file if you want to mill the isolation traces. * Load the `gcode/slot_outline.ngc` file for milling the panelized slot outlines.
* Load the `output/gcode/front.ngc` file if you want to mill the isolation traces. * 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 ## 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. 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. 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](../images/spoke_width.png) ![Thermal spoke width](images/spoke_width.png)

View File

@@ -2,8 +2,8 @@
set -euo pipefail set -euo pipefail
GERBERS_DIR="output/gerbers" GERBERS_DIR="gerbers"
GCODE_DIR="output/gcode" GCODE_DIR="gcode"
usage() { usage() {
echo "Usage: $0 <kicad_pcb_file>" echo "Usage: $0 <kicad_pcb_file>"
@@ -11,6 +11,7 @@ usage() {
} }
PCB_FILE="$1" PCB_FILE="$1"
PCB_FILE_PREFIX="$(basename "$PCB_FILE" .kicad_pcb)" # Fix this
mkdir -p "$GERBERS_DIR" mkdir -p "$GERBERS_DIR"
mkdir -p "$GCODE_DIR" mkdir -p "$GCODE_DIR"
@@ -18,20 +19,44 @@ mkdir -p "$GCODE_DIR"
# Export drill, front and back layers as gerber files. # Export drill, front and back layers as gerber files.
echo "Exporting gerbers..." echo "Exporting gerbers..."
kicad-cli pcb export drill -o "$GERBERS_DIR" "$PCB_FILE" kicad-cli pcb export drill -o "$GERBERS_DIR" "$PCB_FILE"
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Front "$PCB_FILE" # kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Front "$PCB_FILE"
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Back "$PCB_FILE" # kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Back "$PCB_FILE"
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Edge.Cuts "$PCB_FILE" kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Edge.Cuts "$PCB_FILE"
# Export outlines of the penelized board i.e. use the layer 'User.Eco1'. echo "Exporting Gcode for drilling and outline routing..."
# echo "Exporting panelized outlines from layer 'User.Eco1'..."
# python3 export_panel_outlines_gerber.py \
# --layers User.Eco1 \
# --output "$GERBERS_DIR" \
# "$PCB_FILE"
# Input layers/filenames and all milling/drilling parameters are taken from the config file: 'millproject'.
echo "Exporting Gcode..."
docker run --rm -i -t \ docker run --rm -i -t \
-u "$(id -u):$(id -g)" \ -u "$(id -u):$(id -g)" \
-v "$(pwd):/data" \ -v "$(pwd):/data" \
ptodorov/pcb2gcode ptodorov/pcb2gcode \
--config millproject \
--output-dir "$GCODE_DIR" \
--drill "$GERBERS_DIR/$PCB_FILE_PREFIX.drl" \
--outline "$GERBERS_DIR/$PCB_FILE_PREFIX-Edge_Cuts.gm1"
# Export outlines of the panelized board i.e. use the layer 'User.Eco1'.
echo "Exporting panelized outline from layer 'User.Eco1'..."
python3 export_panel_outlines_gerber.py \
--layers User.Eco1 \
--output "$GERBERS_DIR" \
"$PCB_FILE"
echo "Exporting Gcode for panelized board's slot routing..."
# Use the 'User-Eco1' layer instead as it contains panelized board's slot outlines only.
docker run --rm -i -t \
-u "$(id -u):$(id -g)" \
-v "$(pwd):/data" \
ptodorov/pcb2gcode \
--config millproject \
--output-dir "$GCODE_DIR" \
--outline "$GERBERS_DIR/$PCB_FILE_PREFIX-User-Eco1.gbr" \
--outline-output "slot_outline.ngc"
# echo "Exporting Gcode for isolation traces routing..."
# docker run --rm -i -t \
# -u "$(id -u):$(id -g)" \
# -v "$(pwd):/data" \
# ptodorov/pcb2gcode \
# --config millproject \
# --output-dir "$GCODE_DIR" \
# --front "$GERBERS_DIR/$PCB_FILE_PREFIX-Front.gtl" \
# --back "$GERBERS_DIR/$PCB_FILE_PREFIX-Back.gbl" \

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env python3
import argparse
import os
import pcbnew
def main():
parser = argparse.ArgumentParser(
description="Export a single PCB layer to a Gerber file using pcbnew."
)
parser.add_argument("input", help="Input .kicad_pcb file")
parser.add_argument("--output", "-o", required=True, help="Output directory")
parser.add_argument("--layers", "-l", required=True,
help="Layer name to export (e.g. User.Eco1)")
args = parser.parse_args()
board = pcbnew.LoadBoard(args.input)
# Resolve layer name to ID
layer_id = board.GetLayerID(args.layers)
if layer_id == -1:
parser.error(f"Unknown layer: {args.layers!r}. "
f"Run with a known layer name (e.g. User.Eco1, Edge.Cuts).")
# Resolve output directory to absolute path so pcbnew doesn't make it
# relative to the board file location
output_dir = os.path.abspath(args.output)
os.makedirs(output_dir, exist_ok=True)
prefix = args.layers.replace(".", "-")
pc = pcbnew.PLOT_CONTROLLER(board)
po = pc.GetPlotOptions()
po.SetOutputDirectory(output_dir)
po.SetPlotFrameRef(False)
pc.SetLayer(layer_id)
pc.OpenPlotfile(prefix, pcbnew.PLOT_FORMAT_GERBER, args.layers)
print(f"Plotting layer {args.layers!r} (id={layer_id}) to {pc.GetPlotFileName()}")
pc.PlotLayer()
pc.ClosePlot()
print("Done.")
if __name__ == "__main__":
main()

BIN
images/spoke_width.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

View File

@@ -1,11 +1,3 @@
front=output/gerbers/Flow_Controller_Panel-Front.gtl
back=output/gerbers/Flow_Controller_Panel-Back.gbl
drill=output/gerbers/Flow_Controller_Panel.drl
outline=output/gerbers/Flow_Controller_Panel-Edge_Cuts.gm1
# Use the 'User-Eco1' layer instead as it contains panelized board's slot outlines only.
#outline=output/gerbers/Flow_Controller_Panel-User-Eco1.gbr
# Generic # Generic
metric=true # use metric units for parameters metric=true # use metric units for parameters
metricoutput=true # use metric units for output metricoutput=true # use metric units for output
@@ -13,7 +5,6 @@ nog64=true # do not set an explicit g64
#nom6=true # do not emit m6 #nom6=true # do not emit m6
zsafe=2 # The height in mm at which the bit can move freely without obstruction zsafe=2 # The height in mm at which the bit can move freely without obstruction
zchange=35 # Tool changing height in mm zchange=35 # Tool changing height in mm
output-dir=output/gcode
# Place a 5x7cm board in the lower right quadrant of the coordinate system # Place a 5x7cm board in the lower right quadrant of the coordinate system
# This will allow you to probe the fixed jaw of the vise for (0,0) on the CNC. # This will allow you to probe the fixed jaw of the vise for (0,0) on the CNC.