From ShapeOko
Jump to: navigation, search

G-Code (more precisely G and M Code, more formally, RS-274D or other names) is a programming code that dates back circa 1950, and was originally developed to control mechanical machining operations using paper tape.[1]

As noted below, programming constructs are not supported by the most prevalent G-code interpreter among the community. This can be extended by using a pre-processor, e.g., https://github.com/NRSoft/GSharp [2]


  • G0 is rapid move. It moves the machine to the given coordinates, with the expectation that no machining takes place during the move (tool not in contact with the stock). Unless the mode is changed by other G-code commands, the coordinates are absolute: G0 X10 moves to X=10, G0 X10 again does nothing because you're already at X=10. If coordinates for two or more axes are given, the machine moves in a straight line to the specified point. Starting from X=0, Y=0, the command G0 X10 Y10 moves diagonally to X=10, Y=10. Even if the axes have different maximum speeds and accelerations, the machine still moves them in a coordinated fashion, so that the move is linear. Only the axes specified move; the others do not change position.
  • G1 is linear move. It moves the machine to the given coordinates, with the expectation that the tool would be cutting. It's exactly like G0, except it has an extra parameter, F, that gives the feed rate (the speed at which to move). The speed is expressed in units per minute (mm per minute or inches per minute, depending on mode -- default mm/min). So, with the machine at X=0, Y=0, the command G1 X100 Y100 F200 moves it diagonally to X=100, Y=100, a distance of about 141 mm, at 200 mm/min, so it takes about 43 seconds to get there.
  • G2 and G3 are arc moves (clockwise and counter-clockwise), and they're described very well here. I would use only the I J form and not even bother with the R form.[3]

cvoinescu wrote up the following in a post in the thread Re: MakerCAM - Issues with Circles (Google Chrome, Mac):

X, Y, Z, I, J and K are coordinates. They're in millimeters, and it makes no sense to preserve precision beyond one micron. Three decimals are plenty, but if you want four, so be it, as long as your lines are less than 50/70 characters long (so as to comply w/ Grbl's line length limits).

G-code is relatively easy to read. It consists of commands (which start with G, and some with M) followed by parameters. G0 moves as fast as the machine can go and is called "traverse", G1 moves at the speed given by the F parameter and is called "feed", G2 and G3 draw arcs, clockwise and counterclockwise. The expectation is that milling occurs during G1, G2 and G3, but not G0, which is why there's no speed ("feed rate") control for G0. Of the parameters, X, Y and Z are the coordinates to move to (usually absolute, but there's a relative mode too), and, for arcs, I, J and K are the coordinates of the center (usually relative, and K is for modes that are rarely used). If a coordinate does not change during a move, it can be omitted (which is why you see almost no Z parameters). With some commands (G0 to G3 included), you don't need to repeat the command on a new line if it's the same as before: you can supply just the new set of parameters (coordinates, and maybe feed rate), which is why most of your lines are just X, Y, I, J and F. Linear moves would be just X and Y (and/or Z if moving vertically too, and/or F if speed has to change).

G-code is not compiled; the Arduino runs an interpreter which receives it line by line and executes it. It doesn't move right away, then read another line. In order to avoid starting and stopping for each little move, it processes several commands ahead and feeds them into a movement planner, which schedules the moves as fast as it can while making sure that (a) it doesn't exceed the pre-programmed speed, acceleration (and/or jerk) limits of the machine, (b) it doesn't exceed the given feed rates, (c) it keeps the movements coordinated, that is, if several axes move simultaneously, they accelerate and decelerate together so that the resultant movement is a straight line (or an arc), and (d) it can stop at the end of the last command processed so far, while still obeying the same limits. It's fairly tricky to do this, and even trickier to do it on the Arduino Uno, which has only limited processing power. The Uno also generates pulses for every single microstep each motor has to move, each perfectly timed, while also doing what I described above. Be suitably impressed!

You can tell most CAM programs how many decimals to generate. Sometimes that's part of a post-processing step for the G-code. Some G-code senders can do that for you too. Failing that, just read the file and round any number after a letter X, Y, Z, I, J or K to 3-5 decimals (3 should be plenty for mm, 4 should be good for inch coordinates too).

The "AutoCAD to G-code" is what "CAM" is about. You design the part (essentially a shape) in CAD, and then design the manufacturing process for it in CAM. It's not as easy as converting, say, JPG to PNG, which any dumb computer can do. While there are programs that attempt to guess, and maybe even do a good job for simple parts, in most cases you have to tell the CAM program what to do and how to do it for each feature of your part (type of operation, choice of tool, other parameters). The CAM program helps a lot: once you've told it how you'd like it to mill a certain feature, it'll calculate what could be a very complex toolpath for you (the G-code), taking into account the geometry of the part, the geometry of the tool, and the practical limits of your manufacturing process (e.g. you can't mill more than this much material with every pass, you can't plunge more than this much at a time, you have to do a roughing pass stopping slightly short of the final shape followed by a finishing pass with a different tool, and so on). The CAM program will help you visualize the planned movement of the tool and the resulting object. It'll keep track of features and help you optimize the order of operations, and do all sorts of other things to make the process easier. But, ultimately, it's still a blend of design and engineering, with a human involved.


