GreatLight CNC Machining Factory logo
CNC Machining
Rapid Prototyping
Materials
Industries
News
About GL

Get Instant Quote

Programming note

CNC macro programming essentials for shops that run repeat work

Macros exist to stop you from editing the same G-code 40 times a week. This page covers what macro variables actually store, how IF/GOTO and WHILE loops behave on a Fanuc-style control, how to pass values into a subprogram, and the cases where plain G-code is still the better answer.

Fanuc Macro B5-axis work±0.005 mm3–5 day ship
Custom auto spare parts cut on a 5-axis machine using CNC macro programming essentials
What a macro is

What CNC macro programming essentials actually cover

A macro is a program that can read the machine state, do arithmetic, and decide what to do next. Standard G-code cannot. It runs top to bottom and stops. If you want the same bolt-circle cycle at three different radii, you either write three programs or you write one macro and pass the radius in as a number.

On a Fanuc-style control the arithmetic lives in variables. #1 through #33 are local and get wiped when the macro returns. #100 through #199 and #500 through #999 are common variables that survive a power cycle on most machines. #1000 and up are usually tied to system data such as tool offsets, current position, or alarm state. Confirm the range on your own control before you write to it.

The practical gain is not speed of the spindle. It is speed of the setup. A parametric drilling cycle that accepts hole count, radius, start angle, and peck depth turns a 20-minute edit into a 20-second change. That matters most on families of parts, not on one-off work.

One boundary up front: macros do not fix a bad process. If the fixture moves, a macro just moves the error faster. Fix the setup first.

Variables

Variables, arguments, and how values get in

A macro call looks like this: G65 P9010 X50.0 Y25.0 R20.0 A0. B8. I-2.5. Inside program O9010, the letters map to local variables in a fixed order. X is #24, Y is #25, Z is #26, A is #1, B is #2, C is #3, I is #4, J is #5, K is #6, R is #18. Get that mapping wrong and the cycle runs at the wrong radius with no alarm.

You can also call a macro with G65 or with M-code aliases set in parameters, and you can call it as a subprogram with M98. G65 passes arguments, M98 P9010 L3 does not pass a value but will repeat the subprogram three times. Use G65 when the geometry changes, M98 when it does not.

Local variables reset to null on each call unless you use the G66 modal form or copy them out to common variables. A common mistake is storing a tool offset in #1 and expecting it next cycle. It is gone. Write it to #101 or #501 if it needs to persist.

