Offline G-code generator for solder-paste dispensing on a 4-axis
GRBL CNC. The host never talks to the machine — it writes a .gcode
file that you stream with
Universal G-code Sender (UGS)
or any compatible sender.
┌────────────┐ ┌───────────┐ ┌───────────┐ ┌───────┐ ┌───────┐
│ Shapes / │ → │ paste-gen │ → │ .gcode │ → │ UGS │ → │ CNC │
│ Gerber pads│ │ GUI │ │ file │ │ │ │ │
└────────────┘ └───────────┘ └───────────┘ └───────┘ └───────┘
- Visual CAD-like workspace. Drop rectangles, circles, and grids,
or import a KiCad paste-layer Gerber (
.gtp/.gbp) — every pad becomes an individually-editable shape. - DOT vs OUTLINE modes. DOT dispenses paste at the shape centre; OUTLINE traces the perimeter with no paste flow (great for dry runs and mechanical calibration).
- Origin picker with offsets. Pick a corner or centre of the layout's bounding box to land at a configurable machine coordinate, so fixed-fixture setups survive a restart.
- Persistent workspace. Machine bed dimensions live in the profile and are drawn as a wireframe in the 3D preview; out-of-bounds shapes raise a warning at generate time.
- Safety-first G-code writer. Pre-flight checks reject impossible Z moves, empty jobs, and sub-zero safe heights; advisory warnings flag out-of-envelope layouts and feedrates above the firmware's ceiling.
- Target-firmware aware. The output is a verified subset of
gcobos/grbl4axis's RS274 dialect (G0 G1 G4 G21 G90 G92 M2+X Y Z E F Ponly). A dialect-contract test suite pins the output down line-by-line so future edits can't silently drift. - Configurable 4th-axis letter. Defaults to
E(gcobos/grbl4axis, Marlin-lineage). Flip toAforfra589/grbl-Mega-5Xor any stock 4-axis GRBL fork.
| Layer | Recommended |
|---|---|
| Controller | Arduino Uno + CNC Shield V3, A-slot rewired to D12/D13 |
| Firmware | gcobos/grbl4axis (GRBL 0.9j, 4-axis Uno fork) |
| Streamer | Universal G-code Sender (Platform or Classic) |
| Host | Windows 10/11 or Linux, Python 3.11+ |
Other firmware (e.g. fra589/grbl-Mega-5X on a Mega 2560) also
works — change the plunger axis letter in the profile editor. Stock
GRBL 1.1 is 3-axis only and will error:21 on every plunger move.
git clone https://github.com/your-fork/cnc-paste-controller.git
cd cnc-paste-controller
python -m venv .venv
# Windows:
.\.venv\Scripts\Activate.ps1
# macOS / Linux:
source .venv/bin/activate
pip install -e ".[dev]"paste-genor directly:
python -m paste_ctrl.mainpytestExpect 133 tests passing, including the test_gcode_dialect.py
contract suite that verifies every emitted word and modal code is
parser-legal for gcobos/grbl4axis.
- Flash the firmware and verify
$$returns$103(E-axis steps/mm). - Install the host software (above) and run
paste-gen. - Open Profile… in the toolbar. Set travel feedrates, syringe inner diameter, workspace dimensions. Save.
- Add shapes from the left panel or Load Gerber… from the toolbar. Pick an origin-corner mode and set an offset if needed.
- Save G-code… from the right panel. Review the header; it
tells you which
$setting must match your firmware. - Stream with UGS: connect, jog to the origin corner, zero XY, touch off Z, prime the plunger, hit Send.
Full step-by-step walk-through: docs/setup_guide.md.
- docs/setup_guide.md — canonical end-to-end setup guide (hardware → firmware → host → first dispense).
- docs/hardware_wiring.md — deeper hardware detail (older doc; firmware section superseded by setup_guide).
- docs/calibration_procedure.md — long-form calibration walk-through.
- docs/configuration_reference.md — every profile field explained.
cnc-paste-controller/
├── src/paste_ctrl/
│ ├── main.py # GUI entry point
│ ├── config/ # profile schema + TOML load/save
│ ├── shapes/ # ShapeMode, RectShape, CircleShape, GridShape, TracePath
│ ├── gerber/ # Gerber pad parser (pygerber wrapper)
│ ├── motion/coordinates.py # shape-space → machine-space transforms
│ ├── toolpath/sequence_builder.py # TSP ordering, DispenseOp, TraceOp
│ ├── gcode/writer.py # the emitter — see its module docstring
│ └── gui/ # main_window, shapes_panel, generate_panel, config_editor
├── tests/ # 133 tests (pytest)
├── profiles/default.toml # shipped profile (edit via Profile… dialog)
└── docs/ # setup_guide, hardware_wiring, calibration, configuration
The app is offline-only as of version 0.3.0 of the G-code writer. Older snapshots of this repo contained hardware-control code (Connect/Home/Start Run buttons, a live jogging panel). All of that has been deleted — use UGS for anything that physically moves the machine.