← All guides
Machined metal parts

M-Code Explained: CNC Machine Functions Reference

Tutorials

M-Code Explained: CNC Machine Functions Reference

M-code (Miscellaneous code) controls the machine functions that are not related to motion — spindle on and off, coolant flow, tool changes, and program flow. While G-code tells the tool where to go, M-code tells the machine what to do.

Every CNC program that runs on a real machine uses a combination of G-codes and M-codes working together to produce a finished part. G-codes handle the geometry of the cut. M-codes handle the machine operations that support the cut.

This guide covers every common M-code, how it works, and how to use it correctly in your programs.


G-Code vs M-Code: The Difference

G-Code M-Code
Controls Tool motion and geometry Machine auxiliary functions
Examples G00, G01, G02, G90, G54 M03, M05, M06, M08, M30
Modal? Most are modal Some modal, some one-shot
Written per line Usually one G-code per line One M-code per line (can combine with G-code)

A typical program uses them together on the same line or on adjacent lines:

G01 X100 F200  ; G-code: move the tool
M03 S3000      ; M-code: start the spindle
M08            ; M-code: turn on coolant
G00 Z5         ; G-code: rapid retract
M09            ; M-code: turn off coolant
M05            ; M-code: stop the spindle
M30            ; M-code: end the program

G-code and M-code work together. You cannot cut material with G-code alone because the spindle will not start. You cannot cut with M-code alone because the tool will not move.


Complete M-Code Reference

Spindle Control

Code Function Example Notes
M03 Spindle on, clockwise M03 S3000 Most common — standard milling direction
M04 Spindle on, counterclockwise M04 S3000 Used for left-hand tools or reverse operations
M05 Spindle stop M05 Stops spindle rotation. Use before tool changes

M03 starts the spindle rotating clockwise when viewed from above the tool. This is the standard direction for right-hand cutting tools. M04 is counterclockwise and is used for specific applications like left-hand taps or reverse spot facing.

The spindle speed is set with the S-word on the same line:

M03 S3000  ; Start spindle at 3000 RPM clockwise

S is modal — once set it stays active until you change it. You do not need to repeat S on every line.

M05 stops the spindle. Always stop the spindle before a tool change:

M05       ; Stop spindle
M06 T2    ; Change to tool 2
M03 S4000 ; Start spindle at new speed for new tool

Coolant Control

Code Function Example
M07 Mist coolant on M07
M08 Flood coolant on M08
M09 All coolant off M09

M08 turns on flood coolant — a steady stream of liquid directed at the cutting area. This is the standard for most metal cutting operations. M07 turns on mist coolant which is a fine spray of coolant mixed with air for applications where flood coolant would be excessive.

M09 turns off all coolant. Always turn off coolant before stopping the spindle or removing the part from the machine.

G01 X100 F200  ; Start cutting
M08            ; Turn on flood coolant
...
M09            ; Turn off coolant
M05            ; Stop spindle

Tool Change

Code Function Example Notes
M06 Tool change M06 T1 Stops program, changes tool, then continues

M06 stops the program and signals the operator (or automatic tool changer) to load the specified tool. The T-word on the same line specifies which tool number to load.

On manual tool change machines the spindle stops, moves to the tool change position, and waits for the operator to load the tool and press Cycle Start.

On automatic tool changer machines the tool change happens automatically. The machine moves to the tool change position and exchanges the tool in about 2-5 seconds.

M06 T1   ; Load tool 1 (6mm end mill)
M03 S3000
; ... cut with tool 1 ...
M05
M06 T2   ; Load tool 2 (drill)
M03 S2500
; ... cut with tool 2 ...

Program Flow

Code Function Example Notes
M00 Program stop (full) M00 Completely stops machine. Press Cycle Start to resume
M01 Optional stop M01 Stops only if optional stop button is enabled. Used for checking parts
M02 End of program M02 Ends program without rewinding
M30 End of program + rewind M30 Ends program and rewinds to start. Most common end code

M00 is a full program stop. The machine stops all motion, stops the spindle, and waits for the operator to press Cycle Start. Use M00 for intermediate inspection, part repositioning, or manual intervention during a program.

M01 is similar to M00 but only activates when the optional stop button on the controller is enabled. When the button is off M01 is ignored and the program continues. Use M01 for checks that are sometimes needed but not always.

