Marlin Firmware & G-Code: The Complete Configuration Guide
Marlin is the open-source firmware that runs on the majority of desktop 3D printers, CNC routers, and custom motion platforms in the world โ from Prusa MK4 clones to DIY syringe pump bioprinters. At its core, Marlin is a G-Code interpreter: it receives commands like G1 X50 F1500 and translates them into precise stepper motor pulses, PID-controlled heater outputs, and safety watchdog functions.
Configuring Marlin correctly โ and knowing which G-Code commands interact with which firmware settings โ is the difference between a machine that works reliably and one that under-extrudes, crashes axes, or fires thermal runaway errors in the middle of a critical print. This guide covers the full configuration workflow, calibration procedures, and the G-Code commands that make it all work.
Hardware Context: RAMPS 1.4 + A4988 / TMC2209
The most common Marlin hardware stack โ and the basis for this guide โ is an Arduino Mega 2560 running the RAMPS 1.4 shield with A4988 or TMC2208/2209 stepper drivers. This combination is used in countless DIY 3D printers, CNC machines, and lab automation devices including syringe pumps. The RAMPS board provides 5 stepper driver slots (X, Y, Z, E0, E1), 3 endstop connectors, heated bed/hotend MOSFETs, and fan control.
The firmware's Configuration.h file is where all the permanent settings live. Marlin compiles these settings into the firmware binary that's flashed to the Arduino. Runtime changes (like steps-per-mm adjustments) can be made via G-Code and saved to EEPROM โ but the firmware's compiled values are the fallback defaults.
Steps-per-mm Calibration: The Most Important Setting
Steps-per-mm (steps/mm) tells Marlin how many stepper motor steps correspond to 1 mm of axis movement. Get this wrong and every dimension the machine produces will be scaled incorrectly. The setting depends on three physical factors: your stepper motor's steps-per-revolution (typically 200), your microstepping setting, and your mechanical ratio (belt pitch + pulley tooth count for Cartesian axes, or lead screw pitch for Z and extruder).
Theoretical Calculation
; For a belt-driven axis (GT2 belt, 20-tooth pulley):
; Steps/rev = 200 ร microstepping_factor
; Distance/rev = tooth_count ร belt_pitch = 20 ร 2mm = 40mm
; Steps/mm = Steps/rev รท Distance/rev
; At 16ร microstepping (A4988 with MS1,MS2,MS3 all HIGH):
; Steps/mm = (200 ร 16) / 40 = 80 steps/mm
; For a lead screw Z axis (8mm lead, M5 rod = 8mm/rev):
; Steps/mm = (200 ร 16) / 8 = 400 steps/mm
; For extruder (BMG dual-drive, ~415 steps/mm typical):
; Varies greatly by extruder design โ MUST be empirically calibrated
Empirical Calibration (Always Do This)
Theoretical values are a starting point. Always verify empirically:
- For X/Y/Z: Command a 100mm move. Measure actual distance moved with calipers.
- Calculate corrected steps/mm:
new_steps = current_steps ร (commanded / actual) - For extruder: Mark filament 120mm from the extruder entry. Command
G1 E100 F100. Measure remaining distance to mark. Actual extruded = 120 - remaining. Apply same formula.
; Example: commanded 100mm, measured 97.5mm
; new_steps/mm = 80 ร (100 / 97.5) = 82.05
; Set corrected value at runtime:
M92 X82.05 ; Set X steps/mm
M92 E418.3 ; Set extruder steps/mm
M500 ; Save to EEPROM
M503 ; Verify โ read all EEPROM settings
Microstepping and the A4988 Driver
The A4988 stepper driver divides each full motor step into smaller microsteps using internal DAC circuitry, producing smoother motion and higher resolution. The microstepping level is set by three logic pins: MS1, MS2, MS3 on the RAMPS board. A4988 supports: full (1), 1/2, 1/4, 1/8, and 1/16 step modes.
RAMPS default: All three MS pins are pulled HIGH via resistors, selecting 1/16 microstepping. This is the most common setting and gives 80 steps/mm for GT2/20T Cartesian axes. If you change microstepping via hardware jumpers, you MUST recalculate and update your steps/mm in firmware or via M92.
TMC2208/2209 drivers differ: they use a single UART serial pin for configuration and support 256ร microstepping internally, but interpolate from 16ร externally โ so your steps/mm calculation should still use 16ร as the effective microstepping ratio unless you change the driver's stealthChop configuration.
PID Tuning: Stable Temperatures = Better Prints
Marlin uses PID (Proportional-Integral-Derivative) control to regulate hotend and heated bed temperatures. Poorly tuned PID causes temperature oscillations โ the hotend swings ยฑ5ยฐC around the target โ which directly causes inconsistent extrusion, layer adhesion problems, and under/over-extrusion bands visible on printed walls.
Marlin includes an automatic PID tuning routine triggered by M303:
; Auto-tune hotend PID at 210ยฐC, 8 cycles:
M303 E0 S210 C8
; Output looks like:
; Kp: 22.50 Ki: 1.85 Kd: 68.42
; bias: 101 d: 101 min: 208.72 max: 211.28
; Apply the suggested values:
M301 P22.50 I1.85 D68.42 ; Set hotend PID
M500 ; Save to EEPROM
; Auto-tune heated bed (use E-1):
M303 E-1 S60 C8
M304 P57.12 I11.04 D196.28 ; Set bed PID
M500
โ Important: Run M303 with the hotend at its typical printing temperature and with part cooling fan at its normal speed. PID values change significantly with fan airflow, so tune under realistic conditions.
EEPROM Management
Marlin's EEPROM (Electrically Erasable Programmable Read-Only Memory) stores runtime-adjustable settings that persist across power cycles โ steps/mm, PID values, Z-offset, acceleration limits, and more. Think of it as a small configuration database on the Arduino that overrides the compiled firmware defaults.
M500โ Save current settings to EEPROMM501โ Load settings from EEPROM (undo unsaved changes)M502โ Reset all settings to firmware-compiled defaults (does NOT save โ you must follow with M500 if you want to save the reset)M503โ Report all current settings (extremely useful for debugging)
M503 ; Read all EEPROM settings โ output includes:
; echo: M92 X80.00 Y80.00 Z400.00 E415.00 ; Steps/mm
; echo: M203 X200.00 Y200.00 Z5.00 E25.00 ; Max feed rates
; echo: M201 X500.00 Y500.00 Z100.00 E5000.00 ; Max acceleration
; echo: M301 P22.5 I1.85 D68.42 ; PID hotend
; echo: M851 Z-1.20 ; Z probe offset
Auto Bed Leveling (ABL) with BLTouch / CR Touch
Auto bed leveling probes multiple points on the print bed, builds a mesh of height variations, and compensates for bed warp or tilt during printing by adjusting the Z axis in real time. Marlin supports several ABL modes: 3-point, bilinear mesh, and UBL (Unified Bed Leveling). The G-Code workflow is:
G28 ; Home all axes (required before G29)
G29 ; Run ABL probe routine โ builds mesh
M500 ; Save mesh to EEPROM
; In start script, after G28:
G29 L1 ; Load saved mesh from EEPROM slot 1 (UBL)
; or just G29 ; Re-probe (bilinear mode)
The Z-probe offset (M851 Z-x.xx) is the distance between the probe trigger point and the nozzle tip. This must be measured and set correctly โ it determines how far from the bed the nozzle actually is when the probe triggers. Fine-tuning the baby-step Z offset during the first layer is done with M290 Z-0.05 (move nozzle 0.05mm closer) in real time.
Retraction Tuning
Retraction pulls the filament back into the nozzle during travel moves to prevent oozing strings. The key parameters are retraction distance and speed:
; Set retraction via G-Code (if EEPROM_SETTINGS enabled):
M207 S1.0 F2400 ; Retract 1.0mm at 40mm/s (F in mm/min: 40ร60=2400)
M208 S0.0 F2400 ; Recover (unretract) 0mm extra, same speed
M500 ; Save
For direct-drive extruders: 0.5โ1.5mm retraction distance is typical. For Bowden: 3โ7mm. Too much retraction causes grinding and clogs; too little causes stringing. Use a retraction tower calibration print to dial in the optimal value.
Key Marlin G-Code Commands at a Glance
M92 X Y Z Eโ Set steps/mm for each axisM203 X Y Z Eโ Set maximum feed rates (mm/min)M201 X Y Z Eโ Set maximum acceleration (mm/sยฒ)M204 P Rโ Set print and retract accelerationM205 X Y Z Eโ Set jerk/junction deviation limitsM301 P I Dโ Set hotend PID valuesM304 P I Dโ Set heated bed PID valuesM303 E S Cโ Run auto PID tuningM851 Zโ Set Z probe offsetM290 Zโ Baby-step Z offset (live adjust)M119โ Report endstop statesM114โ Report current positionM112โ Emergency stop (all motors off, heaters off)
Configuring Marlin for a Syringe Pump / Bioprinter
Syringe pumps and bioprinters built on RAMPS 1.4 use the extruder axis (E) to drive a linear actuator (stepper + lead screw) that pushes a syringe plunger. The E-steps/mm must be calculated from the lead screw pitch and transmission ratio, not from an extruder gear. A typical M5 lead screw with 0.8mm pitch at 16ร microstepping gives:
; M5 lead screw: 0.8mm/rev, 200 steps/rev, 16ร microstepping
; Steps/mm = (200 ร 16) / 0.8 = 4000 steps/mm
M92 E4000 ; Set extruder (syringe) steps/mm
M203 E5 ; Limit max E feed rate to 5 mm/min (slow for viscous bio-ink)
M201 E10 ; Low acceleration for smooth extrusion onset
M500 ; Save to EEPROM
; Dispense 2mm of plunger travel (= defined volume based on syringe ID):
G1 E2 F2 ; Move syringe 2mm at 2mm/min
Flow rate synchronization between X/Y motion and E extrusion is managed by the slicer or by custom G-Code. The volumetric flow rate of the bioink depends on the syringe inner diameter โ calibrating E-steps to actual dispensed volume (by measuring bead diameter or collecting dispensed material) is essential for print accuracy.
GCodex