Macro Structure
What Is a Custom Macro?
A custom macro is a CNC program that uses variables, arithmetic, and control flow instead of fixed coordinate values. Macros are stored as O-number programs (O0001–O9999) in the CNC memory and called from other programs using G65, G66, or custom G/M codes.
The key benefit is flexibility: one macro program can handle an entire family of parts, run probing routines with different parameters, or implement custom canned cycles—all without rewriting code. Instead of hardcoded positions and feeds, macros use variables that are set at call time or computed on the fly.
Program Number Ranges
Fanuc reserves specific O-number ranges for different purposes. Knowing these ranges prevents conflicts and protects critical programs.
| Range | Purpose | Notes |
|---|---|---|
O0001–O7999 | User programs | General use, no special protection |
O8000–O8999 | Machine builder (MTB) programs | Often write-protected via parameter 3202 |
O9000–O9999 | System macros / custom cycles | Protected, called by custom G-codes (params 6050–6059) |
O9800–O9899 | Renishaw / probe vendor | Typical probing cycle programs |
Macro Call with G65
G65 is the primary way to call a macro program with argument passing. The syntax is:
G65 P____ [L____] [arguments]
P = program number to call (required). L = repeat count (optional, default 1). Arguments = letter-value pairs passed as local variables (#1–#33).
Example:
G65 P9100 A1.5 B2.0 C-0.5 L3
This calls O9100 three times with A=1.5, B=2.0, C=-0.5. On each call, control jumps to the called program, local variables (#1–#33) are loaded with the argument values, the program runs until M99, and control returns to the calling line.
G65 creates a new local variable scope at each call level, supporting nesting up to 4 levels deep. Each nested call gets its own independent set of #1–#33 variables.
G65 vs M98 Comparison
G65 and M98 both call subprograms, but they serve different purposes. G65 is for parametric macros; M98 is for fixed subprograms.
| Feature | G65 (Macro Call) | M98 (Subprogram Call) |
|---|---|---|
| Arguments | Yes — letter addresses map to #1–#33 | No argument passing |
| Local variable scope | New scope per call level | Shares parent scope |
| Nesting levels | Up to 4 levels | Up to 10 levels |
| Typical use | Parametric macros, probing | Fixed subprograms, repeated geometry |
| Decimal handling | Arguments keep decimal precision | N/A |
| Syntax | G65 Pnnnn A_ B_ C_ | M98 Pnnnn [Lnn] |
Modal Macro Call (G66/G67)
G66 activates a modal macro call: the macro is called automatically after every subsequent motion block (G00, G01, G02, G03). This continues until G67 cancels the modal call.
The syntax is the same as G65:
G66 P____ [arguments]
Use cases include automatic chamfering, deburring at each hole position, or custom tool-change logic that runs after every move.
Example:
G66 P9200 A0.5 (ACTIVATE MODAL MACRO WITH ARG)
G81 X1.0 Y1.0 Z-0.5 R0.1 F10. (DRILL + MACRO RUNS)
X2.0 Y2.0 (DRILL + MACRO RUNS AGAIN)
X3.0 Y3.0 (DRILL + MACRO RUNS AGAIN)
G67 (CANCEL MODAL CALL)
G80
Custom G-Code Macros
Fanuc parameters 6050–6059 map custom G-codes to programs O9010–O9019. For example, setting parameter 6050 = 100 means that when the control reads G100, it automatically calls O9010 with G65-style argument passing.
The custom G-code behaves exactly like a built-in G-code from the operator's perspective. Up to 10 custom G-codes are available on standard controls (more on some models).
See Custom G/M Cycles for full parameter setup details and M-code mapping.
Macro Program Template
Below is a complete skeleton macro demonstrating best practices: header comments documenting inputs/outputs, argument validation with alarm messages, modal state save/restore, and a clean return.
O9100 (CUSTOM PROBING MACRO)
(INPUT: A=X POSITION, B=Y POSITION, C=DEPTH)
(OUTPUT: #500=MEASURED X, #501=MEASURED Y)
(-------------------------------)
(ARGUMENT VALIDATION)
IF [#1 EQ #0] THEN #3000=1(MISSING A - X POSITION)
IF [#2 EQ #0] THEN #3000=2(MISSING B - Y POSITION)
IF [#3 EQ #0] THEN #3000=3(MISSING C - DEPTH)
(-------------------------------)
(SAVE MODAL STATE)
#3003=1 (DISABLE SINGLE BLOCK)
#3004=1 (DISABLE FEED HOLD)
(-------------------------------)
(MACRO BODY)
G90 G00 X#1 Y#2
G43 Z5.0 H#11
G01 Z#3 F200.
... (probing logic) ...
(-------------------------------)
(STORE RESULTS)
#500=#5061
#501=#5062
(-------------------------------)
(RESTORE AND RETURN)
G90 G00 Z50.0
#3003=0
#3004=0
M99
See also: Argument Variables for the letter-to-variable mapping tables, Custom G/M Cycles for parameter setup, and Variable Types for local vs common variable scope.
References
- Peter Smid, Fanuc CNC Custom Macros, Industrial Press, 2004.
- Fanuc, Operator’s Manual / Parameter Manual, FANUC Corporation.
Have a question or want to contribute?
Contact us with corrections, additions, or topics you'd like covered.
Get in Touch