G-codes and M-codes for a CNC lathe: reference with examples (LinuxCNC)
· ~16 min read
A CNC part program is plain text made of command lines. Each line tells the machine where to move, how to move and what to switch on. G-codes (preparatory functions) cover the “how to move” part, and M-codes (miscellaneous functions) cover “what to switch on”: spindle, coolant, stops.
This article lists the codes you actually need on a lathe, with a focus on LinuxCNC. Most codes are the same on every control (Fanuc, Siemens in ISO mode, Mach3/4 and others); where LinuxCNC differs, it is pointed out.
Contents
- Command groups at a glance
- Lathe axes
- What a program line is made of
- Addresses (letters) in commands
- G-codes: motion
- G-codes: modes and coordinate systems
- G-codes: feed and spindle speed
- G-codes: threading
- G-codes: tool compensation
- G-codes: drilling cycles
- M-codes
- Program structure
- Example: OD turning
- Main lathe cycles and their G-code
- Common mistakes
Command groups at a glance
| Group | Codes | Used for |
|---|---|---|
| Motion | G0, G1, G2, G3, G4 | Rapid, feed move, arcs, dwell |
| Plane and units | G18, G20, G21 | XZ plane of the lathe, inch / mm |
| Diameter / radius | G7, G8 | Whether X means diameter or radius (LinuxCNC) |
| Coordinates | G90, G91, G53, G54-G59, G28, G30 | Absolute / incremental, work offsets, return positions |
| Feed and spindle | G94, G95, G96, G97 | Units per minute or per revolution, constant surface speed or RPM |
| Threading | G33, G76, G33.1 (G32 on Fanuc) | Threading pass, multi-pass cycle, rigid tapping |
| Compensation | G40, G41, G42, G43, G49 | Tool nose radius, tool length offset |
| Drilling | G73, G81, G82, G83, G80 | Drilling cycles and cancel |
| Spindle and program | M0, M1, M2, M30, M3, M4, M5 | Stops, program end, spindle rotation |
| Tool and coolant | M6, M61, M7, M8, M9 | Tool change, coolant |
Lathe axes
- Z - along the spindle axis. Z0 is usually on the part face; “minus” goes toward the chuck.
- X - across, from the part axis to the tool. X0 is the spindle centerline.
The X coordinate can mean either diameter or radius - this is set with G7/G8 (see below). Mixing them up is one of the most common mistakes: the part comes out twice as thick or twice as thin.
What a program line is made of
N40 G1 X30 Z-50 F0.2 (finishing pass)
| Element | Meaning |
|---|---|
N40 |
line number (optional) |
G1 |
preparatory function - linear feed move |
X30 Z-50 |
end point |
F0.2 |
feed |
( ... ) |
comment, ignored by the machine. LinuxCNC also accepts ; to end of line |
Addresses (letters) in commands
A G- or M-code is followed by parameters: a letter (address) and a number.
| Address | Meaning | Example |
|---|---|---|
| N | Line (block) number, optional | N40 |
| X | Coordinate across the part axis - diameter (G7) or radius (G8) | X30 |
| Z | Coordinate along the part axis; “minus” is toward the chuck | Z-50 |
| F | Feed: mm/min (G94) or mm/rev (G95) | F0.15 |
| S | RPM (G97) or surface speed (G96, m/min) | S800 |
| T | Tool number | T1 M6 |
| I, K | Arc center of G2/G3 in X and Z; for G33, K is the thread pitch | G3 X4 Z-8 I-3 K-4 |
| R | Arc radius | G3 X30 Z-5 R5 |
| P | G4 dwell time (seconds) or a cycle parameter | G4 P0.5 |
| Q | Cycle parameter or tool number in M61 | M61 Q2 |
| D | Maximum RPM for G96 (LinuxCNC) | G96 D2000 S150 |
Many codes are modal: once G1 or F0.2 is set, it stays active until
it is replaced by another code from the same group. That is why programs
often list only the coordinates that change.
G-codes: motion
| Code | What it does | Example |
|---|---|---|
| G0 | Rapid move at the machine’s maximum speed. Never for cutting! | G0 X42 Z2 |
| G1 | Linear feed move at feed F. The main code for turning, facing, chamfers and tapers. | G1 Z-50 F0.2 |
| G2 | Clockwise arc | G2 X30 Z-5 R5 |
| G3 | Counterclockwise arc | G3 X30 Z-5 R5 |
| G4 | Dwell. In LinuxCNC P is in seconds |
G4 P0.5 |
G2/G3 arcs. An arc is given by its end point plus either the center
(I - offset in X, K - in Z) or the radius R:
G1 X20 Z0
G3 X30 Z-5 R5 (R5 fillet)
Note: on a lathe, “clockwise” and “counterclockwise” depend on which side of the centerline the tool sits (front or rear toolpost) and how the X axis is configured. Check the arc in the toolpath preview before cutting. In LinuxCNC the I/K arc center is relative to the start point by default (G91.1 mode), not in absolute coordinates.
G-codes: modes and coordinate systems
| Code | What it does |
|---|---|
| G18 | XZ plane - the working plane of a lathe. Needed for arcs and nose radius compensation. LinuxCNC defaults to G17, so lathe configurations usually set G18 in the startup code. |
| G7 | X is the diameter (LinuxCNC). The mode lathe operators are used to: X30 = 30 mm diameter. |
| G8 | X is the radius (LinuxCNC, the default). X30 = radius 30, i.e. diameter 60. |
| G20 / G21 | Inches / millimeters |
| G90 | Absolute coordinates - from the part zero |
| G91 | Incremental - from the current point |
| G54-G59 | Work coordinate systems (part zeros). LinuxCNC also has G59.1-G59.3 |
| G53 | Move in machine coordinates (this line only) |
| G28 / G30 | Go to a stored position (stored with G28.1 / G30.1) - often used as the tool change point |
| G61 / G64 | Exact stop at every point / path blending. G64 P0.01 - blending with 0.01 mm tolerance |
G-codes: feed and spindle speed
| Code | What it does | Example |
|---|---|---|
| G94 | Feed F in mm/min (in/min) | G94 G1 Z-20 F80 |
| G95 | Feed F in mm per spindle revolution - the handiest mode for turning | G95 G1 Z-20 F0.15 |
| G96 | Constant surface speed: S in m/min (with G21). RPM rises automatically as the diameter gets smaller |
G96 D2000 S150 M3 |
| G97 | Constant RPM: S in rev/min |
G97 S500 M3 |
Always limit RPM with G96. As the tool approaches the centerline (for
example, facing to X0), RPM heads toward infinity. In LinuxCNC the limit is
set with the D address right on the G96 line:
G96 D2000 S150 M3 (150 m/min, but no more than 2000 RPM)
Fanuc uses a separate G50 S… command for this; LinuxCNC does not use G50 for it.
G-codes: threading
| Code | What it does | Example |
|---|---|---|
| G33 | Spindle-synchronized move - one threading pass. K is the thread pitch (mm/rev) |
G33 Z-25 K1.5 |
| G76 | Multi-pass threading cycle (LinuxCNC) | see below |
| G33.1 | Rigid tapping (requires a spindle encoder) | G33.1 Z-15 K1.25 |
One G33 pass looks like this:
G0 X19.4 Z3 (move to pass depth, 3 mm run-in)
G33 Z-25 K1.5 (pass with 1.5 mm pitch)
G0 X22 (retract)
G0 Z3 (return)
A full thread needs many such passes with decreasing depth. That is what
the G76 cycle does: its parameters are P (pitch), Z (thread end),
I (thread peak offset), J (first pass depth), K (full thread depth),
R (depth degression), Q (compound slide angle), H (spring passes),
E and L (taper at the ends). For exact sign and unit rules, see the
documentation for your LinuxCNC version.
G32 or G33? On Fanuc and many Chinese controls a threading pass is G32 and the pitch is given with F. In LinuxCNC it is G33 with the K address. If a program was written for another control, this code has to be changed.
Tapered threads. If a G33 line has both X and Z, the tool travels along a sloped line while keeping the pitch - that is how tapered threads are cut. A real program of this kind, explained line by line, is on the Taper threading page.
Turn G-code switches between G32 and G33 syntax with one button and lets you choose the pitch letter (I, K or F), and the threading and taper threading cycles calculate the passes, run-in and run-out for you.
G-codes: tool compensation
| Code | What it does |
|---|---|
| G40 | Cancel tool nose radius compensation |
| G41 / G42 | Nose radius compensation, tool to the left / right of the path. Needed for accurate tapers, spheres and radii. In LinuxCNC the tool table must contain the nose radius and the tool orientation (Q) |
| G43 | Apply the tool length offset from the tool table. On a lathe, LinuxCNC applies both X and Z offsets |
| G49 | Cancel the tool length offset |
G-codes: drilling cycles
| Code | What it does |
|---|---|
| G81 | Simple drilling |
| G82 | Drilling with a dwell at the bottom |
| G83 | Peck drilling with full retract (for deep holes) |
| G73 | Drilling with chip breaking |
| G80 | Cancel the cycle |
A LinuxCNC quirk: a canned cycle drills along the axis perpendicular to the selected plane. In the G18 plane that is Y, which a lathe does not have. So before a drilling cycle along Z you switch to G17 and go back to G18 afterwards. It is easier to leave this to a generator: the Drilling cycle in Turn G-code outputs drilling as plain moves.
M-codes
| Code | What it does | Example |
|---|---|---|
| M0 | Program stop (resume with Cycle Start) - for example, to flip the part | M0 (FLIP PART) |
| M1 | Optional stop - only works if the operator has turned it on | M1 |
| M2 | Program end | M2 |
| M30 | Program end and rewind | M30 |
| M3 | Spindle clockwise (forward) | S800 M3 |
| M4 | Spindle counterclockwise (reverse) | S800 M4 |
| M5 | Spindle stop | M5 |
| M6 | Tool change | T1 M6 |
| M7 | Mist coolant | M7 |
| M8 | Flood coolant | M8 |
| M9 | Coolant off | M9 |
| M48 / M49 | Enable / disable feed and spindle overrides | M49 |
| M61 | Tell the machine which tool is loaded without a tool change | M61 Q2 |
| M62-M65 | Digital outputs on/off (LinuxCNC) | M64 P0 |
| M66 | Wait for an input signal (LinuxCNC) | M66 P0 L3 Q5 |
| M100-M199 | User M-codes - your own scripts (LinuxCNC) | M101 |
Coolant M-codes differ from machine to machine: on one, flood is M8; on another, it is wired to M7. Check your machine’s configuration.
Tool change in LinuxCNC. The Fanuc-style T0101 (tool 1, offset 1)
does not work in stock LinuxCNC. Write it like this:
T1 M6 G43
Program structure
A program is read top to bottom, one line (block) at a time. It usually has five parts:
- Start - a
%line (optional in LinuxCNC, but if it is there, the program must also end with%) and a comment with the part name. - Safety line - modes that reset anything left over from the
previous program:
G18 G21 G7 G90 G40 G80. - Tool and spindle -
T1 M6 G43, speedSandM3, coolantM8. - Machining - G0 approaches, G1/G2/G3/G33 cutting moves and retracts.
- End -
M9(coolant),M5(spindle), retract to a safe point andM30.
Comments go in parentheses (in LinuxCNC, also after ;) and are skipped by
the machine. Line numbers N are optional.
Example: OD turning
Stock Ø40, turn Ø30 over a length of 50 mm, 1 mm per side per pass. Part zero is on the face and the centerline.
%
(OD TURNING D40 -> D30, L50)
G18 G21 G7 G90 G40 G95 (XZ plane, mm, diameter, absolute, feed mm/rev)
T1 M6 G43 (turning tool)
G96 D2000 S150 M3 (150 m/min, max 2000 RPM)
M8 (coolant)
G0 X42 Z2 (approach)
G0 X38 (pass 1)
G1 Z-50 F0.2
G0 X42
G0 Z2
G0 X36 (pass 2)
G1 Z-50
G0 X42
G0 Z2
G0 X34 (pass 3)
G1 Z-50
G0 X42
G0 Z2
G0 X32 (pass 4)
G1 Z-50
G0 X42
G0 Z2
G0 X30 (finishing pass)
G1 Z-50 F0.1
G1 X41 (exit along the shoulder face)
G0 Z2
M9 (coolant off)
G97 S500 (leave G96 before stopping the spindle)
M5 (spindle stop)
G0 X100 Z100 (retract to safe point)
M30
%
This is a teaching example: before running it on your machine, check the zeros, tool offsets, the safe retract point and the cutting data for your material and insert. The first run should be in preview and “cutting air”.
Main lathe cycles and their G-code
Every typical operation can be written with these codes. Below are the codes each cycle mainly uses; each link leads to the cycle’s page with a real program from Turn G-code, explained line by line.
| Cycle | Main codes | What happens |
|---|---|---|
| OD turning | G0, G1 in Z | Passes along the axis with decreasing diameter, then a finishing pass |
| Facing | G0, G1 in X | Passes across from the edge to the center, depth in Z |
| Threading | G33 (or G32) with K | Many threading passes with decreasing depth, run-in and run-out |
| Taper threading | G33 X… Z… K… | Threading pass along a sloped line |
| Taper | G1 X… Z… | Roughing steps, then a pass along the taper line |
| Sphere | G1, G3 with I/K | Roughing cylinders around the ball, then the arc to size |
| Groove | G1 in X | Plunges across the groove width, layer by layer |
| Drilling | G1 in Z, G0 | Pecks with retract to clear chips |
| Boring | G1 in Z | Passes inside the hole with increasing diameter |
| Cutoff | G1 in X, G0 | Plunges with chip clearing and a widened kerf |
| Chamfer / radius | G1, G3 | Passes along the chamfer or arc, parallel to the finished profile |
| Archimedean spiral | G33 with K | The tool moves in X synchronized with the spindle - a spiral on the face |
Common mistakes
- Diameter instead of radius. The program is written in diameters but the machine is in G8 - the tool stops twice as far from the centerline and the part comes out oversize. The other way round (radii under G7), the tool goes twice as close to the centerline and cuts far too deep. Check G7/G8 at the start of the program; more in G7 and G8: diameter or radius.
- G96 without an RPM limit. Near the centerline the spindle runs up to its maximum.
- G0 into material. Rapids only through air; always feed in with G1.
- Wrong plane. Without G18, arcs and nose radius compensation do not behave as expected.
- Threading code from another control. G32 from a Fanuc program will not work in LinuxCNC - you need G33 (and vice versa).
- Feed in the wrong units.
F0.2under G94 is 0.2 mm/min, so the machine barely moves. G95 is handier for turning.
How not to write all this by hand
Even simple turning is dozens of lines, and a thread, sphere or taper with compensation is hundreds - and any typo can cost you the part or the insert. Turn G-code generates a ready program for 12 lathe cycles (OD turning, facing, threading, taper, sphere, groove, boring, cutoff, chamfer/radius and more) from form fields: diameters, lengths, feeds, speeds. You see the toolpath in the 2D simulator before it runs on the machine, and G7/G8, G32/G33, coolant M-codes and the output format can be set to match your control.