M02 ends the program. The controller stops and the program is finished. M30 does the same thing but also rewinds the program to the beginning. M30 is the most common end-of-program code in production environments because the machine is ready to run the next part immediately.

M30  ; End program and rewind to start
; The machine now waits for Cycle Start to run again

Subprograms

Code Function Example Notes
M98 Call subprogram M98 P1000 Jumps to subprogram O1000 and executes it
M99 Return from subprogram M99 Returns to the line after the M98 that called it

Subprograms let you reuse blocks of code without rewriting them. The main program contains M98 which calls a separate subprogram. The subprogram ends with M99 which returns to the next line in the main program.

; Main program O0001
G90 G94 G17 G54
M06 T1
M03 S3000
G00 X0 Y0 Z5
M98 P1000    ; Call subprogram O1000
G00 Z5       ; Execution returns here after subprogram
M30

; Subprogram O1000 (the pocket routine)
O1000
G01 Z-1 F100
G01 X50 F200
G01 Y50
G01 X0
G01 Y0
G00 Z2
M99          ; Return to main program

This is useful for repeating the same operation at multiple positions. Call the subprogram with different work offsets to cut the same pocket in multiple locations.


Common M-Code Mistakes

Mistake 1: M06 Without Stopping the Spindle

M06 T2  ; Tool change while spindle is running!

Some controllers reject a tool change command while the spindle is running. Always stop the spindle with M05 before M06 to prevent damage to the spindle and tool holder.

M05     ; Stop spindle
M06 T2  ; Safe tool change

Mistake 2: Missing M30

A program without M30 at the end may run to the last line and stop without rewinding. On some controllers the program ends but the machine does not return to the start, requiring manual rewinding before the next part.

Always end every program with M30.

Mistake 3: M08 Without M09

Leaving coolant on after the program ends wastes coolant and creates a mess. Always include M09 before M05 or M30.

M09  ; Coolant off
M05  ; Spindle off
M30  ; Program end

Mistake 4: Wrong M03 vs M04 Direction

Using M04 (counterclockwise) with a right-hand cutting tool reverses the cutting direction and results in poor surface finish and rapid tool wear. Verify the spindle direction before running.


M-Code Quick Reference

SPINDLE
M03   On, clockwise       M03 S3000
M04   On, counterclockwise M04 S3000
M05   Stop spindle        M05

COOLANT
M07   Mist on             M07
M08   Flood on            M08
M09   Coolant off         M09

TOOL CHANGE
M06   Change tool         M06 T1

PROGRAM FLOW
M00   Program stop        M00
M01   Optional stop       M01
M02   End program         M02
M30   End + rewind        M30

SUBPROGRAMS
M98   Call subprogram     M98 P1000
M99   Return from sub     M99

What’s Next?

Now that you understand M-codes learn how they work with G-codes:

Using M-Codes with Multiple Spindles

Some CNC machines have multiple spindles or a sub-spindle on a lathe. On these machines M-code variations control which spindle operates. M03 controls the main spindle. M03 with a P-word or a different M-code variant controls the sub-spindle. Check your machine manual for the specific M-code assignments for your configuration.

When programming multi-spindle machines verify that the correct spindle is selected before starting rotation. Running the wrong spindle at the wrong time can cause crashes.

M-Codes and Safety

Several M-codes serve safety functions that protect the machine, the tool, and the operator. Understanding these codes helps you write programs that run safely.

M00 and M01 give the operator a chance to check the part or the setup before continuing. Use them at critical points in the program where inspection is required.

M05 stops the spindle before a tool change. Running a tool change with the spindle spinning is dangerous on manual change machines and can damage automatic tool changers.

M09 stops coolant flow before the operator opens the machine door. Coolant spraying from a stopped spindle creates a mess and a slipping hazard.

M-Codes by Controller: What Differs

Most M-codes are universal across Fanuc, Haas, GRBL, and LinuxCNC controllers but there are differences. M03, M05, M08, M09, and M30 work the same on every controller. M06 (tool change) varies in how it handles automatic tool changers. M98 and M99 (subprograms) are standard on Fanuc but are handled differently or not at all on GRBL.

