Using the Z probe to set bed hight rather than just bed level

On a “standard printer” the Z probe is used every time you print to check ”where the bed is”, you add on the Z offset, the distance between the sensor and the nozzle from the M851 value to put the nozzle at exactly the same height every time you print. This is a very consistent process and takes into account any movement/slop or change in the printer frames or structure every time you print.

Snapmaker bed position is measured by the user when they manually set the nozzle height during the final point in the calibration process. From then on, the bed is assumed to be exactly the same distance from the home position which is at the top of the rail and as far away from the bed as you can get. The Z probe is never used to measure the height of the nozzle from the bed, it is only used to ascertain the relative height differences across the bed for the bed levelling process and I will let you read all the work @Tone has done to determine whether the levelling process is fit for purpose.
This process does not take into account any movement/slop of change since the last leveling process.

I think this is part of the reason some people have very inconsistent results even when printing the same print twice without adjustment.

In addition, the only way to adjust the Z offset is to use the console just before you print. This Z offset does not seem to be available to a change via a GCODE command unlike the normal M851.

I use OctoPrint as I am lazy and like to most of the work to print on my laptop from the comfort of my armchair so I want a way to use the proximity sensor to probe the bed before every print and not to wait by the printer. I need a way to programmatically adjust the Z height but Snapmaker makes it very hard. The M851 command exists but seems to be totally ignored, adjusting it does nothing and the Z adjustment that gets created when you do the final levelling setting is only available from the console just before you do a print, not programmatically.

I now have a process but I think it’s sub optimal and would welcome comments/suggestions for improvement.

My OctoPrint start code now, heats the bed, starts a calibration using M1091, when the calibration gets to the wait position, moves the head down a fixed amount, this fixed amount is my equivalent of M851 Z offset, finishes the calibration process then prints the model as normal.

The print accuracy has been great. Yesterday I switched everything over to CNC did some stuff (badly), switched everything back to printing and my first print from OctoPrint without any adjustment was full bed square test and it worked perfectly well.

The process is a bit slow but that’s mainly because the bed heating is slow and it heats up for the calibration, cools down during calibration and has to heat up again to print. But it’s all automatic, started from my chair so it’s no hassle.

My OctoPrint start GCODE script is below. Only use this if you know what you are doing and you MUST CHANGE the Z value Offset to your own value.
All thoughts and improvements suggestions welcome especially if I am missing something obvious that can simplify things.

;bed level and Z offsite profile
G21 ; set units to millimeters
G90 ; use absolute positioning
M82 ; absolute extrusion mode
; start heaters for bed level
M104 S220.0 ; set extruder temp
M140 S65 ; set bed temp

G28 ;home

M109 S220.0 ; wait for extruder temp
M190 S65 ; wait for bed temp

;Auto Level
G1029 A ;start leveling

G91; relative positioning for Z offset move
;*****************
G0 Z-2.05; Device specific Z offset, reduce to bring print closer to the bed. (enquillent to M851)
;*****************
G1029 S ;save data
G1029 D0 ;end leveling
G0 Z10; move up 10mm
G90; restore absolute positioning

11 Likes

Thats a great Idea, I am fidling around with levleling and octoprint and I will test your script - Great!

Hope it works for you @stefix.
To get the initial value for the Z offset I counted the reduction when doing the normal calibration using the console. In my case this was -1.7mm. I then did a couple of automatic tests to get to the value I use now which is -2.05mm. What I dont understand is why there is a difference of 0.35mm between the “manual” and automatic value. I think it may be something to do with the console Z offset you can use before printing. When doing the automatic bed measurement that Z offset is “absorbed” and mine was -0.2mm.

Works very well thank you for the great Idea. Put it in cura as startscript and ready!
Nearly as my other printer a GeeeTech A20T with bltouch. BTW: My offset is 2mm at point.

One question: why do heat the nozzle from the start?

I would expect that’s not needed for this little calibration dance?

You are right its not nessecary to heat the nozzle.

Agree it serves no useful purpose I am removing it! Unfortunately it wont speed anything up as its the bed that takes the time to head and I thing thats necessary.

