How to do a larger than 3 x 3 matrix level

So here’s my attempt at doing a leveling matrix larger than 3 x 3. Please be advised that this is not for the faint of heart. If you mess up this process you can bury your nozzle into your print surface. I know, I did. I’ll try and tell you how to avoid that. If you aren’t having any trouble with the first layer of printing then this process isn’t for you. I am doing this on an A250, so you may have to change some things for your size Snapmaker.

The controller has a version of leveling that the Snapmaker uses. It’s “G1029”. Like the G29 it is a modal type process where you start the process, do the leveling, do the Z offset, then end the process. I think it is just a “G29” wrapper and actually calls the normal Marlin “G29” to do most of the work. You can put these commands in a GCODE file or you can use Luban’s built in Macro widget. I find the Macro widget convenient because you can do the editing and execute it right in the workspace. I use two different Macro’s, one to start, one to end. You have to do the Z offset manually in between the two.

The matrix definition:
Notes: I just do this manually on the console. The “5” in this example is defining a 5 X 5 matrix. You can create up to an 11 x 11 matrix! If you do a “M420V” right after this command you will see that the matrix size has changed. At this point in time the old matrix values will still be there, the rest of the matrix is just filled with zeros.

The “Level” macro:

Notes: The first two commands just get the print head up close to home. The “G1029A” command will want to do a “home command” (G28). The third command turns on the heat and waits till it’s up to temperature. I’m turning on heating because I want the matrix to compensate for heat change. You may want to use a different value there. The G1029A will turn off the heat so the matrix won’t be perfect as in this example it drops to about 50 by the time the process has completed. The “A” in the command is telling it to start the Auto level process. The G1029A will do the grid scan and stop at the end point where you need to set the Z offset value. It will use that value to shift the matrix to the correct Z level. You can use the “Control” mode of the Touch Screen in the “Axes” tab to move the head to that location. BE AWARE that the movement levels are 10X the ones normally used in leveling. You can create a Z-.05 macro to do smaller amounts if you want. You’re using the console with manual commands, macros, and the Touch Screen all at the same time.

The Z offset:
Use the Touch Screen to move the head down until it is touching the test card. I find that you have to move down somewhere around 5.4mm. Your printer may be different because of how your sensor is located. Because of backlash I usually go down until there is resistance on the card and then move back up .1mm (or .05 if you have a macro set up). As the head moves around in normal printing the Z backlash will tend to settle out, although if you have a thin layer being printed, the pressure of the filament coming out of the nozzle may push against the bed and allow movement of the head in the positive Z direction. Once you have the head in the right Z position you are ready for the finish.

The “FINISH” macro:

Notes: The S does a save of the Z offset and the matrix values, the next line, the D0 (that’s a zero, not an “Oh”) This is meant to do an additional “Delta” offset that shifts the matrix by the value of the “D” command. That value has to be in the range of 0 to 1mm. I’m not exactly sure what this is useful for but the “D” command does appear to end the leveling process and ends the leveling mode, turns the “level enabled” on. The M420V is just there to print out the new matrix on the console. It can be omitted.

At this point in time the matrix is now there and active. It hasn’t been saved into EEPROM yet. You’ll have to do a “M500” command to save it. If you have Auto Level turned on it will replace your matrix with the standard 3 x 3.

Now, I have an additional macro that does a “TWEAK” of the matrix as I find the matrix is still not perfect. (Still investigating why) It is basically incrementing the matrix values by the values I measure with my Dial Indicator “Check Level Ind.gcode” file. You can also determine those values using my “Check Level.gcode” file. It takes a different version that is sized for the matrix size I’m currently experimenting with.