In G-code, each "action" (modal group) should be on a separate line.

Grbl accepts coordinates in various forms ("0", "0." and "0.0000" are all ok), but some CNC machines require a decimal point to follow the number, which is why you'll see things like "0." in G-code. Please note that GRBL is limited in how long of a line it will accept. If your job is previewing correctly, but not running properly, check to see that line lengths are w/in its limits (50 for older versions, 70 for 0.8c dev or later) as discussed here.

For further details, please see Wikipedia:G-code and Grbl: How it works and other thoughts… --- includes a list of “currently supported g-code commands and unsupported commands from grbl gcode.c” --- see entries below for more complete G-Code specifications.

Also: http://www.warrensbrain.com/gcode-to-english-translator.html [4]

Code Structure

Grbl doesn't implement most control structures.

Program Start/End --- this is traditionally indicated by a "%" symbol --- since most controllers ignore anything else on the line it may be abused as a way to insert a comment.

Normally a comment is indicated by parentheses (this is a comment).

Spaces are typically ignored.

See: https://www.cnccookbook.com/g-code-basics-program-format-structure-blocks/ for further details.

Code Overview

The following table lists all of the letter codes for G-code, with the ones most likely to be used bolded.

Sources: Wikipedia:G-code, Smid 2008, Smid 2010, Green et al. 1996.

G-code Meaning Notes Support
A Absolute or incremental position of A axis (rotational axis around X axis)
B Absolute or incremental position of B axis (rotational axis around Y axis)
C Absolute or incremental position of B axis (rotational axis around Z axis)
D Defines diameter or radial offset used for cutter compensation. D is used for depth of cut on lathes. It is used for aperture selection and commands on photoplotters.
E Precision feedrate for threading on lathes Note that this has been extended by most 3D printing firmwares to support Extrusion (the length of material to extrude, or a specified number of steps, depending on the specific implementation).[5]
F Defines feed rate (see below).
G Address for preparatory commands G commands often tell the control what kind of motion is wanted (e.g., rapid positioning, linear feed, circular feed, fixed cycle) or what offset value to use.
H Defines tool length offset Incremental axis corresponding to C axis (e.g., on a turn-mill)
I Defines arc center in X axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles.
J Defines arc center in Y axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles.
K Defines arc center in Z axis for G02 or G03 arc commands. Also used as a parameter within some fixed cycles, equal to L address.
L Fixed cycle loop count Specification of what register to edit using G10
M Miscellaneous function Action code, auxiliary command; descriptions vary. Many M-codes call for machine functions, which is why people often say that the "M" stands for "machine", although it was not intended to.
N Line (block) number in program System parameter number to be changed using G10
O Program name
P Serves as parameter address for various G and M codes With G04, defines dwell time value.
Q Peck increment in canned cycles
R Defines size of arc radius, or defines retract height in milling canned cycles Used for temperatures in most 3D printing firmwares.[6]
S Defines speed, either spindle speed or surface speed depending on mode
T Tool selection
U Incremental axis corresponding to X axis (typically only lathe group A controls) Also defines dwell time on some machines (instead of "P" or "X").
V Incremental axis corresponding to Y axis
W Incremental axis corresponding to Z axis (typically only lathe group A controls)
X Absolute or incremental position of X axis. Also defines dwell time on some machines (instead of "P" or "U").
Y Absolute or incremental position of Y axis
Z Absolute or incremental position of Z axis The main spindle's axis of rotation often determines which axis of a machine tool is labeled as Z.


Comments may be prefaced by a semi-colon (which are terminated at the end of the line), or enclosed w/in parentheses.


Some firmware may have an option for checksumming a line, indicated by the checksum value appearing at the end of a line preceded by an *.

Motion (G)

G-code Meaning Notes Support
G0/G00 Rapid positioning Switch to rapid linear motion mode (seek). Used to get the tool somewhere quickly without cutting --- moves the machine as quickly as possible along each axis --- an axis which needs less movement will finish before the others, so one cannot count on the movement being a straight line. All Grbl versions

Carbide Motion

G1/G01 Linear interpolation Switch to linear motion at the current feed rate. Used to cut a straight line --- the interpreter will determine the acceleration needed along each axis to ensure direct movement from the original to the destination point at no more than the current Feed rate (F see below). All Grbl versions

Carbide Motion

G2/G02 Circular interpolation, clockwise Switch to clockwise arc mode. The interpreter will cut an arc or circle from the current position to the destination using the specified radius (R) or center (IJK location) at the current Feed rate (F see below) in the plane selected by G17/18/19 (see below).



All Grbl versions

Carbide Motion

Notably, arc commands are not supported by many 3D printer-oriented firmwares.

G3/G03 Circular interpolation, counterclockwise Switch to anti-clockwise arc mode. Corollary to G02 above. All Grbl versions

Carbide Motion

G4/G04 Dwell (pause) This should probably be calculated to be only one or two spindle rotations for best efficiency. Dwell time is expressed using a parameter (may be X, U, or P) which determines the time unit (seconds, milliseconds, &c.) P, for seconds, is supported and used by Grbl.[7], typically X and U express the duration in milliseconds. All Grbl versions

Carbide Motion

