G-Code

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

Overview

 * 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.

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.

G-code
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

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.

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

Checksums
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 *.

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.

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

http://carbide3d.com/docs/list-of-supported-gcodes/

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.

Overview
http://www.shapeoko.com/forum/viewtopic.php?f=3&t=5576&p=41406

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
http://docs.carbide3d.com/tutorials/tool-change/

http://community.carbide3d.com/t/automatic-tool-length-offset/8480

Forum Discussion

 * Re: Using laser pointer to locate zero
 * Re: Does TinyG support G53
 * Re: SO3, Carbide Motion, & WCS --- overview with diagram
 * http://www.shapeoko.com/forum/viewtopic.php?f=3&t=8297&p=64898#p64898

List of all G-codes
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: ) % ( %: Start or end of program )
 * 1) ( #: Variable Assignment:# )

G-code examples

 * Programming Help Ellipse
 * [[File:Circle-diamond-square-50-45-40mm.txt]] --- Hand-coded G-code to cut a 40mm diamond inset w/in a 45mm circle inset w/in a 50mm square. Speed and feed suitable to a Dremel 4000 w/ a 1/8" 2-flute bit set to 8 or so.

G2 - clockwise arc
G2 Xx Yy Ii Jj

Notes:
 * 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.
 * 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

Cutting a full circle
http://www.helmancnc.com/how-to-mill-full-circle-cnc-program-example-code/

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:

% (TOOL/MILL,0.1,0.05,0.000,0) (FILENAME: ) G21 G90 G0X0.000Y0.000Z10.000

before the initial move to the origin at safety height:

G0X0.000Y0.000Z10.000

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

(TOOL/MILL,6.3500,0,1.0000,0.0) M6 T201 M3 S8333 G0X15.000Y115.000 G0Z10.000 G1Z-2.345F317.5

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} {$tooltable} {$units} {$distancemode} {$workplane} {$clearance}

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} {$workplane} {$mop.header} {$spindle} {$s} {$blocks} {$mop.footer}

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: {$clearance} {$spindle(off)} 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: {$header} {$mops} {$footer}

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:

https://www.reddit.com/r/CNC/comments/448q4n/need_help_making_my_job_easier/