Custom Macros
A macro is an NC program with variables, arithmetic and branching. It has variables, arithmetic, IF and WHILE,
and it can read the machine’s own state, so a program can adapt instead of assuming.
#100 = 25.4 (a variable)G1 X[#100 * 2] F500 (arithmetic, in brackets)IF [#100 GT 20] GOTO 90 (a decision)The variables
Section titled “The variables”| Range | Are | Live |
|---|---|---|
#1 … #33 | local: arguments and scratch | per call, cleared on return |
#34 … #99 | reserved: a write is a block error | always vacant |
#100 … #499 | common | lost at power-down |
#500 … #9999 | common, retained | kept when the machine is switched off |
#1000 upwards | system: the machine’s own state | see below |
Local variables are per call. A macro that calls another macro gets a fresh set, and the caller’s are still there when it returns. Calls can nest several levels deep.
Vacant is not zero
Section titled “Vacant is not zero”A variable that has never been given a value is vacant, written #0. It is not the
same as zero: it answers “was this ever set?”.
IF [#5083 EQ #0] GOTO 100 (tool 3 has never been measured)A macro that treats vacant as zero will use an unmeasured tool length of nothing.
The retained band is shared with the cycles shipped on the machine, which keep their settings there. Check what a machine macro uses before choosing a slot. The full map is in Macro Variables.
Calling a subprogram
Section titled “Calling a subprogram”A section repeated at several places, such as a bolt pattern or a pocket cut at four
positions, goes in a subprogram and is called with M98:
M98 P1000 (run program 1000, once)M98 P1000 L4 (run it four times)M99 at the end of the subprogram returns to the block after the call. M99 P120 returns
to block N120 instead.
A subprogram is an ordinary program in the program list. It shares modal state with the caller: the units, plane and work offset in force at the call are still in force inside it, and anything it changes is still changed on the way back.
Calling a macro
Section titled “Calling a macro”G65 calls a macro and passes arguments. Each letter lands in a numbered local:
G65 P9100 X10. Y20. Z-5. (call O9100 with X, Y and Z)Inside O9100, X arrives as #24, Y as #25, Z as #26. M99 returns.
G65 is the call this control implements. G66, the modal call that repeats on every
following block, is not.
Reading the machine
Section titled “Reading the machine”These are the system variables worth knowing. All are read-only from a program unless noted.
Where the machine is
Section titled “Where the machine is”| Variables | Hold |
|---|---|
#5021 … #5026 | machine position, X Y Z A B C |
#5041 … #5046 | position in the active work coordinate system |
#5061 … #5066 | where the probe last triggered |
Positions are published by the control. A program that tries to assign to one is rejected rather than quietly ignored.
Offsets and tools
Section titled “Offsets and tools”| Variables | Hold |
|---|---|
#5081 … | tool length: geometry plus wear. See Tool & Work Offsets |
#5221 … | work offset G54; each further system starts twenty later |
#5500 / #5600 | tool length geometry / wear |
#5700 / #5800 | tool radius geometry / wear |
#5211 … #5216 | the G92 shift |
#5220 | which work coordinate system is active |
#5161 / #5181 | the G28 and G30 reference positions |
What the machine is doing
Section titled “What the machine is doing”| Variables | Hold |
|---|---|
#3026 | the tool in the spindle |
#3901 / #3902 | parts made / parts required |
#1000 … #1031 | one PLC signal each, 0 or 1 |
#1032 | all thirty-two at once, as a number |
The PLC signals let a program branch on what the machine senses right now; see PLC Signals in Macros.
Stopping with your own message
Section titled “Stopping with your own message”Assigning to #3000 raises an alarm and stops the program:
IF [#1000 EQ 1] GOTO 10#3000 = 891 (fixture not clamped)N10This is how a macro refuses to run rather than cutting something wrong. The number is yours to choose and the text in brackets is what the operator reads.
Writing macros that survive
Section titled “Writing macros that survive”- Keep comments to plain ASCII. Accented and non-Latin characters in a comment can break the parse.
- Use
#100+ for anything that must outlive the call.#1…#33are gone the moment the macro returns. - Check vacancy before arithmetic.
#0in a calculation is not zero, and the result will not be what you expect. - Do not assume a value someone else wrote is fresh. Cycles that publish results also publish which run wrote them; see the result record.
Tool length and work offsets from a macro
Section titled “Tool length and work offsets from a macro”A macro reads it at #5081 onwards: #5081 is tool 1, #5082 is tool 2. It is not
stored anywhere; it is a live view over the two real columns:
- Reading it gives you
L.Geom + L.Wear, the number the control actually uses. - Writing it sets
L.Geomso that geometry plus the existing wear equals what you wrote. Your wear correction survives. - It is vacant (
#0) while a tool has never been measured, meaning neither geometry nor wear has ever been written. A macro can test for that:
IF [#5083 EQ #0] GOTO 100 (tool 3 has never been measured)Writing a work offset
Section titled “Writing a work offset”G10 L2 P_ X_ Y_ Z_ writes a work offset directly: P1 is G54, P2 is G55, and so
on. P is required.
G10 L20 is refused. Work out the value and write it with L2, or use
probing.
Where to go next
Section titled “Where to go next”- Probing from a Program:
G31and the result record, the most common thing to wrap a macro around. - PLC Signals in Macros: branching on what the PLC senses.