G10 Set Work Coordinate Origin (and resultant Offsets) Coordinate system origin setting. This setting is persistent and expects the user to follow good practices and not manually move the machine, instead only using jogging commands via the interface or a pendant which works through the control system, or to have and use homing switches. Examples:
  • G10 P1 L20 --- (which is the equivalent of G92 X0 Y0 Z0) for work co-ordinate system G54 (#P1)[8] (#P2--#P6 are G55--G59 respectively) L20 sets the WCS offsets such that the current position becomes what you say in the axis words (X, Y, Z). The offsets depend on the current machine position.[9]
  • G10 Px L2 (by automatically setting the specified axes from the machine position data) to (re)set the persistent work coordinate offsets.[10] L2 sets the WCS offsets with regard to the machine zero. The current machine position does not matter when you use G10 L2.[11]

See Re: Move after Homing to a position for a discussion of this.

(v0.8 or later)
G17 Select the XY plane (for arcs) Use I and J All Grbl versions

Carbide Motion

G18 Select the XZ plane (for arcs) Use I and K All Grbl versions

Carbide Motion

G19 Select the YZ plane (for arcs) Use J and K All Grbl versions

Carbide Motion

G20 After this, units will be in inches Best practice: do this at the start of a program and nowhere else. The usual minimum increment in G20 is one ten-thousandth of an inch (0.0001"). All Grbl versions

Carbide Motion

G21 After this, units will be in mm Best practice: do this at the start of a program and nowhere else. The usual minimum increment in G21 (one thousandth of a millimeter, .001 mm, that is, one micrometre). All Grbl versions

Carbide Motion

G28 Go to Pre-Defined Position Takes an argument of an X Y Z coordinate for the intermediate point that the tool tip will pass through on its way home to machine zero. v0.7 “Incorrectly performed the homing cycle”[12]

Usually used to park the machine.[13]

Reflashing will reset the associated G28.1 destination coordinate.[14]


https://youtu.be/Rd-h0YA9IzQ [15]

(v0.8 or later)

Carbide Motion

G28.1 Set Pre-Defined Position Takes X Y Z addresses which define the intermediate point that the tool tip will pass through on its way home to part zero, not machine zero. (v0.8 or later)
G28.2 Run homing cycle Grbl requires the explicit command $H

Carbide Motion will interpret this and send $H

G30 Go to Pre-Defined Position (Return to secondary home position) Takes a P address specifying which machine zero point is desired, if the machine has several secondary points (P1 to P4). Takes X Y Z addresses which define the intermediate point that the tool tip will pass through on its way home to machine zero. v0.7 “Incorrectly performed the homing cycle”[16]

Usually used to park the machine.[17] c.f., G28 above.

(v0.8 or later)
G30.1 Set Pre-Defined Position Stores the current absolute position. (v0.8 or later)
G38.1 Probe cycle See Touch Plate and G43.1 below. (v0.9 or later)
G38.2 Straight Probe Probe toward workpiece, stop on contact, signal error if failure (v0.9h or later)
G38.3 Probe Probe toward workpiece, stop on contact (v0.9i or later)
G38.4 Probe Probe away from workpiece, stop on loss of contact, signal error if failure (v0.9i or later)
G38.5 Probe Probe away from workpiece, stop on loss of contact (v0.9i or later)
G40 Tool radius comp off This actually is the only mode which Grbl runs in (there's no way to turn on tool radius compensation), please see below. (v0.9i edge or later)

Carbide Motion (Accepted but ignored)

G43.1 Dynamic tool length offset Change subsequent motions by offsetting the Z and/or X offsets stored in the tool table. Does not cause any motion, but will be applied the next time a compensated axis is moved, that axis’s endpoint will be the compensated location. See G38.1 above for a link which discusses using this. From a post by chamnit (Sonny Jeon, Grbl lead developer)[18]:

The general workflow is:

  • Insert your first tool.
  • Move to a fixed probing location to determine the z-location of the tool tip. People often use G38 and G30 commands to move there, and usually use a touch-plate of some kind to touch off the tip of the tool.
  • Run the job until a tool change.
  • Insert the next tool.
  • Move back to the probing location (via G28 or G30) and determine the z-location of the tip of the new tool.
  • Calculate the z-position difference between the first tool and this tool.
  • Send Grbl a G43.1 command with that difference.
  • Run the next part of the job until the next tool change.
  • Rinse, repeat, and always calculate the z-position difference based on the first tool location.

(v0.9h or later)

Carbide Motion (Accepted but ignored)

G49 Cancel tool offset. Cancels tool offset set by G43 or G44 (v0.9h or later)

Carbide Motion (Accepted but ignored)

G53 Absolute mode override Move in Machine Coordinates. Preface to a movement command on the same line which causes the machine to disregard any coordinate system which is in effect. G53 G0 X0 Y0 Z0 will return to the machine home / origin.[19] Useful to move the tool relative to the machine, e.g., for tool changes.[20] All Grbl versions
G54--G59 Work Coordinate Systems Fixture offset 1--6. CF G10 and G92.[21]

Note that G54 is reserved by Carbide Motion, and will be reset by the software.[22]

(v0.8 or later)

Carbide Motion (Accepted but ignored)

G61 Exact path control mode This is the default path mode Grbl run in. (v0.9i build 20150529 or later)
G80 Motion mode cancel Canned cycle All Grbl versions
G90 Switch to absolute distance mode Coordinates are now relative to the origin of the currently active coordinate system, as opposed to the current position. G0 X-10 Y5 will move to the position 10 units to the left and 5 above the origin X0,Y0. cf. G91 below. All Grbl versions

Carbide Motion

G91 Switch to incremental distance mode Coordinates are now relative to the current position, with no consideration for machine origin. G0 X-10 Y5 will move to the position 10 units to the left and 5 above the current position. cf. G90 above. All Grbl versions

Carbide Motion

G91.1 Arc radius mode (offset mode, for certain CAM programs) incremental distance mode for arcs[23] (v0.9i or later)

Carbide Motion

G92 Coordinate offset. Change the current coordinates without moving e.g. "G92 x0 y0 z0" makes the current position a temporary home position. The intent is to allow one to re-use code (say for a part when doing multiples) which has a given origin. The temporary origin can then be cleared and the actual machine origin, set via G10 restored by the command below.[24] All Grbl versions
G92.1 Clear (temporary) Coordinate System Offsets Previously set by G92 (see above). (v0.8 or later)
G93 Set inverse time feed rate mode An F word is interpreted to mean that the move should be completed in (one divided by the F number) minutes. For example, if F is 2, the move should be completed in half a minute All Grbl versions
G94 Set units per minute feed rate mode An F Word is interpreted to mean the controlled point should move at a certain number of units (or degrees) per minute All Grbl versions

Feed Rate (F)

F-code Meaning Notes Support
F Defines feed rate Unit used is that set by G20 or G21 (see above). The Feed setting in the G-Code determines the maximum rate at which the motor can rotate when moving a given distance so as to get up to (but not exceed) the Feed rate and the maximum acceleration limit which is set in Grbl.

It can be on a separate line or on the same line as a G1/G2/G3 command. There's no 'scope of visibility' though, so it will be valid of the following commands, too, until the next Fxx command.[25]

All Grbl versions

Machine Options (M)

M-code Meaning Notes Support
M0 Program Pause and End Stop --- stops the machine so you can change the tool[26]

Carbide Motion will allow one to restart the program.[27]

(v0.8 or later)

Idle fixed in 0.9i[28] Carbide Motion

M1 Sleep (Optional Stop) Machine will only stop at M01 if operator has pushed the optional stop button. (v0.9 or later, may be supported in earlier versions)

Carbide Motion

M2 Program Pause and End M02 was the original program-end code, now considered obsolete, but still supported for backward compatibility. See M30 below. (v0.8 or later)

Carbide Motion

M3 Spindle direction Clockwise --- (re)starts the spindle[29] (spinning clockwise) if the system is wired up to start/stop the spindle. All Grbl versions

Carbide Motion

M4 Spindle direction Counterclockwise. Used to enable laser mode movement in Grbl 1.0 and later.[30] All Grbl versions
M5 Spindle Control Stop spindle rotation --- if the system is wired up to start/stop the spindle. (v0.8 or later)

Carbide Motion

M6 Tool change

Carbide Motion --- interpreted --- moves the carriage to allow a manual tool change and will display the associated comment describing the tool (if available). On the Nomad, once resumed will then measure the tool.[31]

M7 Coolant Control Mist (v0.9 or later supports this as an option which may be enabled at compilation)

Carbide Motion (Accepted but ignored)

bCNC (unsupported)[32]

M8 Coolant Control Flood coolant on. Universal G-code Sender synch at each M8 or M9 command.[33] (v0.8 or later)
M9 Coolant Control All coolant off. Universal G-code Sender synch at each M8 or M9 command.[34]

Carbide Motion (Accepted but ignored)

(v0.8 or later)
M10 Vacuum (also termed Pallet Clamp) On
M11 Vacuum (also termed Pallet Clamp) Off
M30 Program Pause and End End and rewind. Rewinding refers to programs on punched paper tape. Shorter programs would be connected into an endless loop and be terminated by an M2 (see above), while longer programs would of necessity be rewound at their end by the M30 command. On modern machines M2 and M30 may be considered equivalent. One user’s notes on this command. (v0.8 edge or later)

Carbide Motion

Spindle Speed (S)

Set the spindle speed in revolutions per minute (r.p.m.).

Tooling (T)

Tooling commands are not supported by Grbl. Most don't make sense unless one has an automatic tool changer (ATC).

Note that some Communication / Control programs will intercept these and allow on to change tools.

G-code Not supported by Grbl

Please note that unsupported G-code may cause Grbl to behave oddly, for example drifting into a corner.

G-code Meaning Notes
G40 Tool radius comp off This actually is the only mode which Grbl runs in (there's no way to turn on tool radius compensation), so arguably this command should simply be ignored.[35] Bug report on Github

Note this is now supported in Grbl v0.9i[36]

G41 Tool radius compensation left [37]
G64 Constant velocity mode [38]
G81 Canned drilling cycle Try setting the Drilling Method to Spiral instead of Canned Cycle[39]
G83 Deep hole drilling canned cycle A Perl program for post-processing a file which contains such commands is available on github.[40]
G91.1 incremental distance mode for arcs Universal Gcode Sender incorrectly displaying gcode programs[41]

Note this is now supported in Grbl v0.9i[42]

G12 and 13 cut circular pockets to the specified radius and depth, using a helix or spiral motion.


Grbl Specific Commands[43]

Command Meaning Notes
? Current status Displays Grbl's active state and the real-time current position, both in machine coordinates and work coordinates.
$# View gcode parameters Display the stored offsets from machine coordinates for each co-ordinate system G54--G59, G28 and 30 and G92.
$G View gcode parser state Displays all of the active gcode modes that the parser will use when interpreting any incoming command.
$H Run homing cycle
~ Cycle start
! Feed hold Brings the active cycle to a stop via a controlled deceleration, so as not to lose position. Once finished or paused, Grbl will wait until a cycle start command is issued to resume to program.
Ctrl-x Reset Grbl Resets Grbl, but in a controlled way, retaining your machine position.

Using the Work Coordinate Systems

If you have limit switches on your ShapeOko it opens up the world of work coordinate systems.

Note: These instructions are based on Grbl v0.8c and higher. Other control systems should support these functions, but check the documentation. These are standard G codes but implementations may vary. A further consideration is that Carbide Motion reserves G54 for internal use, and won't allow one to normally send some commands.

There are six user-definable work coordinate systems (WCS) available that are selected with the G54-G59 commands (Note that if using Carbide Motion it seems to store position information in G54 and will over-write any user setting). These are modal, meaning that once you select a WCS all following commands will reference that coordinate system until you select a different one. They are also persistent, meaning that they will be stored between resets and power cycles.

You can also reference the absolute machine coordinate system (home position) using the G53 command, but this command must be issued on every line that you want to reference machine zero on. (eg: G0 G53 X0 Y0 will send the tool to machine zero at rapid speed. The next command will reference the previously selected WCS.)

What are work coordinate systems good for? The easiest way to think about it is that it allows you to set multiple 'zero' locations on your machine which are stored in semi-permanent memory and can be recalled after homing the machine.

For instance I have a small vise that is semi-permanently mounted to the end of my work area and the G55 WCS is set so the face of the non-moving jaw of the vice is X zero and a stop I have bolted to the table is Y zero. This means that when I want to use the vise all I have to do is home the machine, select the G55 WCS, pickup Z zero and hit send on my G code file.

I also have several different jigs that I use that are fastened to the table and located by dowel pins. This allows me to swap in a different jig, select the appropriate WCS and get right to work without having to indicate in the zero location.

The first step to using work coordinate systems is to enable homing. On Grbl v0.8c that requires setting $16 and $17 to 1. In Grbl v0.9 the settings are $23 and $24.

You probably also want to set the step idle delay ($7) to 255 so the motors are locked all the time and the machine will not drift or get bumped. In Grbl v0.9 this is the $15 setting.

After you run the homing cycle ($H) your machine absolute zero will be set. The standard location is in the upper right corner, so that all the coordinates will be in negative space, although it doesn't really matter where you zero the machine. I had mine set to the lower left for a while, but when I upgraded to Grbl v0.9b I left it in the default upper right location.

The next bit is important.

From now on you should only move the machine using the jog feature or by entering G code commands. If you move the machine by hand it will not know where it is and you will lose your zero. You can't use a hand wheel to set the Z depth either.

Once you have jogged the machine to your zero location, you can set a WCS by issuing the command: G10 P[1-9] L20 X [offset] Y [offset] Z [offset]

Let me explain that a little bit.

The P[1-9] is used to select the work coordinate system to change. P1 = G54, P2 = G55, etc.

The X, Y and Z are all optional (but you need at least one otherwise there is nothing to set.)

The [offset] is optional (in that it can be '0') but is useful to compensate for the radius of the tool you are picking up your zero with.

For example, my procedure when setting a WCS is as follows:

  1. Chuck up a piece of 1/4" drill rod. I have pre-measured this rod and it is .250" in diameter +/- .0005".
  2. Home the machine.
  3. Jog over past the edge of the work piece or jig that I want to indicate as 'zero' in the X axis.
  4. Lower the Z and jog back to the edge. I sneak up on it until a piece of paper just gets captured between the rod and the edge.
  5. Set the X zero for the selected WCS. The value to enter is 1/2 the diameter of the rod + the thickness of the paper (I usually use .004"). So I would enter 'G10 P1 L20 X-0.129' The value you enter is the distance from zero to where the center of the tool actually is. It can be positive or negative.
  6. Repeat the procedure for the Y axis.

I do it a little differently for the Z axis. You will have to pick up the Z zero every time you change tools (unless you built a tool changer.) The procedure I use for the Z axis is as follows:

  1. Chuck up the first tool I'm going to use.
  2. Move over to a flat area on the work piece that is designated Z zero (although it doesn't have to be Z zero, you can input any offset you like to compensate for material thickness.)
  3. Using the same 1/4" diameter drill rod, jog the Z down until the rod no longer passes under the tool.
  4. Set Z zero in the work coordinates: 'G10 P1 L20 Z0.25'

Note that there are nine settings for the work coordinate systems (P1-9) but only 6 WCS selection commands in the G54-G59 range. How do you select the other three? The last three work coordinate systems are accessed using G59.1, G59.2 and G59.3. This is not currently supported in Grbl and is unlikely to be added. So in Grbl there are only six usable WCS.

What about G92?

G92 changes the current coordinate system to the current tool position (plus any offset you enter.) This offset remains in effect until you use G92 to change it again, or use G92.1 to remove all offsets.

G92 is useful to set a quick zero position for running parts, but I don't use it as a general rule. The main reason is that G92 is not persistent across resets and power cycles so if you have to E-Stop, or your run is interrupted for some reason, you have to re-pickup your zero.

What about G28 and G30?

G28 and G30 are not WCS settings.

G28 and G30 are persistent, stored positions that you can send the machine to with a single command. G28.1 and G30.1 are used to store the current machine position in absolute machine coordinates.

You set the G28 position by moving the machine to the position you wish to set and issuing G28.1. G30 is set the same way, but with G30.1. These commands do not take any values, and in v0.9 and possibly v0.8c of Grbl, passing a value will cause the machine to move.

Once they are set, you can issue the G28 or G30 command and the machine will move all three axis, at rapid speed, to the predefined position. This behavior can be changed w/ using suitable commands in versions of Grbl which support the additional inputs.1

Note: These commands will not raise the Z axis before moving the X and Y so use caution.

You can specify an optional, intermediate position by adding X, Y or Z values to the command.

Important Note: These coordinates are in the current WCS, not absolute machine values.

So if you wanted to raise the Z first, you could say G28 Z1.5 and it would rapid the Z to 1.5 - in the current WCS - and then rapid move X, Y and Z to the saved position.



Simplest workflow is this:

  • First time:
    • Home the machine.
    • Jog to where you want your WCS 0, 0, 0 to be.
    • Say G10 L20 P1 X0 Y0 Z0.
    • GRBL calculates the offsets from machine origin and stores them in non-volatile memory (EEPROM).
  • Every other time:
    • Home the machine. Done.

Tool Length Offsets and Tool Changes




Forum Discussion

List of all G-codes[44]

See also G-Code and M-Code Grand Master List.

G00 ( G00:Rapid positioning )
G01 ( G01:Linear interpolation )
G02 ( G02:CW circular/helical interpolation )
G03 ( G03:CCW circular/helical interpolation )
G04 ( G04:Dwell )
G05 ( G05:Spline definition )
G06 ( G06:Spline interpolation )
G07 ( G07:Imaginary axis designation )
G08 ( G08:Radius mode )
G09 ( G09:Exact stop check )
G10 ( G10:Program parameter input )
G11 ( G11:Program parameter input cancel )
G12 ( G12:Circle Cutting CW )
G13 ( G13:Circle Cutting CCW )
G14 ( G13:Polar coordinate programming, absolute )
G15 ( G15:Polar coordinate programming, relative )
G16 ( G16:Definition of pole point in polar system )
G17 ( G17:X-Y plane selection )
G18 ( G18:X-Z plane selection )
G19 ( G19:Y-Z plane selection )
G20 ( G20:Inch system selection )
G21 ( G21:Milimeter system selection )
G28 ( G28:Return to home )
G30 ( G30:Return to secondard home )
G31 ( G31:Skip function  )
G32 ( G32:Thread cutting )
G33 ( G33:Constant pitch threading )
G34 ( G34:Variable pitch threading )
G40 ( G40:Tool radius comp off )
G41 ( G41:Tool radius compensation left )
G42 ( G42:Tool radius compensation right )
G43 ( G43:Tool offset compensation positive )
G44 ( G44:Tool offset compensation negative )
G45 ( G45:Tool offset compensation negative )
G46 ( G46:Axis offset single decrease )
G47 ( G47:Axis offset double increase )
G48 ( G48:Axis offset double decrease )
G49 ( G49:Tool offset comp cancel )
G50 ( G50:Scaling OFF )
G61 ( G61:Exact stop mode )
G63 ( G63:Tapping mode )
G64 ( G64:Constant velocity mode )
G65 ( G65:Custom macro simple call )
G66 ( G66:Custom macro modal call )
G67 ( G67:Custom macro modal call cancel )
G68 ( G68:Coordinate system rotation ON ) c.f., http://www.cnccookbook.com/CCCNCGCodeG68G69CoordinateRotation.htm http://www.shapeoko.com/forum/viewtopic.php?f=6&t=6692&p=52375
G69 ( G69:Coordinate system rotation OFF )
G70 ( G70:Enter inch mode )
G73 ( G73:High speed drilling canned cycle )
G74 ( G74:Left hand tapping canned cycle )
G76 ( G76:Fine boring canned cycle )
G80 ( G80:Cancel canned cycle )
G81 ( G81:Drilling to final depth canned cycle )
G82 ( G82:Drilling to final depth canned cycle )
G83 ( G83:Deep hole drilling canned cycle )
G84 ( G84:Tapping or thread cutting with balanced chuck canned cycle )
G85 ( G85:Reaming canned cycle )
G86 ( G86:boring canned cycle )
G87 ( G87:Reaming with measuring stop canned cycle )
G88 ( G88:Boring with spindle stop canned cycle )
G89 ( G89:Boring with intermediate stop canned cycle )
G90 ( G90:Absolute prog )
G91 ( G91:Incremental programming )
G92 ( G92:Reposition current point - can be used to zero machine )
G94 ( G94:Inch per minute )
G95 ( G95:Per revolution feed )
G98 ( G98:Set Initial Plane default )

M01 ( M01:Optional Stop )
M02 ( M02:End of program..no rewind )
M03 ( M03:Spindle On )
M04 ( M04:Spindle CCW )
M05 ( M05:Spindle Stop )
M06 ( M06:Tool change )
M07 ( M07: Coolant On )
M08 ( M08:Flood coolant on )
M09 ( M09:Mist Coolant Device Off )
M10 ( M10:(Mach) Digital Pin Off )
M11 ( M10:(Mach) Digital Pin On )
M20 ( M20:(RepRap) List SD Card )
M21 ( M21:(RepRap) Init SD Card )
M22 ( M20:(RepRap) Release SD Card )
M23 ( M22:(RepRap) Select SD File )
M24 ( M24:(RepRap) Start/Resume SD Print )
M25 ( M25:(RepRap) Pause SD Print )
M26 ( M26:enable automatic b-axis clamping  )
M27 ( M27:disable automatic b-axis clamping )
M27 ( M27:disable automatic b-axis clamping )
M28 ( M28:(RepRap) Start SD Write )
M29 ( M29:(RepRap) Stop SD Write )
M30 ( M30:End program...rewind stop )
M42 ( M42:(RepRap) Set output pin )
M47 ( M47:Repeat program from first line )
M48 ( M48:enable speed and feed overrides )
M49 ( M49:Disable speed and feed overrides )
M50 ( M50:(EMC2) Feed Control Override )
M51 ( M51:(EMC2) Spindle Speed Override Control )
M52 ( M52:(EMC2) Adaptive Feed Control )
M53 ( M53:(EMC2) Feed stop control )
M60 ( M60:pallet shuttle and program stop )
M61 ( M61:(EMC2) Set current tool number )
M62 ( M62:(EMC2) turn on digital output synched with motion )
M63 ( M63:(EMC2) Turn off digital output synched with motion )
M64 ( M64:(EMC2) Turn on digital output immediately )
M65 ( M65:(EMC2) Turn off digital output immediately )
M66 ( M66:(EMC2) Input control )
M80 ( M80:(RepRap) Turn on P/S )
M81 ( M81:(RepRap) Turn off P/S )
M82 ( M82:(RepRap) Set E codes Absolute (default) )
M83 ( M83:(RepRap) Set E codes relative while in Absolute Coordinates (G90) mode )
M84 ( M84:(RepRap) Disable steppers until next move )
M85 ( M85:(RepRap) Set inactivity shutdown timer )
M95 ( M95:?? )
M98 ( M98:Call subroutine )
M99 ( M99:Return from subroutine )
M104 ( M104: (RepRap) Set Extruder Target Temp )
M105 ( M105:(RepRap) Read current Temp )
M106 ( M106:(RepRap) Fan On )
M107 ( M107:(RepRap) Fan off )
M109 ( M109:(RepRap) Wait for extruder current temp to reach target temp. )
M114 ( M114:(RepRap) Display current position )
M115 ( M115:(RepRap) Capabilities string )
M140 ( M140:(RepRap) Set bed target temp )
M190 ( M190:(RepRap) Wait for bed current temp to reach target temp )
M201 ( M201:(RepRap)  Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) )
M202 ( M202:(RepRap)  Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) )
F ( F:Feedrate: )
H ( H:Tool length offset index: )
I ( I:X axis offset for arcs: )
J ( J:Y axis offset for arcs: )
K ( K:Z axis offset for arcs: )
O ( O:Subroutine label number: )
P ( P:Line Number: )
Q ( Q:Repititions of subroutine call: )
R ( R:Arc radius: )
S ( S:Spindle Speed: )
T ( T:Tool Number: )
# ( #: Variable Assignment:# )
% ( %: Start or end of program )

G-code examples

G2 - clockwise arc

G2 Xx Yy Ii Jj


  • I and J are relative to the current position, but X and Y may not be (depends which of G90 or G91 modes is selected)
  • (x,y) should be the same distance from (i,j) as the start position is.[45]
    • If (i,j) isn't half way along a straight line from the start position to (x,y), the move will still begin with an arc of a circle (not an ellipse), and it will be followed by a straight line move to (x,y)
  • Definitions Related to Circles[46]

Cutting a full circle


Cutting Threads

Code for for 20 threads per inch:

G0 X0.00 Y0.50 Z0.50
G1 X0.00 Y0.50 Z0.00 F75
G3 X0.00 Y0.50 Z-0.05 I0.00 J-0.50 F125
G3 X0.00 Y0.50 Z-0.10 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.15 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.20 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.25 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.30 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.35 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.40 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.45 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.50 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.55 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.60 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.65 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.70 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.75 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.80 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.85 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.90 I0.00 J-0.50
G3 X0.00 Y0.50 Z-0.95 I0.00 J-0.50
G3 X0.00 Y0.50 Z-1.00 I0.00 J-0.50

Restarting a file

To restart a G-Code file, or edit it and re-send the portion which hasn't yet been cut in the event of a stop: ​

  • open it in a text editor
  • select the pre-amble and copy it to the pasteboard (see below to learn how to identify that)
  • scroll down through the file to the last line cut
  • from there, scroll up until you find a move down from safety height --- put the cursor before it, select everything from that point to the top of the file and paste in the preamble and ensure that there's a new line between the preamble and the move down from safety height
  • review the machine movement to make sure that from the preamble to the first move down it won't hit any clamps --- edit as necessary
  • save under a new name.

Identifying the pre-amble

The preamble will typically include all the setup information:


before the initial move to the origin at safety height:


and the definition of the first tool and the beginning of cutting:

M6 T201
M3 S8333

Post Processors

As you may have discovered by now the G-Code standard is very loose. Controllers (like Grbl, TinyG and others) are free to pick and choose which G-Code commands and features they implement.

One of the gotchas that seems to bite people in the rear is that the standard says that if there is an unsupported feature on a line of G-Code, the controller can discard the entire line. Which means any other G-Code on that line is ignored. This can cause some frustrating and difficult to debug issues.

Most commercial CAM software includes a feature called the "post-processor". The post-processor formats the G-Code to fit a specific controller. Generally you can edit the post-processor settings to create a new configuration to suit your needs. You can usually set the precision of the values output (number of decimal places), the header and footer output in the file, the supported G-Codes and other options.

It can take some tweaking of the settings to generate a good G-Code file.

The primary CAM software that I currently use is CamBam. CamBam has the ability to create new post-processors, so let's walk though the process. It will be similar for other CAM programs, but not identical.

First we need a list of G-Code supported by our controller. Here is the list for Grbl v0.9. More detailed information is located higher on this page.

Here are the instructions for editing post-processors in CamBam.

Many of the settings are handled with macros that are expanded when the G-Code file is generated.

Start out by selecting the "System" tab on the left hand side of the screen. Right-click on "Post Processors" and select "New post processor". Name it "Shapeoko", or anything else you like.

Starting in the (Main) section we can configure what is output for various stages of the program - they are listed in alphabetical order in the dialog box, but I'm going to go through them in the order in which they are used.

First a note on the Header vs. the MOP (Machining Operation) settings: The "Header" settings are output at the start of your G-Code. The "MOP" settings are output before each machining operation (pocket, profile, etc.) and only the differences between the Header and MOP settings are output (Tool number, coordinate system, etc.)

The first thing output is the "Header". This is output at the top of the G-Code file and allows you to insert comments, the date and time the program was created, the list of tools used in the G-Code, the units and any other settings you think are relevent.

Here is an annotated list of what I put in the Header:

{$comment} {$cbfile.name} {$date} {$endcomment} <- a comment with the filename and the date
{$tooltable} <- comments listing of all the tools used - format defined in the Tool Table Item option
{$units} {$distancemode} {$workplane} <- set the units (G20/G21), distance mode (G90/G91) and the workplane (G17/G18/G19)
{$clearance} <- Sends the tool to the Z Clearance plane

You can copy/paste these:

{$comment} {$cbfile.name} {$date} {$endcomment}
{$units} {$distancemode} {$workplane}

Next are the "MOP"s. The list is almost the same as the Header - remember, only values that are different are output:

{$comment} {$mop.name} {$endcomment} <- A comment with the MOP name in it
{$workplane} <- Sets the workplane (G17/G18/G19)
{$mop.header} <- Inserts the custom MOP header if defined in the MOP
{$spindle} {$s} <- turn on the spindle and set the speed
{$blocks} <- Inserts the actual G-Code for the MOP (no G-Code will be in the file without this)
{$mop.footer} <- Inserts the custom MOP footer if defined in the MOP

You can copy/paste these:

{$comment} {$mop.name} {$endcomment}
{$spindle} {$s}

The MOPs are output in tree order, each one using the MOP definition.

Last is the Footer. This goes at the very end of the file. I like to include a send to home sequence, but you should modify to suit.

{$clearance} <- send the tool to the Z clearance plane
{$spindle(off)} <- turn off the spindle
G53 G0 Z-0.100 <- send the tool to absolute machine coordinates Z-0.100
G53 G0 X-10.000 Y-1.000 <- send the tool to a safe location in absolute machine coordinate (change this to suit your machine or omit)

You can copy/paste these:

G53 G0 Z-0.100
G53 G0 X-10.000 Y-1.000

The "Post File" setting is what actually creates the output - it includes the Header, the MOPs and the Footer

{$header} <- output the Header
{$mops} <- output all the MOPs
{$footer} <- output the Footer

You can copy/paste these:


If you are using a laser or plasma cutter you might want to investigate the Start Cut and End Cut options, but I leave them blank.

The other options that you might want to change are the Number Format (controls how many decimal places are output) and Rapid Down to Clearance (if it makes you nervious to see your machine rapid the Z towards the clearance plane).

Most of the other default options should be fine for a ShapeOko post-processor.

Once you have created a ShapeOko post-processor, you can right-click on it and select "Set as default", you should also save it once you have created it.

Programming and Macros

While not supported by Grbl, some G-code interpreters do support control structures:



The European standard is DIN 66025.