Gcode Support - synthetos/TinyG GitHub Wiki

NOTE: This page describes Gcode supported by TinyG in firmware versions 0.95 and later

See also:

TinyG implements the NIST RS274v3/ngc dialect of Gcode. We try to adhere as closely as possible to the NIST Gcode and LinuxCNC Gcode specifications:

Cheat Sheet

This table summarizes Gcode supported. axes means one or more of X,Y,Z,A,B,C.

Gcode Parameters Command Description
G0 axes Straight traverse Traverse at maximum velocity. At least one axis must be present. Build 449: a G0 with no axis words is accepted and only sets the motion mode.
G1 axes, F Straight feed Feed at feed rate F. At least one axis must be present. Build 449: a G1 with no axis words is accepted and only sets the motion mode.
G2 axes, F, I,J,K or R Clockwise arc feed Arc at feed rate F. Offset mode IJK or radius mode R
G3 axes, F, I,J,K or R Counter clockwise arc feed Arc at feed rate F. Offset mode IJK or radius mode R
G4 P Dwell Pause for P seconds
G10 L2 axes, P Set offset parameters P selects coordinate system 1-6
G10 L20 axes, P Set offsets from current position Build 449. Sets the offsets so that the current position becomes the given axis values
G17 Select XY plane G17, G18 and G19 set the plan in which the G2/G3 arcs are drawn
G18 Select XZ plane
G19 Select YZ plane
G20 Select inches units mode All Gcode from this point on will be interpreted in inches
G21 Select mm units mode All Gcode from this point on will be interpreted in millimeters
G28 axes Go to G28.1 position Optional axes specify an intermediate point
G28.1 Set position for G28 The current machine position is recorded (No parameters are provided)
G28.2 axes Homing Sequence Homes all axes present in command. At least one axis must be specified
G28.3 axes Set Absolute Position Set axis to zero or other value. Use to zero axes that cannot otherwise be homed
G28.4 axes Homing cycle without setting position Build 449. Runs the G28.2 homing sequence but does not set the machine position at the end
G38.2 axes, F Straight probe Build 449. Probe toward the X, Y and/or Z point until the probe input trips. G38.3-G38.5 are not supported
G40 Cancel cutter radius compensation Accepted and ignored (cutter compensation is not supported)
G43.1 axes Set tool length offset Build 450 (edge-next). Axis words set the tool offset; they do not cause a move
G49 Cancel tool length offset Build 450 (edge-next)
G30 axes Go to G30.1 position Optional axes specify an intermediate point
G30.1 Set position for G30 The current machine position is recorded (No parameters are provided)
G53 Select absolute coordinates Non-Modal: Applies only to current block
G54 Select coord system 1 G54 is typically used as the "normal" coordinate system and reflects the machine position
G55 Select coord system 2
G56 Select coord system 3
G57 Select coord system 4
G58 Select coord system 5
G59 Select coord system 6
G61 Exact path mode Continuous motion between Gcode blocks - exact path will be traced - stops only if it must
G61.1 Exact stop mode Motion will stop between each Gcode block
G64 Continuous path mode Sacrifice path following accuracy in order to keep the feed rate up
G80 Cancel motion mode
G90 Set absolute mode
G91 Set incremental mode
G90.1 Arc IJK absolute mode Build 449. Arc centers I, J, K are absolute coordinates
G91.1 Arc IJK incremental mode Build 449. Arc centers I, J, K are offsets from the start point (default)
G92 axes Set origin offsets
G92.1 Reset origin offsets
G92.2 Suspend origin offsets
G92.3 Resume origin offsets
G93 Set inverse feedrate mode
G94 Cancel inverse feedrate mode

Build 449: any other G code, including G95, is rejected with status 131. M48, M49, M50 and M51 are rejected with status 132, and any other unlisted M code also returns 132.

Build 449 (E150): a code with a decimal point runs only if it is one of the listed sub-codes (G28.1-G28.4, G30.1, G38.2, G43.1, G61.1, G90.1, G91.1, G92.1-G92.3, M201.3), written with exactly one significant decimal digit (G92.10 is G92.1; G92.19, G28.01 are not). Any other dotted code is rejected (131 for G, 132 for M) instead of running as its whole number: earlier builds ran G59.1-G59.3 as G59, M3.1 as M3 and M30.1 as M30. A G or M number written with an exponent is also rejected.

