Marlin Workspaces and Homing

In the past I had experienced some unexpected behavior in how Marlin handles work offsets, and in digging through the code recently, I finally understand why it behaves the way it does. Previously I thought that G28 performs an implicit G92, but this is not fully correct either.

When you set an offset using G92, it sets the current offset (position_shift) and also saves the shift to one of the workspace slots based on which workspace you’re currently in. Then switching workspaces with G55, G54, etc. loads the shift from the saved workspace slot and updates position_shift. Good enough so far.

The exception to the save/restore behavior is if you are in G53 native coordinates. In G53 coordinates, it allows you to set an offset with G92, but it does not save, so switching to a different workspace and switching back to native G53 loses the position_shift that you had and resets it to zero. That’s reasonable enough, since G53 is supposed to be native coordinates.

What’s potentially confusing is that homing with G28 will reset the position_shift to zero, but it doesn’t change any of the saved workspace values. So suppose you do this:

  • Home the machine
  • Choose workspace G54
  • Jog to the workpiece
  • G92 X0 Y0 Z0 to set the workspace origin to the workpiece
  • Cut part 1 of a job
  • Disable steppers with M84 and come back the next day
    • (Controller has remained on but maybe the machine has moved)

Now you want to home the machine again and continue the job. You are still in workspace G54, but if you home the machine with G28, it will report X=0 Y=0 Z=0 at the machine origin since it has reset position_shift. It still has the correct offsets saved for the workspace for slot G54, but they are not reflected in position_shift even though you are theoretically still in workspace G54.

If you change to a different workspace and change back, say with G55 and then G54, then it will restore the position_shift to the correct values and then you can continue the job from the previous day. Another way to switch to another workspace and switch back is to use G53 <command> which temporarily runs the command in native workspace and then switches back, which loads position_shift from the saved slot. You can do a simple dwell, like G53 G4 S0.

So to continue the example above, suppose you return to the machine the next day. To cut part 2 of a job:

  • Home the machine
  • G53 G4 S0 to force reloading of the workspace offsets
  • If the gcode for part 2 contains G92 X0 Y0 Z0 then you can jog to the workpiece origin (G1 X0 Y0 Z0) before running part 2
  • Cut part 2 of the job

Workspace offsets survive homing with G28, although they give the initial impression that they don’t.

I haven’t tried saving workspace offsets to EEPROM, but presumably this could be used to continue a job even after the entire machine has been powered off.

Now, in the unlikely case that you have a dual-x-carriage LR3 setup, switching tools T0/T1 reuses some of the code from homing (G28), the effect of which is to sometimes* clear the position_shift in the X direction similar to G28 X. If you had set up an X offset with G92, that offset is lost, unless you had selected a workspace like G54, and in that case you can restore the offset by switching away and switching back. I find the simplest way to do that is with the G53 dwell: G53 G4 S0.

*Clearing of position_shift occurs when switching from T1 to T0, but not when switching from T0 to T1. Go figure.


Are you seeing anything in Marlin that could fix, “Sometimes”? Or would it be easier to use GRBL? The SKR port seems complete, I just have not tried it yet, it was not as easy to compile as the Rambo port from my quick look at it.


The ‘sometimes’ clearing is only on the dual-x-carriage (IDEX) setup when switching tools. I don’t know if GRBL has that, or if it will ever have that. It’s a significant amount of work to add to GRBL, but if someone like Inventables were motivated enough, it’s doable.

I think the conflict within Marlin between IDEX and G92 can probably be solved, but I will submit an issue and leave it to the experts. I have a workaround, so I don’t need a fix, and I would probably butcher it and break something else. Maybe I will suggest a fix and the experts can implement the correct fix. :slight_smile:

Apart from the IDEX bug, I’m not sure that the workspace handling is wrong per se. It’s a bit surprising, but I’m not enough of an expert to know whether it is incorrect. It looks like it can do everything we would want, but the steps to get there might not be the most intuitive.


Submitted a bug here for the IDEX+G92 issue and there is a pretty simple 3-line hack to remedy the bug, although I don’t know if it’s the best solution.

Maybe the Marlin maintainers will pick it up, or maybe they will develop a better solution, or maybe the bug will stay around for a while.