The “TWEAK” macro:
M421 I0J0 Q-.03
M421 I1J0 Q-.03
M421 I2J0 Q-.07
M421 I3J0 Q-.04
M421 I4J0 Q.00
M421 I0J1 Q-.11
M421 I1J1 Q-.10
M421 I2J1 Q.02
M421 I3J1 Q-.18
M421 I4J1 Q-.01
M421 I0J2 Q-.02
M421 I1J2 Q-.02
M421 I2J2 Q.00
M421 I3J2 Q-.07
M421 I4J2 Q-.15
M421 I0J3 Q-.10
M421 I1J3 Q-.02
M421 I2J3 Q.11
M421 I3J3 Q-.15
M421 I4J3 Q-.01
M421 I0J4 Q-.02
M421 I1J4 Q-.02
M421 I2J4 Q.08
M421 I3J4 Q-.02
M421 I4J4 Q.18

Notes: As you can see by the values in the “Q” that is how far off my matrix is. YOUR VALUES WILL BE DIFFERENT. Your file will have to include more or less M421 commands to match your grid size. This example is a 5 x 5 and so there are 25 commands. The “I” & “J” values are the matrix address of each point and correspond to the X & Y directions. The values go from 0 to 4 for a 5 x 5 matrix.

So in conclusion, a larger matrix won’t be the end of your leveling problems, it might just be the beginning!! Because the matrix still isn’t perfect that means you have more points to “TWEAK”. You may still be better off just trying to improve (tweak) your 3 x 3 matrix values. I’ll be posting a new and improved “Check Level. gcode”.

EDIT: How I buried my nozzle into the bed, I didn’t end the level process correctly and as a consequence it thought it was in a different location that it really was. This was because I still didn’t understand how to end the leveling process. When it’s doing the level it is in what they call “raw” position mode. The Z zero position is actually 3+mm or so below where your are when the leveling is turned on. Normally it won’t let you go below Z0 but when you’re in leveling mode, that zero is lower. As a consequence I tried a move that pushed it into the bed. :frowning:

A BIG thanks to the Snapmaker team for all their help and for making the source code available. I hope they’re not upset with me revealing this matrix stuff. They may have some comments on it where I’m off base.

EDIT: See this post for a Google Sheets help file.


Bravo, thank you very much for the ton of work!@Tone
Still waiting for my A350

Great work @Tone. I can confirm that the 7x7 and 9x9 grid are both functional and the mesh is saved across a reboot as long as auto and quick leveling are disabled. Note: If you run straight from Luban or Octoprint like I do, you will need to put an M420 S command just after the G28 command in your slicer start gcode. This will turn leveling back on after the G28 disables it.

1 Like

You need leveling off when it is doing the auto level as you want the dimensions measured in raw coordinates. I believe SM’s version of G28 doesn’t leave leveling off.

I believe the version run from the TS turns leveling back on after a G28 but since I am using Octoprint I need to turn leveling back on after homing in my start gcade.

I’m using G28 in my gcode files and you can see it turn it off during G28 and then turn it back on at the end. Octoprint should be the same.

Dear Tony
Thank you very much for your elaborate explanation. I have started the same process on my A350. I will post my findings here as well. However, I have a couple of questions;

  1. Running G1029A, I got the following responses - see the full response at the end of the post;
    It starts off by homing and measuring the X, Y, Z positions (and steps I believe)
    For mine, it has X as -17.00 and Y as 352.00. With this, the locations of the Probe and Move are different. I noticed this when using the normal Touch Screen Calibration as well.
    This results in the matrix positions not being in the middle of the bed, but with an offset. At the end of the process when it wants to save the Z-offset, it moves to the actual center.
    READ: X:-17.00 Y:352.00 Z:328.46 E:0.00 Count X:0 Y:144000 Z:133600
    You will notice the differences in ProbeX and Move to X is always 13 and the differences in ProbeY and Move To Y is 19.15
    How can I fix this or resolve this to ensure I don’t have an offset in the matrix? Is this offset calculated in the leveling corrections?
    Edit: Found the answer to this. Sensor (Probe) is X=13 and Y=19.15 from the nozzle. Thus, although it seems that it is not centered, the sensor/probe is centered

  2. You mention backlash. Are you referring to the bed backlash? On the A350, there is a very large pitch/roll around the middle of the X-axis. It seems that the sliders in the two Y modules allow for a lot of of rotational movement or play. With the large bed, the downward pressure of the printhead pushes the bed down about 2.0 to 2.5mm. Thus, I am very concerned that correct readings cannot be obtained.
    Edit: I followed the link below and lowered my proximity sensor. Now the nozzle doesn’t push the bed down during calibration. It seems that the sensor couldn’t detect my bed without pushing the bed down.
    Snapmaker official response to print head gouging?

  3. Matrix Positions. Is I0J0 the same as Probing No 0? In the normal 3 x 3, is the matrix calculated from X0Y0 or X0Y350? Printing/displaying the matrix values with M420V gives the Z values/offsets, but where can the X and Y values/positions of the corresponding positions be obtained.