Always verify M-codes against your controller manual when using a machine for the first time. The basic codes like M03, M05, M08, and M30 are universal but the advanced codes for subprograms and probing vary between manufacturers.

Practical M-Code Examples

Complete Program with M-Codes

Here is a complete program that shows every M-code in context:

%
O2000 (BRACKET WITH M-CODES)
; === SETUP ===
N10 G90 G94 G17 G54
N20 G21
; === TOOL 1: FACE AND PROFILE ===
N30 M06 T1          ; Tool change to 20mm face mill
N40 M03 S4000       ; Spindle on at 4000 RPM
N50 M08             ; Flood coolant on
N60 G00 X-10 Y-10 Z5
N70 G01 Z0 F200
N80 G01 X110 F600
N90 G00 Z5
N100 M09             ; Coolant off before tool change
N110 M05             ; Spindle off
; === TOOL 2: DRILL ===
N120 M06 T2          ; Tool change to 10mm drill
N130 M03 S2500       ; Spindle on at 2500 RPM
N140 M08             ; Coolant on
N150 G00 X20 Y20 Z10
N160 G81 R2 Z-20 F150
N170 X80
N180 Y80
N190 X20
N200 G80
N210 G00 Z50
N220 M09             ; Coolant off
N230 M05             ; Spindle off
N240 M30             ; End program
%

Using M00 for Part Inspection

When a part needs to be checked mid-program use M00 to stop the machine at a safe point:

G00 Z50     ; Retract to safe height
M00         ; Stop — operator checks the part
; Press Cycle Start to continue
G00 X0 Y0  ; Continue with the next operation

This is useful for first-part inspection during program prove-out when the program has never been run before and every dimension needs verification. The operator can measure critical dimensions after the roughing pass before the finishing pass removes the final material. This catches problems early when they are still fixable without scrapping the part.

M-Code Modal Behavior

Some M-codes are modal — they stay active until another code cancels them. Others are one-shot and only affect the line they are on.

Modal M-codes:

  • M03 / M04 (spindle on) stay active until M05 (spindle off)
  • M07 / M08 (coolant on) stay active until M09 (coolant off)

One-shot M-codes:

  • M06 (tool change) — executes once, does not need to be cancelled
  • M00 / M01 (program stop) — stops once, program continues after Cycle Start
  • M98 / M99 (subprogram call/return) — execute once per call

Understanding which codes are modal and which are not helps you write cleaner programs. If you turn on coolant with M08 on line 50 it is still on at line 200 unless you turn it off with M09. Forgetting to cancel modal M-codes at the end of a program is a common beginner mistake that leaves the spindle running or coolant pumping after the program finishes.

M-Code Safety Blocks

Just as G-code has a safety block that sets modes at the start of each program, a complete safety block also verifies M-code state:

G90 G94 G17 G54  ; G-code safety block
M05              ; Ensure spindle is off
M09              ; Ensure coolant is off

This safety block ensures the machine starts in a known state regardless of what the previous program left active.

Tips for Writing Clean M-Code Programs

Group M-codes at the start of operations. Put all M-codes that set up an operation at the beginning of that operation, not scattered throughout. A tool change group includes: M05 (stop spindle), M06 (change tool), M03 (start spindle), and M08 (coolant on). Grouping them makes the program easier to read.

Use consistent ordering. Always put M-codes in the same order within each operation. A consistent order is: spindle stop (M05), coolant off (M09), tool change (M06), spindle start (M03), coolant on (M08). Following this sequence every time prevents errors.

Comment every M-code line. M-codes control machine functions that can be dangerous if misunderstood. A comment explaining what the M-code does helps the next person who reads your program understand your intent.

Verify before running. When running a new program for the first time check every M-code line in sequence. Does the spindle start when expected? Does the coolant turn on at the right time? Does the tool change happen at a safe position? These checks take two minutes and prevent crashes.

Learning M-codes is straightforward because there are fewer of them than G-codes and each one has a clear purpose. Master the spindle control and coolant codes first, then add tool changes and program flow. Subprograms can wait until you are comfortable with the basics and need to reuse the same code across multiple operations in a program.

Take the time to learn each M-code group separately. Practice spindle control codes on one day, coolant codes the next, and subprograms after that. Learning in small groups makes the information much easier to retain and apply.

Tags:#m-code#programming#beginner#reference