Mcode Parameter Command Description
M0 Program stop Build 449: the stop is queued; when it is reached the machine holds (stat 3) and stays there until a ~ cycle start is received.
M1 Optional program stop Optional program stop switch is not implemented so M1 is equivalent to M0. Build 449: M1 stops only when the optional stop switch $os is 1; with $os=0 (the default) M1 does nothing.
M2 Program end
M30 Program end
M60 Program stop Same as M0
M3 S Spindle on - CW S is speed in RPM
M4 S Spindle on - CCW S is speed in RPM

Build 449, spindle and coolant: M3, M4, M5, S, M6 and M7/M8/M9 are queued in the planner with the moves, and the planner brings motion to a stop at each of them (they are not executed on the fly). M3/M4 do not wait for the spindle to reach speed; add a dwell (e.g. G4 P2) after M3/M4 if needed (the $spde spindle dwell setting is reserved and not implemented). S is not range checked when it is programmed; when the spindle is on, S is clamped to $p1csl..$p1csh ($p1wsl..$p1wsh for M4) and the clamped value replaces the programmed S. See PWM output. M5 | | Spindle off | M6 | | Change tool | No operation at this time. Build 449: when reached in the queue, M6 makes the tool selected by T the current tool (tool); nothing else happens. M7 | | Mist coolant on | Note that mist and flood share the same Coolant ON/OFF pin M8 | | Flood coolant on | Note that mist and flood share the same Coolant ON/OFF pin M9 | | All coolant off | Note that mist and flood share the same Coolant ON/OFF pin M114 | | Get current position | Report the current coordinates M115 | | Get Firmware | Report the current firmware, version and capabilities M201.3 | axes | Set axes jerk | Set transient axis jerk rate M400 | | Finish moves | Wait for current moves to finish M105 | | Report ADC input 3 | Build 449. Returns the raw reading of ADC input 3 (ADC3:n in text mode, adc3 in JSON)

Other Parameter Command Description
N line number label gcode block Line numbers are allowed, handled, and may be reported back in status reports. Don't underestimate how useful this is for debugging Gcode files.
() comment gcode comment Gcode comments are supported. They are stripped and ignored, except for messages (below)
; comment alternate comment A semicolon is an alternate way to delimit a comment. This is not Gcode "standard", but is used by Mach and some Reprap codes. (available as of build 378.05)
(msg....) message gcode message Gcode messages are comments that begin with the characters msg (case insensitive). These will be echoed to the operator. Edge-next 450.01: in text mode every message is printed once, on the reply to its own line; earlier builds could drop it (after a status report or a $ query) or print the previous line's message again (E167).

Build 449: the word letters accepted in a block are G, M, T, F, P, S, X, Y, Z, A, B, C, I, J, K, L, R and N. A block with any other word letter (for example D, H, Q, E or U) is rejected with status 131 and none of it is executed; this is an error for that line, not an alarm.

Gcode Reference

Some of the more complicated commands are described here. Much of this is shamelessly cribbed from the LinuxCNC Gcode pages

Move-time limits

A calculated move time must be positive, finite and no greater than 178,000 minutes. This check applies after feed, axis and motor rate limits are combined, including in G94. A move outside this range is refused with status 110 (value out of range) before it is queued. A valid axis-rate setting does not guarantee that every distance at that rate fits the move-time limit.

Coordinate range

Work-coordinate offsets and calculated machine targets must be finite and lie between −1e18 and +1e18, inclusive, in canonical units: millimeters for X, Y and Z, degrees for A, B and C. Targets are checked after unit conversion and coordinate offsets are applied. These are numeric bounds, not machine travel limits; configured soft limits still apply.

An out-of-range offset write or target is refused with status 110 (value out of range). A refused offset write leaves the previous value unchanged. Motion that produces a non-finite plan is also refused rather than publishing that plan.

Motor pulse-rate limit

