CNCCookbook: Be a Better CNC'er


Parameterized Programming: Macro Variables

CNCCookbook's G-Code Tutorial


Introduction to the Mini-Tutorial on G-Code Macro Programming and Fanuc Macro B

The next several lessons in the tutorial stand together as a Mini-Tutorial on Macro Programming and Fanuc Macro B. In many ways, Macro Programming is the highest level of G-code Programming. It offers the most flexibility and the greatest potential power of any of the G-Code Programming Techniques. Without Macro Programming, G-Code is not really a full fledged computer language, it's more a recording of a series of manual steps. That's useful, but computers and CNC controllers are capable of a lot more.

A word about Fanuc Macro B

Fanuc Macro B is by far the most common Macro Programming Dialect. Not all controllers support full Macro B, and there are variations supported by some non-Fanuc controllers. We can't document every G-Code Dialect here, but the concepts offered in Macro B will be similar to what you see elsewhere, and therefore applicable to those cases with slightly different syntaxes and capabilities. If you don't have a controller with Macro B, it's still worth checking it out. Just use a our G-Wizard CNC Simulator and Editor to play with the Macro B capabilities.


Parameterized Programming

Until now, all of our g-coding has been done without any recourse to variables or formulas. If we wanted to go to a particular coordinate, we had to enter that coordinate, either absolute or relative, to get there. A tremendous amount can be accomplished in that way, but just as algebra is more powerful than arithmetic, so parameterized programming is more powerful than basic g-code, and for the same reasons. Once you have variables, you can start to parameterize your programming. You'll be able to create general purpose routines that use parameters to tie them to specific uses you want to make. Imagine being able to create your own custom canned cycles that can do almost anything. A custom drilling cycle, or perhaps a routine to automatically serial number your parts. Almost anything is possible.

Covering the whole of parameterized programming will involve three chapters in our tutorial. In this chapter, we'll be dealing with variables and formulas. The next chapter will delve into how to divide your code up into subprograms and access the subprograms. Lastly, we'll deal with macro control structures. Not all controls support parameterized programming. We'll be dealing with the Fanuc Macro B dialect for it, and we'll throw in mention where of Mach3's parameterized programming features as well.


