"Macros" in Carbide Motion

I was going to PM @Julien , who’s been the biggest advocate of macros in CM, but I figured that others might want to chime in. A little background:

Users have requested “Macros” in Carbide Motion for a while and whenever I’ve asked specifically what they mean, they really seem to be looking for quick snippets of gcode that they can run from the MDI, not really “programmable macros”. That’s relatively easy as long as we can make the UI good.

We’re planning to get macros/snippets implemented in the near future and we wanted to see what you might be looking to do with them. Here are examples of what we have in mind:

  • Save multiple named work offsets that can be quickly changed.
  • Move the cutter to the current zero plus some Z height to verify that the Z-zero was properly set. (Our primary use-case)
  • Quick Z probing over the current XY position.
  • Move the router to the back to make it easier to load material.

If you’re of the more nerdy-power-user type, what else might you be looking to implement? How many macros would you have loaded?

@Julien- speak now or forever hold your peace.

(Regarding the UI, we’re planning to make them accessible from the main screen so you don’t need to go into the MDI to trigger a macro.)


One thought, macros stored in CM could be interpolated when loading a g-code file, using some syntax that doesn’t conflict with real g-code.

E.g. when a g-code file is loaded, [[SOMEMACRO]] would be replaced with the value stored in CM.

; some comment
G1 X10

I don’t know if this can be done via a macro, but I was just thinking about being able to “air draw” the current boundaries of the g-code file at a safe Z-height.


That’s a little outside of the scope of what we’re implementing but we might look at that in the future.

We’d have to implement that as a custom M-code in Carbide Motion but I think that’s doable.


I would use macros in the “run a few lines of custom gcode I have written and use a bunch” format (this is really a sub-routine) as well as the more advanced “do math and make decisions based on this variable” type.

I would love to be able to use my own probing routines more easily. I run mostly aluminum and being able to probe the work directly is very nice.

I would also use the true macros that are accessible via an M code while running gcode and make use of variables that can be written to, do math with and make logical choices with. Variables like that should also persist between restarts of CM.

I realize that true macros are probably out of scope for CM but at minimum I think it would be nice to have an M code that allows you to call one of several custom static gcode files you have created beforehand and run them like a sub-routine. I haven’t dug into this much on GRBL but being able to save your current state and location and then return to it after completing your custom sub-routine via variables accessed from inside that routine would be very nice. I suppose you could also get this info from CM if it was exposed as a variable. This last bit isn’t required but would make it easier to use. You could get around this by using relative motion in your static gcode. EDIT: I am wrong, you need to have the current state and position saved into a variable as you enter a sub-routine to truly make them useful.

1 Like

@robgrz This ‘replace placeholder with a pre-defined macro’ functionality is in UGS queue for release as an enhancement I wrote responding to a similar user base request. The ability to define and store pre-defined macros within the CM UI is one part, intercepting and replacing the placeholder ‘text’ within the gcode is the other. This also allowed me to write ‘remove rather than replace’ so say, M6T1 (a tool change command) is in the gcode but you don’t want to respond to this (or can’t), then it could be silently ignored (replaced with ‘’) within the control of the sender app.
Complexity increases with all these features, and I know the conflict between first user simplicity versus requested functionality is a current topic too.


I echo being able to probe a conductive material using something like a tooling pin and BitZero upside down. Being able to probe a hole and use that as XY zero would be awesome.

A quick “go to” a relative or absolute position.


How about taking existing actions, and making them editable macros?

For example - Homing is (I think) $H. Make it editable, and I can have the machine home, then travel to a particular spot, say for a toolchange.

Actually, being able to replace the action may be problematic, but can we have pre / post macros on some exiting actions?

How ‘pseudo-variables’ that macros can use that are replaced at runtime? For example. the extents of whatever program is loaded, or being able to say “Move to ZMax”, whatever that is without hard coding it to the values of my particular machine. It would make sharing macros much easier.

Technically you can probe a hole and use it as XY zero now. Just pretend you have the BitZero V2 and tell it to probe for X and Y. I think it would be better to not have to pretend you have a V2 probe but the functionality does work.

1 Like

In terms of pure G-code / static macros, I would use them for :

  • customizable work offsets / rapid positions. By the way, I often find myself scribbling X0/Y0 coords on a post-it note, and this have saved me a number of times, so if there could be a button that reads “memorize current location”, which automatically generates the G-code macro to return to those absolute coords later, and puts it into one of the macro slots, that would be quite helpful. You could have two or three slots with this associated “memorize current location” button, to memorize a few different locations

  • a macro that lowers Z0 by a small number. For when I just ran a surfacing pass, realize I need to shave off another fraction of a mm, and I just want to rerun the same surfacing file. What I do currently is move the endmill to a safe place, lower Z below Z0, reset Z0, run. Sure, a much faster way in a positive number

  • [nerdy] with the upcoming release of the C3D spindle, a warm-up routine that ramps the spindle from very low RPM to max RPM, at the beginning of the day in the shop. There’s a debate whether such a warmup is really required, but I err on the side of caution/care. Loading and running a warm-up G-code file feels unnatural.

  • [nerdy+] start the spindle at 1000RPM. I use this when I need to use my edge finder. Sure, I could type a single M3 command manually, but clicking a button is even easier / less mouse & keyboard action.

  • [nerdy++] a macro that just moves X/Y by a known offset and sets X0/Y0 there, for when I use the laser pen attached to my spindle to visually zero on a X/Y point on the stock.

  • [Not a macro, but since I’m here…]: when a G-code file is loaded, a button to hover the router above the stock, along the boundaries of the movements (I like this feature in LightBurn, you have a “frame” button for this). Very useful to double check that the job will not exceed travel limits (or hit a clamp). The way I see it, CM could generate/populate a macro that does that.


Here’s a test. How about a macro button that would take CM out of “Beginner’s Mode?” :smiley:

Not exactly a macro, but I would like CM to check a directory for an executable file that has the same name as the letters for current Gcode instruction, passing the arguments to the executable.

Once the executable has finished executing, then send the instruction to the machine.

This could be used to contextually run utility programs to do a variety of useful things… such as turn a light on to say it’s okay to change the tool:)

Hasn’t a version of you last point been suggested before where CM could even just flash a warning after comparing the global coordinates versus the work coordinates and project travel extents. A soft warning saying that the file exceeds the work envelope would be a nice feature.

1 Like

I would like Macros to be usable as variables. List the variables in the beginning of the program or a separate page. #100 = 24 #101=12 and so on.
The program would be edited to look like.
G01 X#100 Y-#101
This would allow for one program to be used for various sizes of the same parts. or to create repeatable patterns by having math functions in the program. G01 X(#100+#103) or building macros #100=#100+10
This can also be used for thicker or thinner stock to add or remove passes.


Old programmer joke:

Claim: I am a hugely productive programmer! I write programs which are hundreds of thousands of lines long!

Rejoinder: You should learn to use loops.

variables, loops, math (including trig functions), conditionals — let’s make this Turing-complete.


Maybe not a macro, but I would like temporary offsets (G92) so I could use my laser engraver without having to rezero my WCS.

For macros, I would like one that I can use in conjunction with the above offset to turn laser mode $32 off and on.

I am using cncjs, which has some limitations but I can put gcode in the beginning of my laser nc files to turn laser lode on and add a G92 offset. And then at the end of the file, it cancels the offset. Can CM pass GRBL commands (ie $32=1) to the controller from within an nc file?

Any chance we might be able to keybind them, for those of us who use things like the Stream Deck?


Maybe, depending on how the initial rollout works.


Did you just let a cat out of a bag?