Argument Variables
There are two styles of passing arguments: Argument 1 and Argument 2.
For Argument 1, you can pass letters in sequential order. For example A1 B2 C3 D4 E5. Note that not all controllers let you pass every letter of the alphabet, but the key concept is that you can pass letters past A, B, and C and each one gets its own specific local variable number.
For Argument 2, you can only pass six letters as arguments A, B, C, and I, J, K. But you can pass an arbitrary number of I, J, K arguments into the macro. The macro can be coded to account for however many get passed in, which gives a lot of flexibility. This is effectively a way you can pass array data into a macro as an argument.
Argument 1 vs Argument 2
Argument 1
| Argument 1 | Variable |
|---|---|
| A | #1 |
| B | #2 |
| C | #3 |
| D | #7 |
| E | #8 |
| F | #9 |
| G | N/A |
| H | #11 |
| I | #4 |
| J | #5 |
| K | #6 |
| L | N/A |
| M | #13 |
| N | N/A |
| O | N/A |
| P | N/A |
| Q | #17 |
| R | #18 |
| S | #19 |
| T | #20 |
| U | #21 |
| V | #22 |
| W | #23 |
| X | #24 |
| Y | #25 |
| Z | #26 |
Argument 2
| Argument 2 | Variable |
|---|---|
| A | #1 |
| B | #2 |
| C | #3 |
| I1 | #4 |
| J1 | #5 |
| K1 | #6 |
| I2 | #7 |
| J2 | #8 |
| K2 | #9 |
| I3 | #10 |
| J3 | #11 |
| K3 | #12 |
| I4 | #13 |
| J4 | #14 |
| K4 | #15 |
| I5 | #16 |
| J5 | #17 |
| K5 | #18 |
| I6 | #19 |
| J6 | #20 |
| K6 | #21 |
| I7 | #22 |
| J7 | #23 |
| K7 | #24 |
| I8 | #25 |
| J8 | #26 |
| K8 | #27 |
| I9 | #28 |
| J9 | #29 |
| K9 | #30 |
| I10 | #31 |
| J10 | #32 |
| K10 | #33 |
Examples
Argument 1 Example
| G65 P1234 A1 B2 C3 D4 E5 F6 | ||||
|---|---|---|---|---|
| A | = | #1 | = | 1 |
| B | = | #2 | = | 2 |
| C | = | #3 | = | 3 |
| D | = | #7 | = | 4 |
| E | = | #8 | = | 5 |
| F | = | #9 | = | 6 |
| G65 P1234 A1 D2 H3 K3 M5 V6 Z7 | ||||
|---|---|---|---|---|
| A | = | #1 | = | 1 |
| D | = | #7 | = | 2 |
| H | = | #11 | = | 3 |
| K | = | #6 | = | 4 |
| M | = | #13 | = | 5 |
| V | = | #22 | = | 6 |
| Z | = | #26 | = | 7 |
Argument 2 Example
| G65 P1234 A1 B2 C3 I4 I5 I6 | ||||
|---|---|---|---|---|
| A | = | #1 | = | 1 |
| B | = | #2 | = | 2 |
| C | = | #3 | = | 3 |
| I | = | #4 | = | 4 |
| I | = | #7 | = | 5 |
| I | = | #10 | = | 6 |
| G65 P1234 A1 I2 J3 K4 I5 J6 I7 | ||||
|---|---|---|---|---|
| A | = | #1 | = | 1 |
| I | = | #4 | = | 2 |
| J | = | #5 | = | 3 |
| K | = | #6 | = | 4 |
| I | = | #7 | = | 5 |
| J | = | #8 | = | 6 |
| I | = | #10 | = | 7 |
G65 Macro Call Syntax
The G65 command is the standard method for calling a custom macro with arguments. Full syntax:
G65 P____ [L____] [A__] [B__] [C__] [D__] ... [Z__]
P = Program number to call (required)
L = Repeat count (optional, default 1)
A-Z = Argument values mapped to local variables #1-#33
When G65 executes, the control creates a new local variable scope. All 33 local variables (#1-#33) start as null, then any argument letters on the G65 line are loaded into their corresponding variables. The called program runs until M99, then control returns to the line after G65.
The L (repeat) parameter runs the macro multiple times with the same arguments. For example, G65 P9100 A5.0 L3 calls O9100 three times, each time with #1=5.0.
G65 supports up to 4 levels of nesting — a macro called by G65 can itself call another macro with G65, up to 4 deep. Each level gets its own independent set of local variables (#1-#33).
Forbidden Address Letters
Five letters cannot be used as arguments in a G65 call:
| Letter | Why It's Reserved |
|---|---|
| G | Conflicts with G-code addresses — the control would interpret it as a preparatory command |
| L | Reserved for the repeat count in G65 syntax |
| N | Reserved for sequence (line) numbers |
| O | Reserved for program numbers |
| P | Reserved for the program number being called in G65 |
Attempting to use these letters as arguments will either cause an alarm or be interpreted as their standard CNC function.
Modal Macro Call (G66 / G67)
G66 activates a modal macro call: the specified macro is automatically called after every subsequent motion block (G00, G01, G02, G03) until G67 cancels it.
G66 P9200 A0.5 B1.0 (ACTIVATE MODAL MACRO)
G81 X1.0 Y1.0 Z-0.5 R0.1 F10. (DRILL - THEN MACRO RUNS)
X2.0 Y2.0 (DRILL - THEN MACRO RUNS AGAIN)
X3.0 Y3.0 (DRILL - THEN MACRO RUNS AGAIN)
G67 (CANCEL MODAL CALL)
G80
Arguments are passed once on the G66 line and reused for every subsequent call. G66 uses the same argument-to-variable mapping as G65. Common uses include automatic chamfering after each hole, deburring, or custom inspection at each point.
G65 vs M98 Comparison
| Feature | G65 (Macro Call) | M98 (Subprogram Call) |
|---|---|---|
| Argument passing | Yes — letters map to #1-#33 | No argument passing |
| Local variable scope | New scope per call level | Shares parent scope |
| Nesting depth | Up to 4 levels | Up to 10 levels |
| Repeat count | L parameter | L parameter |
| Typical use | Parametric macros, probing cycles | Fixed subprograms, repeated geometry |
| Decimal precision | Arguments keep full decimal precision | N/A |
| Modal version | G66 (auto-call after each motion) | None |
| Syntax | G65 Pnnnn A_ B_ C_ ... | M98 Pnnnn [Lnn] |
Use G65 when you need to pass data into the called program. Use M98 when you just need to run a fixed subprogram with no variable input.
See also: Macro Structure for complete macro program organization, Variable Types for local vs common variable scope, and Custom G/M Cycles for parameter-mapped G-code macros.
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