G-code and Programming
Coordinates, work offsets, arcs, canned cycles and subprograms for mills, plus lathe G-code and machine accuracy.
What G-code is
G-code is a simple text language of machine commands: move here, at this feed, turn the spindle on. A program is a list of lines, called blocks, each made of letters and numbers. CAM software normally writes it from your model, and the controller reads it one block at a time. You rarely write it by hand, but you should be able to read it, because that is how you find mistakes, fix a post processor, and write short programs for set-up and probing.
- A G word is a preparatory command (a kind of move or mode): G0, G1, G2, G54.
- An M word is a miscellaneous machine function: M3 spindle on, M8 coolant on, M30 end.
- Address letters carry numbers: X, Y, Z for positions, F for feed, S for spindle speed, T for tool, H and D for offsets, I, J, K for arc centers, R for a radius.
- Modal commands stay in force until replaced: after G1, every following block is a straight cut until you give G0 or another motion code.
- Dialects. GRBL (hobby routers), Mach3/Mach4, LinuxCNC, Fanuc, Haas, Siemens and Heidenhain all differ in details. Check your controller’s manual. Comments are written after a semicolon on some controls and in (parentheses) on others (Fanuc).
The common codes
| Code | Meaning | Example |
|---|---|---|
G0 | Rapid move: as fast as possible, not for cutting | G0 X10 Y10 |
G1 | Straight cutting move at the feed rate F | G1 X40 Y10 F600 |
G2 / G3 | Clockwise / counter-clockwise arc. X, Y is the end point; I, J the offset from the start to the arc center | G3 X40 Y5 I0 J5 |
G17 / G18 / G19 | Arc plane: XY (mills) / XZ (lathes) / YZ | G17 |
G20 / G21 | Units: inches / millimeters | G21 |
G90 / G91 | Absolute coordinates / relative (incremental) to the last position | G90 |
G94 / G95 | Feed per minute / feed per revolution | G94 F600 |
G54 to G59 | Work coordinate systems (work zero) | G54 |
G40 / G41 / G42 | Cutter compensation off / left / right | G41 D1 |
G43 H1 | Tool length compensation using tool 1’s offset | G43 H1 Z5 |
G80 to G89 | Canned cycles (drilling, tapping, boring); G80 cancels | G83 Z-20 Q5 R2 |
M3 / M4 / M5 | Spindle clockwise / counter-clockwise / stop (S sets the speed) | M3 S12000 |
M6 T1 | Tool change to tool 1 | M6 T1 |
M8 / M9 | Coolant on / off | M8 |
M30 | End of program, rewind | M30 |
Feed in a mill program is in mm/min (G94) and must be written with the right units: mm/s is 60 times too slow, and in/min 25 times too fast.
A first program: a rounded rectangle
Cut a 40 × 30 mm rectangle with 5 mm corner radii. The coordinates are the center line of the tool, starting at the bottom edge and traveling counter-clockwise, so the arcs are G3.
G21 G90 G17 G54 ; mm, absolute, XY plane, work offset 1
M3 S12000 ; spindle on
G0 X0 Y0 Z5 ; rapid to the origin, 5 mm above the work
G0 X5 Y0 ; rapid to the start point
G1 Z-1 F200 ; plunge 1 mm
G1 X35 Y0 F600 ; bottom edge
G3 X40 Y5 I0 J5 ; bottom-right corner
G1 X40 Y25 ; right edge
G3 X35 Y30 I-5 J0 ; top-right corner
G1 X5 Y30 ; top edge
G3 X0 Y25 I0 J-5 ; top-left corner
G1 X0 Y5 ; left edge
G3 X5 Y0 I5 J0 ; bottom-left corner, back to the start
G0 Z5 ; lift clear
M5 ; spindle off
M30 ; end
Worked example: path length and time
- Straight sides: 30 + 20 + 30 + 20 = 100 mm.
- Corners: each quarter circle of radius 5 mm is π ÷ 2 × 5 = 7.85 mm, so the four corners are 31.4 mm.
- One pass: 131.4 mm. At F600 (600 mm/min = 10 mm/s) that is 131.4 ÷ 10 = 13.1 s.
- Three passes of 1 mm each to cut 3 mm: about 39.4 s of cutting, plus plunges and moves between passes.
- The tool center follows this line, so the finished edge is half a tool diameter outside (or inside) it. CAM offsets the path for you; in hand-written code it is your job (or use cutter compensation).
Work offsets and tool offsets
- Work offsets (G54–G59) store the position of a part’s zero in machine coordinates. A program that says G54 X10 Y10 means 10 mm from that part’s zero, wherever it sits on the table. The same program can run on several parts using G54, G55, … for each.
- Setting a work offset. Touch the tool or a probe to the part’s edges (or find a hole center) and tell the control to store the position. A touch probe automates this.
- Tool length offset (G43 H#). Every tool sticks out a different length. The control stores each tool’s length, and G43 shifts Z so that Z0 always means the work surface, whichever tool is in the spindle. Measure the length with a tool setter or by touching off.
- Cutter radius (diameter) offset (D#). Stores the tool’s radius, so that cutter compensation (G41 or G42) can offset the path automatically, and a worn tool is corrected by changing one number.
- Z zero. Set it at the top of the stock or the finished surface, whichever the program expects, and keep a clear height above it. A wrong Z zero is the most common crash.
Arcs and cutter compensation
- I, J, K are the offsets from the arc’s start point to its center, in X, Y and Z, with their sign. The classic mistake is to measure them from the origin.
- R format (G3 X10 Y5 R5) gives the radius instead; the control finds the center. It is ambiguous for arcs over 180° and can fail, so use I and J for full circles.
- Full circles need I, J, because the start and end points are the same. Many controllers do not accept R for a full circle.
- Cutter compensation (G41/G42). The control shifts the path sideways by the tool radius, so you write the finished outline. Use an entry move that is long enough to apply the offset (at least the tool radius), and cancel it with G40 on a lead-out. Compensation errors on tight inside corners cause gouges.
- Arc fits. CAM can output arcs (G2/G3) instead of many short lines (G1). Arcs give a smoother cut and a shorter program; long strings of tiny lines can starve the controller of data and slow the machine.
Canned cycles, subprograms and macros
| Cycle | What it does | Example (Z-20 deep, R plane at 2 mm) |
|---|---|---|
G81 | Simple drill: feed down, rapid out | G81 X10 Y10 Z-20 R2 F100 |
G83 | Peck drill: drill Q mm, retract fully to clear chips, repeat | G83 X10 Y10 Z-20 Q5 R2 F100 |
G73 | Chip-breaking peck: small retracts only | G73 X10 Y10 Z-20 Q5 R2 F100 |
G84 | Rigid tap with spindle and Z synchronized | G84 X10 Y10 Z-12 R2 F(rpm × pitch) |
G76 / G85–G89 | Fine boring and reaming variants | See your controller manual |
G80 | Cancel the canned cycle | G80 |
- Subprograms (M98 P#, M99 or O-words) repeat a block of code: one drilling pattern for several positions, or a contour at several depths.
- Macros and parameters (such as #100 variables, or conditional G65 calls) let you program probing, patterns and families of parts. They are controller-specific.
- Probing cycles measure the part and set offsets automatically; use them for set-up and for in-process checks.
Lathe programming
A lathe program uses the same ideas, with X as a diameter and Z along the axis. The stepped shaft below (cut from 30 mm bar) is described by five points on the finished profile.
O0100 ; stepped shaft
N10 G21 G18 G40 G97 ; mm, XZ plane, cancel nose compensation, rpm mode
N20 T0101 ; roughing tool, offset 01
N30 G96 S180 M3 ; constant surface speed 180 m/min, spindle on
N40 G50 S3000 ; limit the spindle to 3000 rpm
N50 G0 X32 Z2 ; start point clear of the bar
N60 G71 U1.5 R0.5 ; rough turning: 1.5 mm depth per cut, 0.5 mm retract
N70 G71 P100 Q200 U0.4 W0.1 F0.25 ; profile lines N100-N200, leave 0.4 on X, 0.1 on Z
N100 G0 X18 ; P1: start the profile at the face
N110 G1 Z0 F0.1 ; face edge
N120 X20 Z-1 ; P2: 1 x 45 degree chamfer
N130 Z-25 ; P3: turn the diameter 20 to Z-25
N140 X28 ; P4: step up to diameter 28
N150 Z-40 ; P5: turn diameter 28 to Z-40
N200 X32 ; clear the stock
N210 G70 P100 Q200 ; finishing pass along the same profile
N220 G0 X100 Z100 ; retract
N230 M5 ; spindle off
N240 M30 ; end
- G71 (Fanuc-type) is a roughing cycle: the control calculates the passes from the profile you give between the P and Q blocks and leaves the finishing allowance U (X, on the diameter) and W (Z). G70 then runs the same profile as a finishing pass. Other controls use different cycles (Haas G71 has two formats; Siemens uses CYCLE95), so check your manual.
- Diameter programming: X20 means a 20 mm diameter, so the tool moves 10 mm from the center. U0.4 leaves 0.4 mm on the diameter, 0.2 mm per side.
- Speed. G96 S180 holds 180 m/min; G50 S3000 caps the spindle. At Ø30 the spindle runs at about 1 910 rpm, and at Ø10 at about 5 730 rpm.
- Material removed: the 30 mm bar, 40 mm long, holds 28 274 mm³; the finished part has 17 090 mm³, so about 40 % is removed as chips.
- Threading uses G76 (see Turning: Lathes and Operations) and parting off uses a G1 feed to the center at a low feed rate.
- Tool numbers. T0101 is tool 1 with offset 1; the offset holds its X and Z position and any wear.
Resolution and accuracy
Most hobby machines use stepper motors. A 1.8° motor takes 200 full steps per revolution, and the driver divides each step into microsteps (here 16), so 3 200 per revolution. How far one step moves the tool depends on the transmission. See Motion Control and Embedded Systems.
Steps per mm = (full steps per rev × microsteps) ÷ travel per motor revolution
Worked example: steps per mm
- Lead screw with an 8 mm lead (a T8 screw): 200 × 16 ÷ 8 = 400 steps/mm, so one step moves 8 ÷ 3 200 = 2.5 µm.
- Belt drive with a 20-tooth pulley on a 2 mm pitch (GT2) belt: the belt moves 40 mm per revolution, so 3 200 ÷ 40 = 80 steps/mm (12.5 µm per step).
The step size is much finer than the real accuracy. Backlash in the nut, flex in the frame, the tool’s deflection and stepper torque limit what you achieve, typically ±0.05 to ±0.2 mm on a hobby machine and far better on a rigid mill. Do not mistake resolution for accuracy.
- Test the machine. Cut a square, measure both directions, and compare. A circle that looks like an oval shows differing X and Y scaling or loose belts. Check against a known gauge, not another cut.
- Backlash shows up when the direction reverses (a circle’s edges do not meet). Adjust or replace anti-backlash nuts, and in CAM prefer climb cuts that load the screw consistently.
- Steppers lose steps if the feed or acceleration is too high; the machine does not know it, and every later move is wrong. Servo and closed-loop drives detect and correct this.
- Thermal growth. Steel grows about 11.7 µm per meter per °C: a 100 mm steel part warmed by 10 °C grows 11.7 µm. Aluminum grows about twice as much. Let parts reach room temperature before the final measurement.
- Tolerances. Know what the drawing asks for and whether the process can hold it; see Fits & Tolerances.
Writing safe programs
- Start with a safe block that sets units, absolute mode, the plane, the work offset and cancels compensation and canned cycles, so that the program never depends on what the machine did last.
- End and begin at a safe height above the work and the clamps, and retract Z before moving X or Y.
- Comment the program with the tool, the material and the date. Add the stock size and the work zero in the header.
- Simulate first, then air-cut with the Z offset raised, and use single-block mode and reduced feed override for the first run. See Troubleshooting, Accuracy and Safety.
- Check the post. Run a short test program to confirm the arc format, units, tool change and spindle commands on your controller.
Related
- CNC Machining: the overview of this guide.
- CAM and Toolpaths: how CAM produces G-code.
- Turning: Lathes and Operations: lathe operations, inserts and threading.
- Embedded Systems: stepper drivers and motion.
FAQ
What is G-code?
It is a simple text language of machine commands: move here, at this speed, turn the spindle on. CAM software writes it from your design, and the machine’s controller reads it line by line. You rarely write it by hand, but reading it helps you find mistakes.
What is the difference between G0 and G1?
G0 is a rapid move at the machine’s maximum speed, not for cutting, and the path may not be straight on some machines. G1 is a straight line at the programmed feed rate, used for cutting.
Why does my machine cut a circle as an oval?
The X and Y axes are scaled differently (steps per mm are wrong in one), a belt is loose, or there is backlash. Calibrate each axis with a gauge and cut a test circle.
Can I edit G-code by hand?
Yes, for small changes such as feed, speed, depth or a start line. For toolpaths, change the CAM instead and re-post so that the program stays consistent with the model.
Why does the program start with G54?
G54 selects the first work offset, the stored position of the part’s zero. Without it, the program would run from whatever offset was last active.
References
- NIST, The NIST RS274NGC Interpreter, Version 3 (the reference definition of G-code).
- LinuxCNC documentation (G-code reference) and GRBL wiki (supported G-codes for hobby machines).
- Smid, P., CNC Programming Handbook, 3rd ed., Industrial Press.
- Fanuc series 0i-TD/0i-MD operator manuals (G71, G70, G76 cycles) and Haas lathe programming manuals.
- Oberg, E. et al., Machinery’s Handbook, 31st ed., Industrial Press (numerical control).
Last reviewed: October 2026. Cutting data are starting points: machines, tools and materials differ, so test on scrap and follow the tool maker’s data.
