M-Codes: Machine Functions
G-codes control tool motion; M-codes control the machine itself — spindle, coolant, tool change, program stop. This page covers the common M-codes and the correct program start and end sequence on a Haas (FANUC-compatible) mill.
Concept
If G-codes answer "where does the tool go," M-codes answer "what does the machine do." An M-code is a machine function: start the spindle, turn on coolant, change a tool, stop the program. M-codes are mostly one-shot: they execute once when the block is read. Once M03 starts the spindle, it stays running until M05, but that is a physical state change, not a modal code group in the G-code sense.
A block can contain both motion and an M-code. On a Haas mill, M-codes (M03/M04/M05/M08/M09) are executed at the end of the block after motion completes. To express a clear order, put each M-code on its own block: move first, then turn the machine function on or off. This avoids ambiguity about whether coolant starts before or after the tool arrives at the cut.
Why It Matters
M-codes are the on/off switches for the machine. Their order at start and finish matters: starting the spindle before the tool is clear, or changing tools without the machine having completed the tool-change sequence, causes errors. On a Haas, M30 itself ends spindle and coolant at shutdown; explicit M09/M05 documents the order. M-codes are also the most machine-specific part of the program — the G-codes G00/G01/G90 are largely universal, but M-codes are not. Always verify against your machine manual.
How It Works
Spindle: M03, M04, M05
M03 starts the spindle in forward (Haas terminology); M04 starts it in reverse; M05 stops it. The speed is set with the S word: M03 S2000 starts the spindle at 2000 RPM forward. On a mill, right-hand cutting tools run forward (M03); M04 is reserved for left-hand tooling. On a lathe, confirm forward direction against your machine and tooling arrangement before assuming M03.
Give the spindle time to reach speed before cutting. The line M03 S2000 starts acceleration; a safe move to clearance or a short dwell gives the spindle time to ramp. M05 stops the spindle; on a Haas, M06 (tool change) automatically stops the spindle, turns off coolant, and moves to the tool-change position as part of its cycle. Writing M05 explicitly before M06 is a teaching habit that makes the shutdown order clear, not a requirement because M06 would otherwise change tools while spinning.
Coolant: M08, M09, and Through-Spindle
M08 turns on flood coolant. M09 turns off coolant. On a Haas mill, through-spindle coolant (TSC) uses separate M-codes (commonly M88 on / M89 off) — check your manual. M07 mist coolant is machine-specific and not a Haas universal. Write M08 on its own block after the tool is at safe clearance and confirm coolant reaches the tip before the first cut. In this example the end sequence retracts to verified clearance first, then M09 and M05; the exact clearance value is set by the setup, not a universal Z5.
Tool Change: M06, T, and H Offsets
On a machining center, T02 M06 selects tool 2 from the magazine and loads it into the spindle. On a Haas, M06 automatically stops the spindle, turns off coolant, and moves to the tool-change position. On a lathe, the turret moves to the tool station directly: T0202 selects tool 2 and its offset.
T selects the tool number; H sets the length offset separately. After M06, establish the tool length offset with G43 H02 on the next safe Z move. Whether the control automatically recalls the matching H offset depends on control version and settings; explicitly writing G43 H is the clear, portable practice. This page uses that explicit form.
Program Control: M00, M01, M02, M30
| Code | Function | Use |
|---|---|---|
| M00 | Unconditional program stop | Always pauses; press cycle start to continue. Used for mandatory inspections or chip clearing. |
| M01 | Optional stop | Pauses only if the optional-stop switch on the panel is on. Used for spot checks; skipped in production. |
| M02 | Program end | Stops the program without rewinding to the top. Rarely used today. |
| M30 | Program end and rewind | Standard end: ends the program, stops spindle/coolant, and rewinds to program top for the next cycle. |
On a Haas mill, M30 ends the program and stops the spindle and coolant as part of the end sequence. Writing M09 and M05 explicitly before M30 documents the shutdown order clearly; it is not required because M30 would otherwise leave the spindle running. M02 does not rewind, which is why M30 is the standard end command.
M-Code Timing on a Block
On a Haas mill, an M-code on the same line as motion executes at the end of the block, after the motion completes. To express a clear order, use separate blocks: retract first (G00), then M09, then M05, then M30. Do not try to reorder an M-code by moving it to the front of the same line — block order is controlled by writing separate blocks, not by word order inside one block.
Other Common M-Codes
M19 orients the spindle to a fixed position (used for some setups, boring bar orientation, or probe alignment; on a Haas, M19 with an R word can orient to a specific angle). Chuck clamp/unclamp and tailstock functions use machine-specific M-codes (commonly M10/M11 on some lathes, but verify). These vary by builder — do not assume.
Program Number and Block Structure
A FANUC/Haas mill program starts with O0001 and ends with M30. Comments in parentheses after a block are ignored by the controller but read by the operator: (DRILL 4 HOLES). Write comments that explain why, not what.
Safety: Why the Start Block Matters
The startup block G21 G17 G90 G40 G49 G80 establishes a known state: metric units, XY plane, absolute mode, compensation cancelled, cycles cancelled. It does not set spindle, coolant, or work offset — those follow. Without it, the program inherits whatever mode the previous program left.
Example: Program Start and End (Teaching Snippet)
A Haas mill teaching snippet. Assumes: tool 1 loaded, G54 work datum set, fixture clears Z50, Z5 is above the work face, and the tool can safely move at Z50. This is a fragment, not a complete production cycle:
O0001 (DEMO SNIPPET)
G21 G17 G90 G94 G40 G49 G80 (startup: metric, XY, abs, mm/min, modes off)
T01 M06 (load tool 1; M06 stops spindle/coolant)
G54 G90 (work offset)
G00 G43 H01 Z50. (length offset at safe Z; verify Z50 clears fixture)
S1500 M03 (spindle forward at 1500 RPM)
G00 X0. Y0. (XY position over part at safe Z50)
M08 (coolant on, confirm flow before cutting)
G00 Z5. (rapid to clearance above work face)
G01 Z-2. F100. (plunge feed)
G01 X50. F300. (cut)
G00 Z50. (retract to safe height)
M09 (coolant off)
M05 (spindle stop)
G91 G28 Z0 (optional Z home return)
M30 (end, rewind)
Note the order: G43 H01 Z50 is established at a verified safe Z before XY moves; M08 is on its own block at clearance; the end block retracts, then M09, M05, then M30. Assumptions: after tool change the current position allows a Z move to Z50, H01 and G54 are calibrated, Z50 clears all fixtures on XY traverse, Z5 at X0 Y0 clears the work face, and the selected tool is confirmed by the manufacturer to plunge axially at the programmed feed.
Spindle Orientation and M19
M19 orients the spindle to a fixed position (used for some tool setups, boring bar orientation, or probe alignment). On a Haas, M19 with an R word can orient to a specific angle. This is a setup function, not a cutting function.
Why M-Codes Are Not G-Codes
M03 starts the spindle and it stays running until M05, but that physical persistence is not a modal G-code group. Track spindle, coolant, and program state separately: M03/M04/M05 control spindle state; M08/M09 control coolant state; M30 controls program state. G-codes set motion and mode groups. Mixing the mental models — for example expecting M08 to cancel a drilling cycle — causes errors.
Checking M-Code Effects Before Running
When a program uses an unfamiliar M-code, look it up in the machine manual before cycle-start. A wrong M-code can unclamp the chuck, flood coolant, or move the pallet. Most modern machines show the M-code function on the screen when you single-block through it; use that as a checklist on the first run.
Common Mistakes
- Putting M08 on the first plunge line — the first cut runs dry because coolant turns on after the motion. Put M08 on its own block at clearance.
- Starting spindle before the tool is clear — position the tool at safe Z, then M03.
- Assuming M06 loads the H offset — T selects the tool; explicitly write G43 H on the next safe Z move. Auto-recall depends on control version.
- Omitting the explicit shutdown order — retract, M09, M05, then M30. M30 also stops spindle/coolant, but writing the order documents it.
- Using M02 instead of M30 — M02 does not rewind to program top.
- Assuming M-codes are universal — chuck, tailstock, TSC, and pallet M-codes are builder-specific. Verify against the manual.
Practice
1. What does M01 do?
Show answer
Optional stop — pauses only if the optional-stop switch on the panel is on. Used for spot checks; skipped during production runs.
2. Why write M09 and M05 explicitly before M30?
Show answer
To document the shutdown order clearly. On a Haas, M30 also ends spindle and coolant as part of program end; the explicit M09/M05 makes the sequence readable and portable to controls where behavior differs.
3. What is the difference between M00 and M01?
Show answer
M00 always stops (unconditional). M01 stops only if the optional-stop switch is on.
4. After T01 M06, what must happen before the first Z cut?
Show answer
Establish the tool length offset with G43 H01 on a safe Z move (Z50). T selects the tool; this page writes H explicitly rather than assuming the control auto-recalls it.
5. Why is M30 preferred over M02?
Show answer
M30 rewinds the program pointer to the top for the next cycle; M02 does not.
Sources
- Haas M30 Program End — M-code behavior on Haas mills.
- Haas M06 Tool Change — M06 stops spindle/coolant and moves to tool-change position.
- Haas Mill M-Codes manual — M-code list and timing.
- All speeds and feeds are classroom teaching assumptions, not tooling recommendations.