Readability costs nothing and saves a lot. Comment the variable map at the top of the program: (X=#24 center X, Y=#25 center Y, R=#18 radius). Six months later, that comment is the difference between a two-minute change and an hour of decoding.

Control flow

IF/GOTO, WHILE, and conditional logic on the floor

The two workhorses are IF [condition] GOTO n and WHILE [condition] DO m ... END m. IF is a one-shot branch. WHILE loops back until the condition fails. Both compare using operators you write as brackets: EQ, NE, GT, GE, LT, LE, plus AND, OR, XOR. They evaluate as true or false, nothing else.

A typical use is depth stepping. Instead of hard-coding five Z passes, you write WHILE [#1 GT #2] DO 1, cut, then #1 = #1 - #3, END 1. Change the step size in one place and the loop count adjusts itself. That is the whole point of CNC macro programming essentials: one input, many passes.

Guarding is not optional. Add a check at the top of the macro: IF [#18 LE 0] GOTO 9999, then at N9999 write an alarm or a message. A macro that runs with a null radius will happily rapid the tool into the fixture. The control will not stop it for you.

Watch for infinite loops. If #1 never satisfies the exit condition, the WHILE never ends and the machine sits there. Always step the counter inside the loop body, and test the loop with the spindle in the air before you cut metal.

  • 1
    IF is a branch, WHILE is a loopIF runs once and jumps. WHILE repeats until false.
  • 2
    Step the counter inside the loopForget this line and the program hangs.
  • 3
    Guard every inputA null argument can send the tool into the vise.
  • 4
    Keep loops shallowNested DO loops read poorly and debug badly.
Real cycle

A bolt-circle drilling macro, step by step

The classic example is a bolt circle. Nine inputs: center X, center Y, start angle, hole count, radius, hole depth, peck depth, rapid plane, and feed. Everything else is computed. The macro converts the start angle and the index angle to radians, then loops once per hole using SIN and COS to find X and Y.

Written out, the loop reads: WHILE [#5 GT 0] DO 1, then #30 = #2 + #18 * COS[#3], #31 = #1 + #18 * SIN[#3], then a G81 or G83 at that position, then #3 = #3 + 360 / #4 and #5 = #5 - 1, END 1. Degrees to radians is the step people forget. Multiply by 0.017453.

The gain shows up on setup. A 12-hole flange becomes a 16-hole flange by changing one number. Same program, different R value. On the machines we run, that is a ten-second edit instead of a full re-post.

The limit is equally clear. If the hole pattern is irregular, if the holes sit on a spline, or if the part is a one-off, a macro costs more time than it saves. Write it once, use it a hundred times, or do not write it at all.

  • 1
    Radians, not degreesMultiply by 0.017453 before SIN or COS.
  • 2
    Count down, not upDecrement the hole counter so the loop exits cleanly.
When it pays

Where macros help and where they get in the way

Macros pay back on part families. A family shares geometry and varies in a few dimensions: length, hole count, boss diameter, thread depth. If you make that family more than a handful of times a year, the parametric program wins. The CAM post stops being the bottleneck.

Macros also pay on in-process checks. You can probe a datum, write the result to a common variable, and shift the work offset before the first cut. On a five-axis job with a long setup, that catches a fixture error before it becomes scrap. We run 16 simultaneous 5-axis centers where that check is standard practice.

They do not pay on one-off prototypes. A macro takes longer to write and prove out than a posted program. For a single part, posted G-code is faster and easier to verify. The trade-off is real: a macro is an investment in repeat work.

They also do not pay when the CAM system already handles it. If your post outputs a clean parametric cycle and the operator never edits it, adding a macro layer just adds a place for the two systems to disagree.

Safety

Proving out a macro before it cuts metal

Run the macro in single block with the tool at a safe Z. Watch the position display, not the code. Confirm each computed X and Y matches the drawing before you let it feed. A wrong COS sign is invisible on screen and obvious on the part.

Set a hard upper bound on any loop: IF [#5 GT 100] GOTO 9999. A runaway loop is rare but it wastes a shift. The guard costs one line.

Keep the macro in a protected program number and back it up off the machine. Controls lose memory. A macro that only exists on one control is a single point of failure.

Finally, document the arguments on the setup sheet. The operator needs to know that R is the radius in millimeters, not the rapid plane. Ambiguity here is where most macro scrap comes from.

Decision table

Macro vs plain G-code: which one fits the job

Match the programming method to the work, not to habit.

Job conditionUse a macroUse posted G-code
Part family with 3+ varying dimensionsYes, one program, many sizesNo, re-post each variant
One-off prototypeNo, write time exceeds run timeYes, fast to verify
Bolt circles or hole arraysYes, radius and count as inputsOnly if count never changes
In-process probing and offset shiftYes, reads state and reactsNot possible in plain G-code
CAM post already parametricRarely, adds a second source of truthYes, single source of truth
Operator edits dimensions at the machineYes, one number changes the cycleNo, edit means re-post
Five-axis tapered wall or swarf cutSometimes, for tool vector mathUsually, CAM handles the vectors
Anything with a null argument riskOnly with a guard at the topNot applicable

The short version

If the part repeats and only a few numbers change, write the macro. If it runs once, post the G-code and move on. There is no prize for parametric code on a one-off.

FAQs

Macro programming questions we get asked

Which variables survive a power cycle?

On most Fanuc-style controls, #100 through #199 and #500 through #999 are common variables that hold their value with the power off. Local variables #1 through #33 reset to null when the macro returns.

The exact range and behavior vary by control model and option. Check the manual for your machine before you store a tool offset or a work coordinate there.

What is the difference between G65 and M98?

G65 calls a macro and passes arguments through address letters such as X, Y, R, and A. M98 calls a subprogram. It repeats the block but does not hand it a value.

Use G65 when the geometry or the count changes between calls. Use M98 when the same fixed cycle just needs to run again.

Can I use macros on a lathe as well as a mill?

Yes. The variable and control-flow rules are the same across mill and lathe controls. What changes is the address-to-variable map, so verify it against the lathe manual.

Common lathe uses are family turning cycles, groove width steps, and thread depth passes driven by a single input.

How do I stop a macro from running with a bad input?

Put a guard at the top of the program. Test the critical arguments and branch to an alarm label if any of them is zero or negative.

A radius of zero or a null feed will not raise an error on its own. The control will simply execute it.

Does macro programming replace CAM software?

No. CAM still handles complex 3D surfacing, five-axis tool vectors, and rest machining far better than hand-written macros.

Macros are best for the parametric, repetitive cycles that CAM tends to output as fixed code. The two work side by side.

What tolerance can a macro-driven cycle hold?

The macro itself does not set tolerance. It computes positions. The machine and the process set the achievable result.

On our equipment, we hold ±0.005 mm and finishes from Ra 0.2–0.8 μm on the right setup, with 100% inspection before shipment.

Send us the part family and we will quote it

Upload a drawing and we return a quotation with a free DFM analysis within 12 hours. Production can start within 24 hours, and parts ship in 3–5 days.

12-hour quote100% inspectionNo minimum order quantityNDA on request

Follow

More from the shop floor

We publish setup notes, tooling trials and inspection data from the factory floor.

FacebookTikTokYouTubeLinkedInInstagramThreadsPinterest

Trusted by engineers and manufacturers worldwide

Tesla Ford Motor Company BYD Auto Denso Magna International Boeing Airbus Medtronic KUKA FANUC