Macro Control Flow
Quick Reference
Fanuc Macro B provides three primary control flow mechanisms: conditional branching with GOTO, single-statement conditional execution with THEN, and iterative loops with WHILE/DO. The table below summarizes all three at a glance.
| Type | Syntax | Description |
|---|---|---|
| Conditional Branch | IF [condition] GOTO n | Jump to sequence number Nn if condition is true |
| Conditional Execution | IF [condition] THEN statement | Execute a single macro statement if condition is true |
| Unconditional Branch | GOTO n | Jump unconditionally to sequence number Nn |
| Combined Conditions | IF [[cond1] AND [cond2]] GOTO n | Compound tests using AND, OR, XOR |
| WHILE/DO Loop | WHILE [condition] DOm ... ENDm | Repeat block while condition is true (m = 1, 2, or 3) |
Conditional Branch (IF/GOTO)
The IF/GOTO statement evaluates a condition and, if true, transfers program execution to the specified sequence number. This is the most fundamental branching mechanism in Fanuc Macro B.
Syntax: IF [condition] GOTO n where n is a sequence number label (Nn in the program).
Comparison Operators
Six comparison operators are available for use inside the bracketed condition:
| Operator | Meaning | Example |
|---|---|---|
EQ | Equal to | IF [#1 EQ 0] GOTO 10 |
NE | Not equal to | IF [#1 NE #2] GOTO 20 |
GT | Greater than | IF [#100 GT 50] GOTO 30 |
LT | Less than | IF [#100 LT 0] GOTO 40 |
GE | Greater than or equal to | IF [#1 GE 10] GOTO 50 |
LE | Less than or equal to | IF [#1 LE #2] GOTO 60 |
Null Variable Gotcha
This is the single most common Fanuc macro debugging issue. In Macro B, an uninitialized variable is null (also called vacant), which is distinct from zero. The variable #0 is permanently null and is often used as a null reference.
| Expression | Result | Explanation |
|---|---|---|
#0 EQ 0 | FALSE | Null is not equal to zero |
#0 NE 0 | TRUE | Null is not equal to zero |
#0 EQ #0 | TRUE | Null equals null |
#1 EQ #0 | TRUE (if #1 unset) | Uninitialized variable is null, which equals null |
#1 EQ 0 | FALSE (if #1 unset) | Uninitialized #1 is null, not zero |
Always check for null explicitly when validating arguments: use #1 EQ #0 to test if an argument was omitted, not #1 EQ 0.
Example
O0001 (IF/GOTO EXAMPLE)
#100=5
IF [#100 GT 10] GOTO 50
(VALUE IS 10 OR LESS)
#101=#100*2
GOTO 99
N50 (VALUE IS GREATER THAN 10)
#101=#100*3
N99 (END)
M30
Conditional Execution (IF/THEN)
The IF/THEN form is a shortcut that executes a single macro statement when the condition is true. Unlike IF/GOTO, it does not require a target sequence number and does not branch — execution continues on the next line regardless.
Syntax: IF [condition] THEN macro-statement
Important: Only one statement is allowed after THEN. You cannot chain multiple statements or create multi-line blocks. If you need to conditionally execute multiple lines, use IF/GOTO to jump over them.
Examples
(UNIT CONVERSION - CONVERT INCHES TO MM IF NEEDED)
IF [#1 GT 0] THEN #100=#1*25.4
(ARGUMENT VALIDATION - ALARM IF MISSING)
IF [#1 EQ #0] THEN #3000=100(MISSING ARGUMENT A)
IF [#2 EQ #0] THEN #3000=101(MISSING ARGUMENT B)
(DEFAULT VALUE - SET TO 1.0 IF NOT PROVIDED)
IF [#3 EQ #0] THEN #3=#3+1.0
(INCREMENT COUNTER)
IF [#100 LT 999] THEN #100=#100+1
Unconditional Branch (GOTO)
The GOTO statement transfers execution unconditionally to the specified sequence number. Both forward and backward jumps are allowed.
Syntax: GOTO n where n is a sequence number or a variable containing a sequence number.
Computed GOTO
The target sequence number can be a variable, enabling computed or dynamic branching:
(COMPUTED GOTO - JUMP BASED ON VARIABLE VALUE)
#100=20
GOTO #100 (JUMPS TO N20)
N10 (CASE 1)
(... code ...)
GOTO 99
N20 (CASE 2)
(... code ...)
GOTO 99
N30 (CASE 3)
(... code ...)
N99 (END)
M30
Warning: Be careful with backward jumps. A GOTO that jumps backward without a conditional exit creates an infinite loop that will run until the operator hits reset or the machine alarms out.
Combined Conditions
Fanuc Macro B supports compound conditional tests using the logical operators AND, OR, and XOR. When combining conditions, each individual condition must be enclosed in its own set of brackets, and the entire compound expression is enclosed in an outer set of brackets.
Syntax: IF [[condition1] AND [condition2]] GOTO n
| Operator | Meaning | Result |
|---|---|---|
AND | Logical AND | True only if both conditions are true |
OR | Logical OR | True if either condition is true |
XOR | Exclusive OR | True if exactly one condition is true |
Examples
(RANGE CHECK - VALUE MUST BE BETWEEN 0 AND 100)
IF [[#1 GT 0] AND [#1 LT 100]] GOTO 10
#3000=110(VALUE OUT OF RANGE)
N10 (VALUE IS VALID)
(EITHER CONDITION MET)
IF [[#1 EQ 1] OR [#1 EQ 2]] GOTO 20
#3000=111(INVALID SELECTION)
N20 (SELECTION ACCEPTED)
(COMBINED WITH THEN - WORKS THE SAME WAY)
IF [[#1 NE #0] AND [#2 NE #0]] THEN #100=#1+#2
WHILE/DO Loops
The WHILE/DO loop repeatedly executes a block of code as long as the condition remains true. The loop identifier m can be 1, 2, or 3, allowing up to three levels of nesting.
Syntax:
WHILE [condition] DOm
(loop body)
ENDm
Nesting Levels
Fanuc allows a maximum of 3 nesting levels. Each level uses a unique identifier number:
| Level | Open | Close | Typical Use |
|---|---|---|---|
| 1 (outermost) | WHILE [...] DO1 | END1 | Main iteration (rows, passes, cycles) |
| 2 (middle) | WHILE [...] DO2 | END2 | Secondary iteration (columns, sub-passes) |
| 3 (innermost) | WHILE [...] DO3 | END3 | Innermost iteration (fine steps) |
Note: DO/END identifiers must be properly nested. You cannot cross-nest (e.g., DO1 inside DO2 that is inside DO1 is not allowed unless each pair is independently matched). Each DOm must have exactly one matching ENDm.
Infinite Loop Pattern
A common technique is the infinite loop using a condition that is always true, with a GOTO to exit:
(INFINITE LOOP - EXITS VIA GOTO)
WHILE [1 EQ 1] DO1
(... process something ...)
IF [#100 GE #101] GOTO 99
#100=#100+1
END1
N99 (LOOP EXITED)
Nested Loop Example
(NESTED LOOP - 10 ROWS x 5 COLUMNS)
#100=1 (ROW COUNTER)
WHILE [#100 LE 10] DO1
#101=1 (COLUMN COUNTER)
WHILE [#101 LE 5] DO2
(PROCESS ROW #100, COLUMN #101)
#102=[#100-1]*5+#101 (LINEAR INDEX)
#101=#101+1
END2
#100=#100+1
END1
Practical Examples
Counter Loop
A simple counted loop that iterates a variable from 1 to N, performing an operation each pass:
O0010 (COUNTER LOOP - DRILL N HOLES AT EQUAL SPACING)
(#1=A NUMBER OF HOLES)
(#2=B STARTING X POSITION)
(#3=C SPACING BETWEEN HOLES)
(#4=D Z DEPTH)
(#5=E FEED RATE)
IF [#1 EQ #0] THEN #3000=100(MISSING NUMBER OF HOLES)
IF [#4 EQ #0] THEN #3000=101(MISSING Z DEPTH)
#100=0 (HOLE COUNTER)
WHILE [#100 LT #1] DO1
#101=#2+[#100*#3] (CALCULATE X POSITION)
G81 X#101 Z#4 R0.1 F#5
#100=#100+1
END1
G80
M30
Search Loop
Scan through a range of variables to find a specific value. This pattern is useful for tool offset lookups or searching calibration tables:
O0020 (SEARCH LOOP - FIND VALUE IN VARIABLE RANGE)
(SEARCH #500-#531 FOR THE VALUE IN #1)
#100=500 (START INDEX)
#101=-1 (RESULT: -1 = NOT FOUND)
WHILE [#100 LE 531] DO1
IF [#[#100] EQ #1] THEN #101=#100
IF [#101 GT 0] GOTO 99
#100=#100+1
END1
N99 (SEARCH COMPLETE)
(#101 CONTAINS THE VARIABLE NUMBER WHERE VALUE WAS FOUND)
(#101 = -1 IF NOT FOUND)
IF [#101 LT 0] THEN #3000=200(VALUE NOT FOUND)
M30
Bolt Hole Pattern
A classic macro application: drill holes equally spaced around a circle. Uses trigonometry with Fanuc's degree-based trig functions:
O0030 (BOLT HOLE CIRCLE)
(#1=A BOLT CIRCLE RADIUS)
(#2=B Z DEPTH)
(#3=C NUMBER OF HOLES)
(#4=D STARTING ANGLE - DEGREES)
(#5=E FEED RATE)
IF [#1 EQ #0] THEN #3000=100(MISSING RADIUS)
IF [#3 EQ #0] THEN #3000=101(MISSING HOLE COUNT)
IF [#5 EQ #0] THEN #5=10.0
#100=0 (ANGLE COUNTER)
WHILE [#100 LT #3] DO1
#101=#1*COS[#100*[360/#3]+#4]
#102=#1*SIN[#100*[360/#3]+#4]
G81 X#101 Y#102 Z#2 R0.1 F#5
#100=#100+1
END1
G80
M30
In this example, #101 and #102 calculate the X and Y coordinates for each hole using cosine and sine. The angle for each hole is computed as #100 * [360 / #3] + #4, where #3 is the total number of holes and #4 is the starting angle offset. Fanuc trig functions operate in degrees, so no radian conversion is needed.
See also: Variable Types for null vs zero behavior, Macro Arithmetic for expression syntax, and Alarms & Timers for #3000 alarm generation.
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