Moves are slowed when the requested speed would exceed the pulse capacity of a mapped motor. With the 50 kHz pulse timer, the planner limits each motor to 45,000 steps per second, leaving margin for timing and step corrections. The most restrictive motor sets the move time, including when several motors share an axis. This applies to feeds, rapids and inverse-time moves. The programmed F, axis settings and endpoint are not changed; the move can take longer than programmed. Increasing microsteps or reducing travel per revolution can therefore reduce the achievable feed.

G4 dwell duration

G4 P<seconds> accepts a dwell from 0 through 4294 seconds. A negative P is refused with status 163 (P word is negative). A value above 4294 seconds is refused with status 110 and the message dwell maximum 4294 seconds; the dwell is not queued. P must be finite. Split a longer wait into separate supported dwell commands if it is needed.

A dwell can produce a silent interval with no status reports and no acknowledgements for following queued lines until the dwell ends. The dwell's own acknowledgement means it was accepted into the queue; it is not a completion notification. A sender must allow for the programmed P duration, plus any motion ahead of the dwell, rather than treating this silence as a stalled connection.

Keep receive-flow-control limits in force during the wait. Sending more queries or resending unacknowledged lines does not shorten the dwell and can overrun the input queue. Extend the sender's timeout for the scheduled dwell and resume normal reply handling when it completes.

G93 inverse-time duration

In G93 mode, F specifies the inverse of the requested move duration in minutes: duration = 1/F. Supply a positive F on each feed move. The final calculated move time, including axis and motor rate limits, must not exceed 178,000 minutes; a longer finite duration is refused with status 110 (value out of range) before it is queued. Missing or nonpositive inverse-time feed, or a reciprocal that cannot be represented, returns status 142 (feed rate not specified). Return to G94 for ordinary units-per-minute feeds.

Very small arcs

An accepted G2 or G3 arc whose generated chords are all too short to produce a planner move completes without motion. It does not leave the machine waiting in a running cycle. A sub-resolution full circle is therefore not evidence of a physical revolution; choose geometry large enough for the configured machine resolution.

G10 Set Parameters (Offsets)

G10 supports L2 and L20. P must be an integer 0–6; P0 selects the coordinate system currently in use, and P1–P6 select G54–G59. Other P values return status 161. A missing L word returns status 172, and an L other than 2 or 20 returns status 173. G10 L20 sets the offset so that the current position reads as the given axis value.

When motion is idle, changed offsets are saved to EEPROM before the G10 reply is sent. A host waiting for each reply may send the next G10 as soon as that reply arrives; no extra delay is required. During motion, persistence is deferred until motion ends and serial traffic is quiet, so the reply is not a guarantee that the offsets have already been saved. This does not make pipelined settings writes safe.

The resulting G10 L2 or L20 offsets must satisfy the coordinate range. If any requested offset is invalid, status 110 is returned before any of that command's offsets are stored.

G10 L2 sets coordinate offsets directly. Use Pn to select a coordinate system and axis words to set its offsets. For example:

G10 L2 P1 X0 Y0 Z0 A0 B0 C0  - set G54 offsets to zero, making G54 act as persistent absolute coordinates

G28, G28.1, G30, G30.1 Go To Predefined Position

G28 (and G30) will move the machine to the absolute coordinates set in G28.1 (G30.1), optionally through an intermediate point. Movement will occur at the traverse rate (G0 rate). Axes that are not specified are ignored (not moved). The axis value is the intermediate point for that axis.

Build 449: only the intermediate move uses the axis words. The second move always takes all axes to the stored G28.1 (G30.1) position, including axes that were not in the block. The intermediate point is in work coordinates (G90/G91 apply); the stored position is in machine coordinates. G28.1 and G30.1 positions are not saved to EEPROM.

Format is:

G28 X0 Y0 Z0 A0 B0 C0
Gcode Parameters Command Description
G28 axes Go to G28.1 position Goes through intermediate point if axes are present
G28.1 Set position for G28 Axes are not used and are ignored if present
G30 axes Go to G30.1 position Goes through intermediate point if axes are present
G30.1 Set position for G30 Axes are not used and are ignored if present

Example of use:

  • Go to an arbitrary position, e.g. G0 x100 y100
  • Send G28.1 - This will "remember" the absolute position. This position remains constant regardless of what coordinate system is in effect.
  • Then go to a different place, e.g. G0 x50 y50
  • Send G28 - The machine will return to x100 y100