ok, I’ll definitely try it later.
And it will save a little bit of energy :slight_smile:

@stefix
I am just sorting out having two profiles in OctoPrint, one that does the leveling and one that just prints for a faster result, the start GCODE script will execute depending on which one is chosen. I thought that would be simpler than two Cura profiles.
This is what it looks like. Two OctoPrint profiles, one called “Snap3DPrintLevel” the other “Snap3DPrint”. The G28 home is needed in the leveling script and and I dont want it again in the Cura profile so it’s in OctoPrint for both.

;bed level and Z offsite profile with profile selection to just print
{% if printer_profile.name == “Snap3DPrintLevel” %}
G21 ; set units to millimetres
G90 ; use absolute positioning
; start heaters for bed level
M140 S65 ; set bed temp
G28 ;home
M190 S65 ; wait for bed temp
;Auto Level
G1029 A ;start levelling
G91; relative positioning for Z offset move
;*****************
G0 Z-2.05; Device specific Z offset, reduce to bring print closer to the bed. (equivalent to M851)
;*****************
G1029 S ;save data
G1029 D0 ;end levelling
G0 Z10; move up 10mm
G90; restore absolute positioning
{% else %}
G28 ;home to match levelling script
{% endif %}

2 Likes

I have a couple comments.

I like the idea of automatically setting the offset. That key idea is good. I think it can be used better, however.

I have found the platform will continue to change shape as the temperature gradients settle in as it heats up. Turning the bed on, waiting for it to hit 65C, and taking a measurement: that’s too fast - it needs to soak for about 15-30min for the stresses to stabilize.

Additionally, the amount the bed moves changes with the bed temperature. A bed at 65C will deflect less than a bed at 90C.

Additionally, after the bed movement stops, it doesn’t move afterwards. I think the calibration only needs to be done once per temperature setting.

My conclusion is to take this script and put it in a Luban macro so that you can generate a calibration matrix once for various bed temperatures. Then, you can put that matrix in your extruder profile for different temperatures / materials.

3 Likes

Agree that would also work, it is flexible depending on your personal work processes. A combination of both with a Luban macro with some long G4 waits before levelling for a large full bed print would work well.
The main thing I wanted to get across is a change in approach to using the proximity sensor to measure “where the bed is” rather than asking the user to do it - we all no how inconsistant us users are!
It’s a complete fudge to get round what I think is a suboptimal process. Now give me standard Marlin bed leveling and an M851 Z offset thats actually used and I would be much happier.

2 Likes

This is an interesting idea, i will be following this conversation

Leveling seems to have become not much of an issue with my glass bed though.

1 Like

I follow too and will give a try to that solution, for now I have to set the Z offset manually… It’ll be great maybe if Snapmaker create a probe add-in or if someone manage to create that…

Works fine… I’ve have that on the after connection script, that’s perfect ! I don’t have to move to calibrate and lunch a print !

And in theory you can change out the bed and print head, put them back and it will still work. Also means you can slightly tweak the nozzle height and it will carry forward to next print and next head change.
You only need to reset if you change/remove the nozzle or adjust the proximity sensor.
Pleased it worked.

So the problem I’m getting when I do an 11x11 bed level (It’s the only way I can get PETG to print happily) I get those timeout errors, it’s very annoying, any solution?

Ahhhh, probably because once the levelling starts, it no longer prints the busy lines on the console. I guess I doubt this can be avoided. I guess I will have to do the level on the touchscreen when it’s needed… sigh

Hi @bhaal you can change the timeout in Octoprint so that you dont get the errors. It’s under Settings, Intervals & Timeouts, Communication Timeout. I think protocol support is detected but I have increased both. Time your bed level and add on a bit. I only use 5x5 bed leveling.

Oh I so didn’t read the text after the word “busy” for the 2nd variable, was rushing through stuff trying to get things done before the end of the day. Silly me. Alright, hopefully that will fix things, it’s a pity we cannot turn off the busy detect in the gcode script…

The GCODE is what gets sent to the printer. The timeout settings are telling Octoprint to wait a while before flagging an error when it does not hear back from the printer. They are instructions to different machines but both in the setup area of Octoprint.