G-code Calibration Tower
Inject a temp, flow, speed or fan tower into g-code without a slicer plugin
- plan
- gcode_text
- steps_json
- summary
Calibration towers are how you answer "what's the best temperature for this filament" without running a dozen prints: one tall model, a setting that steps up or down every few layers, and you read the result off the finished tower. Slicers have plugins for this, but if your g-code lives inside a ComfyUI graph, MKRGCodeCalibrationTower is the node that injects those stepped commands directly - temperature, flow, speed or fan - at regular layer or Z intervals.
It's the calibration macro lane of the pack's G-code family: post-process the exported g-code, insert the right M104/M221/M220/M106-family command at each step, and let the printer build your tower for you. Same "the g-code is a living document" philosophy as MKRGCodeBedMeshCompensate, aimed at dialing in the machine rather than fixing its geometry.
The inputs that matter
plan(MKR_GCODE_PLAN) - the source plan, used to resolve layer heights. This is what lets the node know the real Z of each layer marker instead of guessing.gcode_text- the exported g-code to inject into, typically straight fromMKRGCodeExport.axis- step by actualz_mmheight or bylayer_index. Z-height is the more robust choice when layer heights vary.target- what to change:temp,flow,speed, orfan.start_value/step_value- the starting value and the per-step delta. The defaults (220, −5) are a classic PLA temp tower: 220°C dropping 5° every step.every(default 5) - how many Z units or layers per step.clamp_min/clamp_max- hard limits so a runaway step count can't set a ludicrous temperature.only_on_change(default true) - skip emitting a command when the value wouldn't actually change, which keeps the g-code clean at the top of the tower.
How it works - and the trap
The node scans the g-code for ; LAYER: markers, looks up each layer's Z in the plan, computes which step you're in, and appends a labeled calibration command right after the marker. That's where the README's note matters: the g-code must be exported with layer comments enabled. The author's docs say it plainly - keep include_comments on in MKRGCodeExport, or the node finds no markers, injects nothing, and warns you. If your summary says "No '; LAYER:' markers found," that's the cause; re-export with comments on.
Outputs: gcode_text (the modified g-code, ready for MKRGCodeExport or a preview node), steps_json (structured list of every injected command with its layer, axis value, and command), and summary.
Installing
Part of MKRShift Nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart, or ComfyUI Manager search "MKRShift_Nodes". Pure Python, no extra deps.
The honest take: for people who generate g-code inside ComfyUI, this is a genuinely useful automation - a slicer plugin's job, done graph-native. For everyone else it's meaningless. It's young and there's no community chatter, so the steps_json output is your verification tool: read it before printing, confirm the injected commands look sane, and print a test tower before you trust a batch. One more note: the author's own docs confirm the intended ordering - generate with comments, inject calibration, then export - so keep that chain intact.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| plan | MKR_GCODE_PLAN | — | |
| gcode_text | STRING | — | |
| axis | COMBO | z_mm | 2 options: z_mm, layer_index |
| target | COMBO | temp | 4 options: temp, flow, speed, fan |
| start_value | FLOAT | 220.0-999–999 | — |
| step_value | FLOAT | -5.0-999–999 | — |
| every | FLOAT | 5.00.1–999 | — |
| clamp_min | FLOAT | 180.0-999–999 | — |
| clamp_max | FLOAT | 260.0-999–999 | — |
| only_on_change | BOOLEAN | true | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| gcode_text | STRING | — |
| steps_json | STRING | — |
| summary | STRING | — |