Thank you very much for this post. And the new “tools” you opened for some of us.


SENT: G0Z320F6000
READ: ok
SENT: G0X0Y350F6000
READ: ok
SENT: G1029A
READ: new E target temp: 0
READ: new B target temp: 0
READ: new E target temp: 0
READ: leveling OFF
READ: echo:busy: processing
busy: processing
READ: echo:busy: processing
busy: processing
READ: echo:busy: processing
busy: processing
READ: echo:busy: processing
busy: processing
READ: echo:busy: processing
busy: processing
READ: leveling ON
READ: X:-17.00 Y:352.00 Z:328.46 E:0.00 Count X:0 Y:144000 Z:133600
READ: leveling OFF
READ: X:23 - 137
READ: Y:23 - 152
READ: Probing No. 0
READ: ProbeX:40.00 ProbeY:31.00Avtive:1
READ: Move to X: 27.00, Y: 11.85, Z: 15.00
READ: probed z: 5.61
READ: probed z: 5.59
READ: probed z: 5.56
*READ: *
READ: Probing No. 1
READ: ProbeX:177.00 ProbeY:31.00Avtive:1
READ: Move to X: 164.00, Y: 11.85, Z: 10.56
READ: probed z: 5.75
READ: probed z: 5.74
READ: probed z: 5.71
*READ: *
READ: Probing No. 2
READ: ProbeX:314.00 ProbeY:31.00Avtive:1
READ: Move to X: 301.00, Y: 11.85, Z: 10.72
READ: probed z: 6.04
READ: probed z: 6.03
READ: probed z: 5.99
*READ: *
READ: Probing No. 3
READ: ProbeX:314.00 ProbeY:183.00Avtive:1
READ: Move to X: 301.00, Y: 163.85, Z: 10.99
READ: probed z: 5.97
READ: probed z: 6.02
READ: probed z: 5.99
*READ: *
READ: Probing No. 4
READ: ProbeX:314.00 ProbeY:335.00Avtive:1
READ: Move to X: 301.00, Y: 315.85, Z: 10.99
READ: probed z: 3.65
READ: probed z: 5.15
READ: larger clearance between 2 probe!
READ: probed z: 4.33
READ: larger clearance between 2 probe!
*READ: *
READ: Probing No. 5
READ: ProbeX:177.00 ProbeY:335.00Avtive:1
READ: Move to X: 164.00, Y: 315.85, Z: 9.33
READ: probed z: 4.38
READ: probed z: 5.88
READ: larger clearance between 2 probe!
READ: probed z: 4.36
READ: larger clearance between 2 probe!
*READ: *
READ: Probing No. 6
READ: ProbeX:40.00 ProbeY:335.00Avtive:1
READ: Move to X: 27.00, Y: 315.85, Z: 9.35
READ: probed z: 4.49
READ: probed z: 4.55
READ: probed z: 5.55
READ: larger clearance between 2 probe!
*READ: *
READ: Probing No. 7
READ: ProbeX:40.00 ProbeY:183.00Avtive:1
READ: Move to X: 27.00, Y: 163.85, Z: 10.55
READ: probed z: 5.88
READ: probed z: 5.89
READ: probed z: 5.88
*READ: *
READ: Probing No. 8
READ: ProbeX:177.00 ProbeY:183.00Avtive:1
READ: Move to X: 164.00, Y: 163.85, Z: 10.88
READ: probed z: 5.80
READ: probed z: 5.84
READ: probed z: 5.84
*READ: *
READ: ok

