This is really turning out to be the right answer. One of the benefits of using the work offsets is that they are one of the few things that can be stored with M500!
(I thought I could store things from the object model by exploiting M28/M29. But no expressions between those commands gets evaluated, so you can't store the result of an expression.)
So I explained above how to store things by writing gcode to a file you run on startup. But what if you want to store something in the work offsets during operation of the printer? You have a tool number, say 2, and you need to write a gcode expression with an axis letter, G10 L2 P5 Z.... How do you get that Z?
Well, you can write an if block to do that but that code is pretty long and you wouldn't want that cluttering up your all your macros. So I wrapped that up into macro itself so I can re-use it everywhere I need to store something. The trick is we don't have a way to pass variables into macros yet. So I just write the tool #, value to store and desired coordinate system index into coordinate system #9. Basically coordinate system #9 is now the stack for my program:
; copy_var.g
;
; this macro copies a variable from the temporary variable slot and stores it in the requested slot for the specified tool:
;
; How To use:
;
; G10 L2 P9 X{state.currentTool} Y{value_to_store} Z{target_coordinate_system_index}
; M98 P"/macros/scripts/copy_var.g"
;
; Inputs:
;
; move.axes[0].workplaceOffsets[8] - tool number to store the value for
; move.axes[1].workplaceOffsets[8] - the value to store
; move.axes[2].workplaceOffsets[8] - the coordinate system number to store it in
if move.axes[0].workplaceOffsets[8] == 0
G10 L2 P{floor(move.axes[2].workplaceOffsets[8])} X{move.axes[1].workplaceOffsets[8]}
elif move.axes[0].workplaceOffsets[8] == 1
G10 L2 P{floor(move.axes[2].workplaceOffsets[8])} Y{move.axes[1].workplaceOffsets[8]}
elif move.axes[0].workplaceOffsets[8] == 2
G10 L2 P{floor(move.axes[2].workplaceOffsets[8])} Z{move.axes[1].workplaceOffsets[8]}
elif move.axes[0].workplaceOffsets[8] == 3
G10 L2 P{floor(move.axes[2].workplaceOffsets[8])} C{move.axes[1].workplaceOffsets[8]}
else
abort ; if you pass -1 you call at the wrong time!
Now that is solved I can combine it with M500 and I give you per-tool baby stepping adjustment that persists between reboots:
call this in tfreeN.g
; save_babystep.g
; writes the baby stepping value into the work offset 7 and then stores it with M500
G10 L2 P9 X{state.currentTool} Y{move.axes[2].babystep} Z6
M98 P"/macros/scripts/copy_var.g"
M500
and call this in tpostN.g
; restore_babystep.g
; restore the absolute babystepping value from its storage slot
M290 R0 S{move.axes[state.currentTool].workplaceOffsets[5]}
Then call M501 at startup before you write any config values as described in the post above.
alt text
😸 🍻