Calling Custom Macros Through Modal Commands

While G65 does not enable users to simply and easily carry out Custom Macros in multiple locations, G66 and G66.1 provide modal solutions for doing so.


Facebook Share Icon LinkedIn Share Icon Twitter Share Icon Share by EMail icon Print Icon
A stock photo of a woman operating a CNC machine

If you have programmed with Custom Macro, you probably know that one way to call a Custom Macro program is to use a G65 command. Users typically input this command in a main program, specifying the program number for the Custom Macro (with a P-word) and a series of letter address arguments (variables) to pass to the Custom Macro.

Consider the following command for calling a round pocket-machining Custom Macro:

  • N050 G65 P1000 X5.0 Y5.0 Z0 D0.5 R0.75 F5.0

X and Y specify the pocket center location. Z indicates the surface where the machine will make the pocket. D is the depth and R is the pocket radius. F specifies the machining feed rate.

G65 is not modal. To machine another round pocket in a different location, the user must provide another complete G65 command (changing the related arguments, of course). FANUC CNCs have, however, two G-codes for modally calling a Custom Macro: G66 and G66.1. After instating either of them, the programmer must use G67 to cancel them.


G66 does not call the Custom Macro by itself; it will only assign the local variables that correspond to the specified letter address arguments. Consider these commands:

  • .
  • N050 G66 P1000 Z0 D0.5 R0.75 T0.5 F5.0
  • N055 G00 X5.0 Y5.0
  • N060 X10.0
  • N065 Y10.0
  • N070 X5.0
  • N075 G67
  • .

Line N050 sets local variable #26 to the value of Z, #7 to the value of D, #18 to R, #20 to T and #9 to F. But, again, this line does not call Custom Macro O1000.

In the next command (N055), which must be a motion command (usually G00 or G01), the CNC will move to the commanded position and then call Custom Macro O1000. Local variables assigned in the G66 command will be available for use in the Custom Macro, but there is no way to update them after executing the G66 command. The CNC will continue to move into position and call the Custom Macro in subsequent motion commands until it reaches the G67 (N075) command.

Here is an example of the round pocket Custom Macro when using G66:

  • O1001 (Custom Macro called by G66)
  • #32=#5001 (Attain current X absolute position)
  • Z[#26+0.1] (Move to approach position)
  • G01 Z[#26-#7] F[#9/2] (Plunge into pocket)
  • G02 X[#32+#18-#20/2] R[[#18-#20/2]/2] F#9
  • I-[#18-#20/2]
  • X#32 R[[##18-#20/2]/2]
  • G00 Z[#26+0.1]
  • M99


Like G66, a G66.1 command will specify the Custom Macro number and set local variables to the value of letter address arguments. Also like G66, a G67 command must eventually be specified to cancel the modal calling. But unlike G66, G66.1 will call the Custom Macro. Consider these commands:

  • .
  • N050 G66.1 P1001 X5.0 Y5.0 Z0 D0.5 R0.75 T0.5 F5.0
  • N055 X10.0
  • N060 Y10.0
  • N065 X5.0
  • N070 G67
  • .

Now, line N050 will machine the first pocket. In each subsequent command which is not a motion command, the CNC will reset the local variables and call the Custom Macro again. In line N055, the value of local variable #24 (X) becomes 10.0. Assuming the programmer wrote the Custom Macro correctly, a motion command in the Custom Macro will move the tool to this position before the machine begins creating the pocket.

The advantage of G66.1 over G66 is that any of the letter address arguments can change during any of the times the user calls the Custom Macro. If the depth of the pocket changes for the pocket N060 machines, for instance, the programmer can include the letter address D in line N060.

Creating Custom Macros using G66.1 is more involved than G66. Since the values of all the local variables return to vacant at the M99 command that ends the Custom Macro, users must store these values in common variables that are not lost until the power is turned off.

Consider this Custom Macro program using G66.1:

  • O1001 (Custom Macro called by G66.1)
  • (Change values for arguments included in the calling command)
  • IF [#24 NE #0] THEN #100 = #24
  • IF [#25 NE #0] THEN #101 = #25
  • IF [#26 NE #0] THEN #102 = #26
  • IF [#7 NE #0] THEN #103 = #7
  • IF [#18 NE #0] THEN #104 = #18
  • IF [#20 NE #0] THEN #105 = #20
  • IF [#9 NE #0] THEN #106 = #9
  • G00 X#100 Y#101 (Move to pocket center)
  • Z[#102+0.1] (Move to approach position)
  • G01 Z[#102-#103] F[#106/2] (Plunge into pocket)
  • G02 X[#100+#104-#105/2] R[[#104-#105/2]/2] F#106
  • I-[#104-#105/2]
  • X#100 R[[#104-#105/2]/2]
  • G00 Z[#102+0.1]
  • M99

Which Is Better?

While it requires more programming work, G66.1 provides more flexibility than G66. Namely, the programmer can change any argument in any of the commands between the G66.1 and the G67 command. In our example, this means the pocket’s X/Y position, radius, depth, Z-surface location or feed rate. In this sense, a Custom Macro called with G66.1 behaves almost exactly like any hole-machining canned cycle, like G81.

On the other hand, if you are sure there will be no need to change things after specifying the initial set of arguments, using G66 may be more suited to your application, since G66 is so much easier to use.