Macro programming is a way of writing flexible programs by using variables, mathematical operations and conditions instead of the fixed numbers in a CNC program. In a normal program the hole positions are written one by one; in a macro program the start position, hole spacing and hole count are defined as variables, and the program calculates the coordinates automatically.
Macro programming is especially useful for similar parts of different sizes, regular hole patterns, repeated pocket and slot operations, automatic coordinate calculation by dimension, evaluating probe results, tool-life/breakage checking and stopping the program under certain conditions. The examples here are written to teach the general FANUC-type macro (Custom Macro) logic.
Macro Program vs Normal Program
A normal CNC program contains the coordinates and cutting values directly. In a macro program these values can come from variables:
#100 = 20. (start X position)
#101 = 20. (start Y position)
#102 = 20. (hole spacing)
G00 X#100 Y#101The meaning of each variable is decided by the programmer; the program uses these values to calculate the coordinates.
What Is a Macro Variable?
A macro variable is a memory location into which a numeric value can be stored. The common form is #100 = 25.; this assigns the value 25 to variable #100. The variable can then be used inside a coordinate, feed or calculation:
#100 = 25.
#101 = 40.
G00 X#100 Y#101 (the tool moves to X25 Y40)Variable groups
The meaning of variable numbers can differ between controls. On FANUC-type controls these groups are generally seen:
| Variable group | General use |
|---|---|
| #1–#33 | Local variables |
| #100–#199 | Common variables |
| #500–#999 | Persistent common variables |
| System variables | Offset, position, alarm and control data |
These ranges may not be the same on every control. System variables in particular must not be used without consulting the machine manual. At beginner level, common variables such as #100 and #101 can be used in example programs.
Assigning Values and Doing Math
A variable can take a constant, another variable, or the result of a calculation:
#100 = 30.
#101 = #100 (takes the value of another variable)
#102 = #100 + 20. (if #100=30, then #102=50)The basic math operations are addition, subtraction, multiplication and division. Square brackets are used to set the order of operations:
#100 = #101 + #102
#100 = #101 - #102
#100 = #101 * #102
#100 = #101 / #102
#100 = [#101 + #102] / 2. (average of two values)For example, if #101 = 20. and #102 = 60., then #100 = [#101 + #102] / 2. gives #100 = 40. This can also be used to find the centre between two surfaces measured with a probe.
Common math functions
If the control supports them, functions such as SIN[], COS[], TAN[], ATAN[], SQRT[], ABS[], ROUND[], FIX[], FUP[] may be available. For example, #100 = SQRT[100.] gives #100 = 10. Sine and cosine can be used for circular hole patterns; however, whether the trigonometric angle unit is degrees or something else must be verified from the control manual.
The IF Condition
IF makes an action happen when a given condition is true. The basic logic is IF [condition] GOTO line:
IF [#100 EQ 0] GOTO 100 (if #100 equals zero, go to line N100)
...
N100| Operator | Meaning |
|---|---|
| EQ | Equal |
| NE | Not equal |
| GT | Greater than |
| GE | Greater than or equal |
| LT | Less than |
| LE | Less than or equal |
The values entered at the start of a macro can be checked. For example, if the hole count is entered as zero or negative, the program should not continue:
IF [#103 LE 0] GOTO 900
...
N900
#3000 = 1 (HOLE COUNT INVALID)The use of user-alarm variables such as #3000 can differ between controls; it must not be used at random and should be verified from the machine manual.
The WHILE Loop
WHILE makes a section of the program repeat as long as a condition stays true. The common format is WHILE [condition] DO1 ... END1:
#100 = 1
WHILE [#100 LE 5] DO1
...
#100 = #100 + 1
END1This section runs five times; DO1 and END1 mark the start and end of the same loop.
Loop counter and infinite loops
The variable that tracks the repeat count inside a loop is called the counter, and it is increased at the end of each pass (#100 = #100 + 1). If the counter is not increased, the WHILE condition can stay true forever and an infinite loop occurs:
(RISKY – infinite loop because the counter is not increased)
#100 = 1
WHILE [#100 LE 5] DO1
G00 X20
END1Parametric Linear Hole Pattern
The example below shows the basic macro logic for drilling equally spaced holes in X. Variables: #100 first hole X, #101 Y, #102 hole spacing, #103 hole count, #104 counter.
%
O5000
G17 G21 G40 G49 G80 G90
T01 M06
G54
S1200 M03
G00 X0 Y0
G43 H01 Z50
M08
#100 = 20.
#101 = 30.
#102 = 25.
#103 = 4.
#104 = 1.
G00 X#100 Y#101
G98 G81 Z-15. R2. F120.
WHILE [#104 LT #103] DO1
#100 = #100 + #102
X#100 Y#101
#104 = #104 + 1.
END1
G80
G00 Z50
M09
M05
M30
%Note: Inside the loop the positioning line is written as X#100 Y#101, not with G00. This is because G00 and G81 are in the same modal group, and writing G00 inside the loop can cancel the active drilling cycle. Since G81 stays modal, a hole is drilled automatically at each new X position. This behaviour should be verified for the control.
How the program works
The first hole is drilled at X20 Y30 on the G81 line. On each pass #100 = #100 + #102 is calculated: 20 + 25 = 45 on the first pass, 45 + 25 = 70 on the second, 70 + 25 = 95 on the third. When the counter reaches the hole count, the WHILE loop ends. The hole positions come out as X20, X45, X70 and X95.
Calling a Macro with G65 and Local Variables
A macro can be called like a subprogram. On some FANUC-type controls, in the call G65 P9000 A20. B30. C25. D4. the values sent with letters are transferred to local variables; depending on the control structure, mappings such as A → #1, B → #2, C → #3 may apply. However, the letter-to-variable mapping must be verified for the control, so G65-based macros must not be copied directly to another machine.
Macro Program vs Subprogram
| Subprogram | Macro program |
|---|---|
| Repeats fixed moves | Calculates from variable values |
| Called with M98 | Can use a macro call such as G65 |
| Coordinates are mostly fixed | Coordinates can be calculated automatically |
| Suitable for simple repeats | Works flexibly at different sizes |
| Limited logical control | IF and WHILE can be used |
A macro program can be thought of as a more flexible, calculation-capable form of a subprogram.
Common Macro Mistakes
- Not giving a variable a starting value
- Using the wrong variable number
- Not increasing the counter (infinite WHILE loop)
- Writing the EQ, GT or LT condition the wrong way round
- Leaving out square brackets
- Dividing by zero
- Not checking the G90/G91 state
- Leaving G80, G40 or other modal states active at the end of the macro
- Changing system variables without consulting the manual
- Testing the program directly on a real part at full speed
Safe First Test
- Calculate the variable values on paper; work out the first and last coordinate.
- Verify how many times the loop will run.
- Run a graphic simulation; test the program first without cutting.
- Use Single Block; lower the Rapid Override.
- Watch the active variables on the macro-variable screen.
- Check the first and last move positions; follow the program flow in case of an infinite loop.
Even if a macro calculates correctly, a wrong starting value can send the tool to the wrong point.
Mentor CNC Disclaimer and Safety Notice
Macro variable ranges, the G65 call structure, the mapping of letters to local variables, system variables, user alarms and the WHILE syntax can differ between controls. The examples are written to teach the general FANUC-type macro logic. Before use on a real machine, review the control’s programming manual and test the program with graphic simulation, Single Block and low Rapid Override.