Example:

  • Go back to X0Y0
  • Send G91 G28 Z10 - this will move to x100 y100. The tool will initially lift z by 10 mm (or inches); G91 is used to set relative mode for this command.

G40, G41, G42 Cutter Radius Compensation (not supported)

TinyG does not offset the toolpath by the tool radius. G40 (compensation off) is accepted and ignored, so programs that cancel compensation in their header run normally. G41 and G42 (compensation left and right) are rejected with status 131 like any other unsupported G code, so a program that relies on them stops instead of cutting the wrong path.

This is deliberate, for edge-next (build 450) and later on the ATxmega192A3:

  • CAM output already carries the offset. Fusion, Vectric, Carbide Create and similar posts generate the path for the tool diameter (computer compensation) and emit G40; controller compensation is only needed to trim for tool wear at the machine.
  • It needs lookahead geometry on every line: corner intersections with the next move, offset arcs, entry and exit moves, and detection of inside corners tighter than the tool radius, where a mistake gouges the part.
  • The xmega has no floating-point hardware and dense files already limit the board by how many lines per second it can plan. Compensation would add float work to every line and lower that rate.
  • Without compensation a tool table needs only lengths; tool diameter has no use in the firmware.

Tool length is supported: G43.1 sets the tool length offset directly from axis words (e.g. G43.1 Z12.5) and G49 cancels it. G43 with an H word (offset from a tool table) is not supported; a host can send G43.1 with the length from its own tool library instead. See G43.1, G49 Tool Length Offset.

G43.1, G49 Tool Length Offset

Build 450 (edge-next) is the first release where tool length offset works as described here. Build 449 (edge-0.97) accepted G43.1 and G49, but applied the offset with the opposite sign, also shifted G91 incremental moves, and ignored the rest of the line after G43.1 or G49. Do not rely on tool length offset before build 450.

  • G43.1 sets the offset from its axis words, in the current units, and moves nothing. Any axis can carry an offset, not only Z.
  • A positive offset moves the controlled point away from the work by that amount, as for a longer tool. With Z at 0, G43.1 Z10 makes Z read -10, and a following G0 Z0 raises the spindle 10 mm.
  • A new G43.1 replaces the offset; it does not add to it. Changing from G43.1 Z5 to G43.1 Z7 and moving to the same Z moves 2 mm.
  • The offset applies to absolute moves in work coordinates. G91 incremental distances are not shifted, and G53 moves are in machine coordinates without the offset.
  • G49 cancels the offset; the next move goes to the position without it.
  • The offset stays active through M2 and M30, as in RS274NGC. A reset clears it.
  • G43.1 and G49 on the same line are a modal group conflict (status 133). Other codes on a G43.1 or G49 line still run, but the axis words on a G43.1 line belong to the offset, so that line makes no move even in G0 or G1 mode.

G61, G61.1, G64 Path Control Modes

TinyG supports exact path mode (G61) and exact stop mode (G61.1). G64 is recognized, but is treated as exact path mode. In exact stop mode motion will stop between each Gcode block. In exact path mode the exact path is followed (i.e. corners are not rounded). The velocity at the points joining 2 blocks is controlled to keep the change in direction between the blocks within centripetal acceleration limit set by $JA. Please see here for an explanation.

M2, M30 Program End

program END (M2, M30) performs the following actions:

  • Axis offsets are set to G92.1 CANCEL offsets
  • Set default coordinate system (uses $gco)
  • Selected plane is set to default plane ($gpl)
  • Distance mode is set to MODE_ABSOLUTE (like G90)
  • Feed rate mode is set to UNITS_PER_MINUTE (like G94)
  • The spindle is stopped (like M5)
  • Motion mode is canceled like G80 (not set to G1)
  • Coolant is turned off (like M9)
  • Default INCHES or MM units mode is restored ($gun)
  • The tool length offset (G43.1) is not canceled; it stays active until G49 or a reset

