CNC Variables and Macro Programming — Parametric G-Code on Machining Centers

Standard G-code is static — every coordinate, feed rate, and depth is a fixed value written into the program. Macro programming adds variables, arithmetic, conditional branching, and loops, turning G-code into a programming language capable of handling parametric geometry, adaptive cycles, and complex automation.

On Fanuc controllers, this is called Custom Macro B. Haas and Siemens have equivalent implementations. The syntax differs between controllers, but the concepts are identical.

Variables

A variable is a storage location that holds a numeric value. Variables are referenced with a hash symbol followed by a number:

#1 = 25.0        (assign value 25.0 to variable #1)
G0 X#1           (move to X25.0 — X reads the value of #1)
#1 = #1 + 10.    (add 10 to #1 — now #1 = 35.0)
G0 X#1           (move to X35.0)

Variables can be used anywhere a numeric value appears in a G-code block.

Variable Types on Fanuc

Fanuc Custom Macro B defines three variable types:

Local variables (#1–#33)
Exist only within the current macro call. Reset to null when the macro ends. Used for temporary calculations within a subprogram.

Common variables (#100–#199, #500–#999)
Persist across subprogram calls and remain in memory even after the program ends. #500–#999 are retained even after power off (stored in battery-backed RAM). Used to pass values between programs or store machine-specific constants.

System variables (#1000 and above)
Read-only or read-write variables that interface with the controller — tool offsets, work offsets, current machine position, operator inputs, alarm states. Examples:

#5001    (current X position in G54)
#5002    (current Y position in G54)
#5003    (current Z position in G54)
#2001    (tool length offset H1)
#2101    (tool diameter offset D1)

Arithmetic and Functions

Macro B supports standard arithmetic operators and mathematical functions:

#1 = 50. + 10.          (addition: #1 = 60)
#2 = #1 * 2.            (multiplication: #2 = 120)
#3 = SQRT[#2]           (square root: #3 = 10.954)
#4 = SIN[45.]           (sine of 45 degrees: #4 = 0.7071)
#5 = COS[#4]            (cosine)
#6 = ATAN[1.]/[1.]      (arctangent: #6 = 45 degrees)
#7 = ABS[#1 - 100.]     (absolute value)
#8 = ROUND[#3]          (round to nearest integer)
#9 = FIX[#3]            (truncate to integer, toward zero)

Note: Fanuc uses square brackets [ ] for expressions, not parentheses (which are reserved for comments).

Conditional Branching — IF / GOTO

IF [#1 GT 100.] GOTO 100    (if #1 > 100, jump to N100)
IF [#1 EQ 0] GOTO 200       (if #1 = 0, jump to N200)

N100
(code executed when #1 > 100)
GOTO 999

N200
(code executed when #1 = 0)

N999

Comparison operators: EQ (=), NE (≠), GT (>), GE (≥), LT (<), LE (≤)

Loops — WHILE / DO

#1 = 1.                      (initialize counter)
WHILE [#1 LE 10] DO1         (loop while #1 <= 10)
  G91 G0 X10.                (incremental move)
  #1 = #1 + 1.               (increment counter)
END1                         (end of loop)
G90                          (restore absolute)

DO/END pairs are numbered 1–3, allowing up to three nested loops.

Practical Example — Bolt Circle

Drill 8 holes equally spaced on a 60mm radius bolt circle:

O9000 (BOLT CIRCLE MACRO)
#1 = 8.        (number of holes)
#2 = 60.       (radius)
#3 = 0.        (starting angle)
#4 = 360. / #1 (angle increment = 45 degrees)

WHILE [#3 LT 360.] DO1
  #5 = #2 * COS[#3]    (X position)
  #6 = #2 * SIN[#3]    (Y position)
  G99 G81 X#5 Y#6 Z-12. R3. F250
  #3 = #3 + #4         (advance angle)
END1
G80
M99

Call this macro from the main program with the bolt circle center as the active work offset. The same macro handles any number of holes at any radius — just change #1 and #2.

Reading Tool Offsets via System Variables

Macros can read and modify tool offsets at runtime:

#100 = #2001    (read tool 1 length offset into #100)
#101 = #2101    (read tool 1 diameter offset into #101)

IF [#101 LT 4.9] GOTO 500    (alarm if tool diameter is worn below 4.9mm)

This enables tool wear monitoring — the macro checks the offset against a minimum value and can trigger an alarm or skip the operation if the tool is worn.

Haas Macro Differences

Haas uses the same Macro B syntax as Fanuc with minor differences:

  • System variable numbering is largely compatible but not identical
  • Haas supports #TOOL_LENGTH and similar named variables in some firmware versions
  • M109 can display messages and capture operator input into a variable:
M109 P5    (display message from string variable #5, wait for operator input)

Simulate Macros Before Running

Macros with loops, conditional branches, and system variable reads execute differently depending on tool offset values and machine state. A logic error in a loop can cause the program to run indefinitely or skip critical operations. Eureka3X evaluates macro variables at simulation time, expanding the full execution path so you can verify the actual tool positions the macro will produce.

Try Eureka3X free for 30 days →

Related Articles

Start verifying your real G-code today.

Ensure your programs are safe and accurate with Eureka 3X Pro.

Start 30-Day Free Trial