Parameters to Customize the Machine to the Controller (aka Why We're Going to Quit Saying "Parameters")

You may have noticed that different companies often make the CNC Controller versus the actual machine tool. In fact, this is nearly always the case. There are a collection of settings inside the controller that are called parameters that are used to perform that configuration of the controller to the machine tool. For example, the travels, spindle speed range, rapid traverse rate, and many other types of information that are critical to making the control work right with the machine. For that reason, you don't want to go poking around with parameters too much, or you can scramble some of those settings. Reading a system variable is okay, but don't assign any values to them unless you know for sure what they do. You should make sure you have a good backup of all your parameters in case the battery fails on the controller or they get inadvertently changed. Typically there is a procedure available for your controller to use DNC to perform a backup.

Now here is the tricky part: Parameters and Macro Variables are Two Different Things!

I don't know why we like to call it "Parameterized Programming" and then immediately quit talking about Parameters, which have little to do with Parameterized Programming. It's tempting to think Parameters are just System Variables (more on what a System Variable is in a moment), but they're completely different. There are ways to set some Parameters from a part program, but this is not the most common way to deal with them--usually it's done via the control panel. Therefore, we'll be sticking to the term "variables" and will leave "parameters" for a future chapter.


What Are Variables?

First thing is first, what are variables? Simply put, they are just like algebra variables that you can use in your g-code. They can be assigned values, and when you refer to them, they give back the last value they were assigned.

The syntax for a variable is the pound sign followed by a number up to however many digits your controller supports that identifies the variable. For example, we can write "#1 = 100" to assign the value "100" to the variable "#1". There's even a special "null" value that says the variable never had a value assigned. The variable #0 always has a null value, and you can give any other variable a null value just by assigning #0 to it. For example:

#100 = #0 ( Make #100's value "null" )

These variables fall into ranges that affect their meaning and how they can be used. Here is how Fanuc thinks of these ranges, for example:

Variable Number
Type of Variable
#0 Null You can never assign a value to #0, it's value is always "null", which means "no value."
#1 - #33 Local Variables Local variables are used to pass arguments to macros and as temporary scratch storage. Your controller won't remember the value of any local variables when the power is turned off. Local variables nest when used with suprograms, so be sure you understand how that works.

#100 - # 199

#500 - #999

Common Variables Common Variables are shared by all your macro programs. When the power is turned off on the controller, #100 - #199 are cleared to null. #500 - #999 remember their values for the next time power is turned on.
#1000 and up



System variables can be used to tell things about what the controller is doing, such as the current position. Don't assign anything to these unless you know what they do!

Fanuc Macro Variables: Note that these ranges may vary across controllers and especially for non-Fanuc controllers!

Mach3 has 10,320 variables available, from #0 to #10320. There's not quite the variety found in Fanuc, but still, plenty of system variables are accessible so you can get at things like work offsets. Mach3's variables are saved from one control boot up to the next, so be sure to reset them if you aren't expecting them to have a value.

What Are Variables Good For?

Use variables whenever you think you might want to change a value in different situations. For example, suppose you have a macro or subprogram that cuts a square pocket. You probably want to have variables that let you define the size of the square and the feeds and speeds so they may vary as the material changes. Depending on the subprogram, you might want a variable for the top left corner of the square, or you might simply let that corner be the current position when the routine is called. You may want a variable defining the depth of the square pocket. And lastly, you may want a variable that defines the diameter of the tool.

Which Variables Should I Use in My Programs?

System Variables and Local Variables have some special behaviors, so steer clear of those unless you specifically want those behaviors. System variables refer to specific things going on in the controller, so are not usable as general purpose variables. Local Variables exhibit "nesting" behavior with macros, so wait until you have read about macro subprograms and understand them before deciding to use a Local Variable.

Common Variables are there for the taking, so try to stick to using those variables for general purpose programming.

When Variables Can't Be Used

Most addresses (remember word address format?) can be variables, but not all. For example, I can't have a sequence number that is a variable. N#10 is not allowed. Here is a short list of the "not alloweds":

- Program Numbers: O#10 is not allowed. Neither is :#10 for controls that allow ":" for program numbers.

- Sequence Numbers: N#10 is not allowed.

- Block Skip Address: /1 is okay but /#1 is not allowed.

- WHILE..DO..END Addresses: DO1 is allowed, DO#1 is not.


Expressions: Formulas

Formulas used in parameterized programming are called Expressions. They work pretty much as you'd expect algebraic formulas to work with a few things to keep in mind:

- G-Code uses square brackets ("[" and "]") instead of parenthesis, since parenthesis are used for comments. It looks kind of strange, but you get used to it pretty fast. So, instead of:

#1 = (#2 * #3) + #4

you need to use:

#1 = [#2 * #3] + #4

- The standard operators are add ("+"), subtract ("-"), multiply ("*" asterisk and not "x"!), and divide ("/").

- The minus sign is also used for negation. Think of it as multiplying whatever follows by -1.

- There is a list of other operators and functions that may be somewhat control-dependant. Make sure you check your manual to see if your control supports them and if so just how they work. Here is a list of operators and functions for Fanuc and Mach3:

Fanuc Uses
Mach3 Uses
Arithmetic Functions
#1 ** #2
#1 ** #2 raises #1 to the power #2. Power takes precedence over the other operators.
Modulus divides and returns the remainder. So 5 MOD 2 is the remainder of 5 divided by 2, which is 1. The modules of 4 divided by 2 is 0. Mod is a convenient way to keep a value with a range of 0 to the MOD divisor.
Absolute Value
Absolute value. ABS(1) = 1. ABS(-1) = 1.
Rounding Down
Rounds down to the next smaller integer. FIX(2.8) = 2, FIX(-2.8) = -3.
Rounding Up
Rounds up to the next larger integer. FUP(2.8) = 3. FUP(-2.8) = -2.
Rounding Off

When used in a macro function like IF, ROUND rounds down by slicing off the fractional decimal places. ROUND(1.1) = 1.0. ROUND(-1.1) = -1.0.

When used as a coordinate address, ROUND rounds off to the least input increment of the address = 0.001 for mm and 0.0001for inches.

Square Root
Natural Logarithm

Trig Functions

(Units are Degrees, 90 degrees 30 seconds = 90.5)

Arc Cosine
Arc Sine
Arc Tangent
Logical Functions
Logical OR
Logical AND
Logical XOR
Other Functions
Convert from BCD to BIN
See your Fanuc manuals for more details on these specialized functions.
Convert from BIN to BCD
See your Fanuc manuals for more details on these specialized functions.

Fanuc and Mach3 Expression Operators and Functions...


Tip: When in doubt about the order a formula will be calculated in, use extra brackets

Most of us learned tricks in grammar school for how to remember what order to perform arithmetic operations in. The one I learned was "My Dear Aunt Sally", which translates to "Multiplication then Division then Addition then Subtraction." Because of that order (called an order of precedence), these two formulas have an identical result:

#1 = [#2 * #3] + #4

#1 = #2 * #3 + #4

But this can get confusing. Always use extra brackets to make the order clearer at a glance.


Calculating Which Variable to Access

This is kind of a trick, but you can calculate which variable to access. Instead of retrieving #107, you could write #[100 + 7], or any other expression inside the square brackets. This is often useful when you want to loop through variables that are grouped together in a certain way. You can even write #[#2], which is the variable whose identity is the value stored in variable #2. So, if the value of #2 was "10" and we write "#[#2]", it is the same as writing "#10". Some controls will tolerate "##2", but most won't, so get in the habit of using the square brackets.


Macro Variables and Expressions in G-Wizard Editor

Our G-Wizard CNC Simulator and Editor understands macro variables and expressions, so you can use it to experiment with them a bit. Just bring it up and type in the expressions you want to see. Use the Simulator / Debugger to step through and see the results.

For example:

Macro variable and expression debugging

Debugging Macro Variables and Expressions with G-Wizard Editor...

Just type your expressions on the left. In this case, we have a pretty simple set:

#100 = 10
#101 = #100 * 2
#102 = [[#101 / 3] + 6]

Now, put the debugger in Single Block by selecting the button just left of the Tortoise.

As you step through a block at a time, the variables values are show in the box right below the backplot:

Macro variable values

Macro variable values are shown below the backplot...

This little window shows all the modal activity, for example, we're in G00 - Rapids mode. The values of Macro Variables are also modes of sorts, so they're shown too. You get to see values for the last n variables whose value changed, and they're sorted by variable #. Note how it also gives you a little hint about what the variable does. For example, it says #100, #101, and #102 are "Volatile Common Variables". "Volatile" means their values are not remembered when the controller is switched off, and as we saw from the table up near the top of this page, variables in this range are Common Variables. G-Wizard doesn't have all the variable values, but is has an awful lot of them and it will try to use this information to help you understand what's going on.

You can see the full list of what it understands by looking under Setup, Post, Variables:

Macro Variable Setup in GWE

This screen is useful for a number of purposes. You can immediately see the current value of any variable, for example (anyone see the bug in the screen above? GWE has made a mistake on one of the variables). You can change the value of any variable just by double clicking it too. And you can see the different groupings for the variables with the row of buttons right above the table. The groupings will help you narrow things down to a particular thing you're looking for, such as a Work Offset variable.



That was a lot of information, but you're now equipped to start parameterizing your g-code programs in ways that should make it possible to reuse the g-code in multiple situations instead of always having to rewrite the code for each individual situation. Good CNC programmers start to accumulate a library of useful g-code subprograms that are tested and ready to go the next time a similar task is at hand.



1. Pull out your CNC controller manual and see what differences exist between your controller and what's described here.

2. Use GWE to experiment with Macro Variables and Expressions until you've got a good grasp of them.

3. Modify one of your existing G-code programs to use some variables and expressions. Verify that it still produces the correct results when you've finished.



Try the Free Trial Version of G-Wizard G-Code Editor...


No credit card required--just your name and email.


Next Article: Subprogram and Macros




CNCCookbook's G-Code Course


Featured Articles

Step-By-Step Guide to Making CNC Parts

CNC Router Cutter Types

Why Use a Single Flute Endmill?

Step and Servo Motor Sizing

The Truth About Tool Deflection

10 TIps for Router Aluminum Cutting

2 Tools for Calculating Cut Depth and Stepover

CNC Machine Hourly Rate Calculator

Special Purpose CNC Calculators

Feeds and Speeds Guide

CNC Cutter Guide

Feeds and Speeds By Material

G-Code Tutorial

Sales, and Special Deals


Feeds and Speeds:
Made Easy.

Try G-Wizard


GCode is complicated.
G-Wizard Editor
makes it easy.

Try It!



Do you want to be a better CNC'er?

Get Better Tool Life, Surface Finish, and Material Removal Rates.


Start Now, It's Free!