1 Like

Hello Tone!

Thanks for the great work on this guide. However I seem to get stuck at step 5 "Adjust values using “Check Lev Hot.gcode”. I’ve ran the code and then it finishes, but my measuring paper is moving freely underneath several points it passes.

When I just do the 7x7 probe/auto levelling, I seem to get very good results. (placed a small print on the corners and the center of the board and have it print it, showing good adhesion now). So I think I’m very much helped with just a 7x7 levelling instead of 3x3.

But I’m intrigued by the tweaking bit. I just don’t seem to understand what you mean by step 5. Because at step 6, you mention “Enter values in 2nd matrix to left”. What values? I don’t seem to be getting any?

Or am I missing a step?
Thanks in advance, like I said; this has helped me greatly allready !

When you run that file you should be recording on a piece of paper if the test card is loose, tight, or just right. Then you have to either do a “M421 InJn Qz” for each of the points needing adjustment or enter the adjustments into a macro and do them all at once.Then you’ll repeat the Check Level again and repeat the process until you’re happy with the Check Level results. Then you can do an M420V to print out your matrix and then enter those values into the second matrix on the Google Sheet. That will then let you produce the Tweak macro which you’ll use when ever you do an Auto Level in the future.

What I do when I turn on my machine is run the Check Level Hot.gcode file and if it’s pretty close I’ll just go with it. If it’s off a little on a couple of points I’ll adjust those points and continue on from there. You really only need to use the TWEAK macro after doing a new Auto Level from the Google Sheets and then you only need to run the TWEAK after that.
If you run the BUILT IN AUTO LEVEL it will revert back to the 3x3 and you will then have to redo the 5 x 5 or 7 x 7 leveling.

One question for you, are you running a copy of the Google sheet or downloading it to an Excel sheet?

Thanks alot! I’m back on it again. I’ve noticed you made a new version, i’d be sure to use the latest version.

I’m using google sheets copy.

1 Like

enough for tonight… been trying and trying… but nothing gives.

I can’t load the macro, it just doesn’t do anything. When i copy past line per line it gives me an “OK” back, and verifying with M420V tells me the line per line method does work… somehow the macro won’t,

Then, what value I give in to alter a point, the nozzle keeps pressing the bed down on 0-0.

For a higher nozzle vs bed, I need an higher value in the cell right? For say, my 0-0 noded at 4.819 but it pressed the bed down.

Are you talking thru WiFI?
WiFi is known to not echo back correctly.

Yes, larger z values moves the nozzle up.

only connected through USB for console. Only used wifi to send files.

Somehow i MUST have missed something. Just have no idea what…

Are you pasting it into a Luban Macro or just trying to paste it into the console?
The console won’t let you paste in multiple lines.

Made a macro.
The finish macro works and the autolevel macro too.

Maybe the macro gets too big?

Yep, there is no return value when sending G-code command via Wi-Fi

The 5*5 levelling method is coming soon.


Good news Edwin ! Did you fix backlash compensation and did you fix M900 ignored command during printing ?
Oh and I forgot did you manage to have the ability to fix the bed temp durring calibration without doing tweaking
Thanks in advance

1 Like

To be honest, i was laughed at today at work :slight_smile:

My colleagues mentioned the 2 lineair y-axis is most likely not a good idea. The bracket which holds the bed will expand and shrink and needs to be firmly mounted to 1 axis only, the other just needs to push and pull on the y-movement but needs play in the X movement. Due to the lach of it, the bracket thats holds the bed, probably twists.

I still have my hopes up on proper bed levelling techniques like the one from @Tone but this theory made alot of sense to me too…


guess there is one way to eliminate or establish the theory; cold bed levelling and printing vs heated bed levelling and printing