Build 449: M2/M30 does not restore the units mode (G20/G21 stays as it was), and does not change the arc IJK mode (G90.1/G91.1) or the path control mode (G61/G61.1/G64). The distance mode is set to the $gdi default rather than always G90. The spindle and coolant outputs are turned off when the M2/M30 is reached in the queue. A line that contains only M2 or M30 also clears an ALARM; see Alarms.

M114 Get current Position

Reports the current target position.

Build 449: M114 is answered immediately and does not wait for queued moves. While the machine is moving or in a feedhold it reports the actual (runtime) work position; when motion is stopped it reports the Gcode model position, which already includes moves that are queued but have not started. Send M400 first to read the position after the queued moves. Values are work coordinates in the current units with 4 decimals; in JSON mode they are returned as posx ... posc in the response.

Example:

M114

X:100.0000 Y:0.0000 Z:0.0000 A:0.0000 B:0.0000 C:0.0000

M115 Get Firmware, Version and Capabilities

Reports the firmware, version and capabilities as many other controllers do. This allows Gcode generating software connected to an initially unknown controller to automatically detect it and adapt itself accordingly. Gcode generating software can then provide a "Plug-and-Play" experience to the user.

Example:

M115

FIRMWARE_NAME:TinyG, FIRMWARE_URL:https%3A//github.com/synthetos/TinyG, FIRMWARE_VERSION:0.97, FIRMWARE_BUILD:440.21, HARDWARE_PLATFORM:1.00, HARDWARE_VERSION:8.00

Build 449 prints only FIRMWARE_NAME:TinyG, FIRMWARE_VERSION:0.97, FIRMWARE_BUILD:449.01 in text mode, and returns fb and fv in JSON mode.

M201.3 Set jerk

Sets the jerk of one or more axes transiently. Axis jerk rates are given in units per second³ in order to remain compatible to analogous M201 commands on other controllers. The jerk rates are internally converted to TinyG's km per minute³ rate. Note, $xjm, $yjm etc. remain unaffected by the transient setting.

Example:

M201.3 X90000 Z10000

Watch a video of how this is useful for the OpenPnP software:

https://youtu.be/6SBDApObbz0

M400 Wait for current moves to finish

Some Gcode generating application (e.g. OpenPnP) need to interact in real-time with the machine. One example: A camera is moved to a location, then Computer Vision is used. Obviously, the application needs to know when the camera has arrived, before it can take a picture.

Build 449: M400 must be alone on its line (an N line number may precede it); otherwise the line is rejected with status 106. In JSON mode the reply {"r":{"gc":"M400"},"f":[...]} (with tid if the request had one) is sent once motion has completed. If the machine is alarmed while waiting, the reply is sent at once with status 204, 205 or 206.

M400 blocks all further command processing, until the move buffers have drained. The acknowledgement "tinyg ok>" is only reported once this has happened. The application can therefore synchronize itself efficiently with TinyG.

Example:

G1 X100
M400   ; wait for the move to complete
M114   ; only now report the position

Gcode Comments

Build 449:

  • A line that starts with % (for example the % start and end markers many CAM post processors write) is taken by the serial input as a queue flush character. Outside a feedhold it is ignored and discarded, so the line arrives empty; during a feedhold it flushes the queue. See Feedhold and Resume.

  • A ! anywhere in a line, including inside a comment, is taken as a feedhold.

  • A line that starts with / (block delete) is always skipped.

  • Characters other than letters, digits, . and - before the comment are removed before parsing (spaces, +, [, ], #, * ...), so expressions and parameters are not evaluated: X[1+2] is read as X12 and X#1 as X1.

  • Comments start with a '(' char or alternately a semicolon ';'

  • Comments always terminate the block - i.e. leading or embedded comments are not supported

Valid comment cases       Notes:
G0X10                      - command only - no comment
G0X10 (comment text)       - command with comment
G0X10 (comment text        - it's OK to drop the trailing paren
G0X10 ;comment text        - comment delimited by semicolon (firmware build 378.05 and later)
(comment text)             - there is no command on this line
Invalid comment cases     Notes:
G0X10 comment text         - comment with no separator
N10 (comment) G0X10        - embedded comment. G0X10 will be ignored
(comment) G0X10            - leading comment. G0X10 will be ignored
G0X10 #comment             - invalid comment separator
⚠️ **GitHub.com Fallback** ⚠️