It doesn’t look like the Marlin devs have even acknowledged that bug report yet.
How long does that usually take? It looks like a pretty obvious bug to me…

If it is not a common use case it gets back burnered. It took a long time to get the autosquaring pulled in.

There is one main dev and he gets swamped with new board configs, and 3D printing bugs. Edge cases are not priority.

On that note a few other firmware are seemingly gaining ground because development is moving faster. I might need to start poking around more.

@jamiek and @vicious1

I have been redirected to this from another post, although my machine is not setup yet I am doing a bit of learning. As I said in the other post I am looking to set up a “tool change” location for my machine.

The way I “see” it happing is this (with a bit more knowledge from @robertbu), using Machine 0,0,0 which is the homing sequence and the limit switches. The work piece is set up to be g54 at the bottom left corner and is, for this discussion located 100mm x 100mm in from machine zero.

So machine Zero and G54 offset are both set respectively to 0,0,0. The process is started with say a surfacing operation, then a tool change is required to say a single flute end mill to start the actual part shape routing. The actual processes are not important to the discussion, just that the GCODE requires a tool change.

I would have assumed a “TOOL CHANGE” script is called, this tools change script saves its current location and then sends the machine to a predetermined location, in this case Machine 0,0,0 and the tool is drive up to its maximum to allow space to be changed, then waits for “buttonPress”
Once you give it that button press "press the any key to continue… Where is the any key anyways? :rofl:) From there it is driven down to set the height of the new bit using the touch plate, (eventually after the new hight is set the Z is driven to a safe height and the machine moves back to the cut location and continues the operation.) Now this is where it gets sticky as we need to set the hight of the Z in g54 not Machine 0,0,0.
With what you are saying above this sounds “doable” could you confirm that my understanding of your post is correct. I admit that this necessitates the use of the workspaces and a different and more complex set up, but if a workspace is used (g54 in the example above) is this doable?

Also I guess we need to confirm also there is such a things as a “tool Change” script in MARLIN and if we have to write the specific code in to the GCODE FILE or call/ GCode/ some other black magic way to call it in MARLIN ?

Have a look at the milling basics page and I show some different tool change settings.

Re-reading what I wrote, the above post is a bit long-winded and confusing. The use-case is more to do with workspaces surviving after homing.

The scenario of changing bits is somewhat different and if you have a G92 offset for your workpiece it is not obvious how to shift it after doing a G38.2 probe.

Suppose you have an MPCNC and not LR3 (I’ll come back to why this matters). Then you could put a micro switch under the bit at machine 0,0 and configure the firmware to home Z downwards against the switch.

Then you can change to workspace G54 and jog to your workpiece and set the workpiece origin using G92 X0 Y0 Z0. Cut the first part of your job.

Then jog the machine to a handy location and change the bit.

Then switch to machine coordinates G53 and jog to X0 Y0. Now youre above your micro switch with your second cutting bit. Home Z with G28 Z.

Now when you change back to workpiece coordinates with G54 you are all set. The machine coordinates are correct for your new bit since you homed, and your G54 offsets are also correct since they are retained relative to machine coordinates. Remember to jog upward before continuing with the job or you might crash on the way to the second toolpath.

With LR3 this is not so simple because with dual Z you can’t home downward with a bit pressing a microswitch. You can probe G38.2 but I don’t know of a way to take the resulting position of the probe and add it to a workspace. Homing does it automatically.

Sorry I’m making this harder than it needs to be. The easiest thing is to touch off the workpiece with a touch plate each time you do a job or each time you change bits. Quick and simple.

If for some reason you can’t (which is uncommon) then you can go to fancy stuff aiming for bitsetter style functionality. But it is tricky and most people (including me) never need it.

For LR3 maybe you could cut a hole in the table at 0,0 and home downward. Dual Z endstops will level the X axis.

Then maybe the ‘bitsetter’ can be at some fixed location not at 0,0 and the switch can be wired in series with both Z endstops. Then you can home downward against the switch and trigger both Z endstops (will it stay level?). Then you can retain the offsets between workspace coordinates and machine coordinates same as MPCNC.

This is very advanced and not recommended, but in theory I think it is possible.

Ok, I am using a LR3 and i will put this on hold to until i can get the LR3 working see how i am going to use it.

thanks for your replies!

That bug report is about to auto-close, with no acknowledgement.