3D Printering: Getting Started With Universal Bed Leveling

Last time we talked about Marlin having multiple bed leveling mechanisms including Unified Bed Leveling or UBL. UBL tries to be everything for everyone and has taken precautions to create dense meshes that model your bed and give you ways to customize and edit those meshes.

We talked last time about how to prepare your printer for UBL, but not how to use it while printing. To do this, you need to create at least one mesh and enable it in your startup code. You should also get your Z-height right for everything to work well.


Almost all UBL mechanisms are included in the G29 command. Unless you’re starting from scratch, you should load a mesh from a “slot” in the EEPROM:

G29 L2

This means the slot 2 mesh is now in memory and you can work with it. If you don’t save it, any changes you made will be lost. This doesn’t necessarily enable leveling, by the way. It only loads the net. If you start from scratch, you don’t need to load anything.

Setting up the mesh requires the use of phase commands for G29, which use the letter P and a number:

  • P0 – Zero the mesh and turn off the leveling system.
  • P1 – Automatically probe as much as possible. Usually this clears the existing mesh unless you use the C option. If you find you don’t want to probe tens or hundreds of points, you can stop by holding the controller’s button for a few seconds.
  • P2- Manually check all unfilled items. The printer will prompt you on the screen to continue. You can manually touch the bed with the nozzle, or use the B argument to measure a shim like a piece of paper the first time, and then use that height to manually measure all the points. You can also cancel the process again by pressing and holding the controller button.
  • P3 – Fill in unoccupied areas of the mesh. You can specify a value with C or omit it and the printer will try to guess the correct value from the surrounding data. It’s surprisingly good at that. However, if you have multiple rows or columns of unspecified points, this command will only run the “first” set of points so you may be able to refine them and guess better for the remaining points. That means you might have to spend P3 multiple times if you’re just trying to fill the grid.
  • P4 – Fine tune mesh points. This causes the printer to prompt you on the screen to measure specific points. Typically, you specify an X and Y coordinate along with a repeat count (often 1).
  • P5 – Provide statistics about the network, including mean and standard deviation. Add a C if you want to shift the mesh so that the average value is considered zero.
  • P6 – Move the mesh. Specify a value with C to move the entire mesh up or down. This can be useful if you’re printing PLA, for example, and want the print to move up a few hundred microns to prevent oversticking.

This seems confusing, but the general idea is that you start with P1 and then use either P2 or P3 (or both) until all points are set. The rest is used for special purposes or for fine tuning. Just don’t forget to save the mesh and remember where you put it:

G29 S1

I suggest you save your first P1 result in a slot you never change, and then save the results somewhere else after P2 and P3. That way, if you screw up, you can go back to the baseline and start over without having to repeat a lot of probes.

Visualize your bed heights

So how do you know what UBL is doing? You can request a topography report (T) and get some data:

G29 T

You can add V1 for a bit more verbosity, and T1 will output data suitable for a spreadsheet or other software to read.

Here is a sample report:

 Bed Topography Report:
     (  0,210)                                      (210,210)
         0       1       2       3       4       5       6
  6 | -0.533  -0.533  -0.522  -0.483  -0.461  -0.429  -0.400
  5 | -0.400  -0.367  -0.324  -0.245  -0.183  -0.112  -0.183
  4 | -0.359  -0.259  -0.183  -0.075  -0.026  +0.076  +0.200
  3 | -0.333  -0.233  -0.115  -0.001  +0.070  +0.181  +0.200
  2 | -0.348  -0.248  -0.140  -0.009  +0.062  +0.161  +0.200
  1 | -0.350  -0.290  -0.177  -0.049  -0.003  +0.130  +0.400
  0 | -0.350 [-0.290] -0.177  -0.049  -0.003  +0.130  +0.400
         0       1       2       3       4       5       6
     (  0,  0)                                      (210,  0)

Incidentally, the P5 instruction reports the standard deviation of this set as about 0.24. This means that about 68% of the data is plus or minus 0.24 mm from the mean. Then 95% of the readings are within 0.48mm (plus or minus again). As you can see I have a corner that needs a bit of work – the total deviation is about 1mm from highest to lowest point.

Bed data were recorded

Z height

Even if we know the shape of the bed, other factors also play a role. In particular, the actual height of the nozzle is crucial. You need to adjust the Z offset so that the difference between the probe and nozzle is just right.

Everyone has their own way of setting up UBL, but my advice is to start with it turned off. Then print a small ring or disk in the middle of the bed. It doesn’t have to be very thick and should be small enough that the bed lies flat underneath. For example a 5 mm high cylinder with a diameter of 20 mm. You can quickly see if the plastic is sticking to the bed or not. If it’s too squishy or not sticky, adjust the Z offset until it is. Then do the mesh measurements.

However, the offset does not change the shape of the bed, so you can set the offset last or adjust the height of the mesh as well. All legitimate solutions, but I prefer to set the height first.


Your startup code has a few things to do. You need to load the desired mesh and turn on leveling. By default, a home command turns it off, but you can change that when rebuilding Marlin. Your bed probably won’t change shape, but it might shift a little. You can use G29 J to take a 3 point measurement and distort the mesh based on that measurement. You must also enable leveling with G29 A if it is not always enabled.

You should also set a fade height, which you can do once in the EEPROM if you like. This is typically 10mm and the correction applied due to the mesh gets smaller and smaller at each level until you reach this height. After that, no Z correction is applied. Usually your print is fine at this point and it also saves time and wear and tear on your Z axis.

A plan

So if you wanted to experiment with UBL, here’s a plan:

  • Recompile Marlin to enable UBL and resist the urge to start with too many points. You may want to familiarize yourself first, and then expand the number of points. A 7×7 grid is good for many printers. You can also set it to reset auto-leveling to the previous state after a HOME.
  • Align your bed in the usual way as much as possible. The less correction is required, the better UBL works.
  • Do not turn on auto-orientation yet. First get a nice cylinder to print in the center of the bed by adjusting the Z offset.
  • Heat the bed to your normal temperature and do a G29 P1. For example, store the results in slot 2 (G29 S2).
  • Run a G29 T and see if points are not being measured. You should understand why they were not measured. For example, if the Z probe is to the left of your print nozzle, you should not have unprobed points on the left side of the bed. If you do this, your setup in Marlin is wrong and you will need to recompile.
  • You can do a G29 P2 to fill in the remaining slots, but try the G29 P3 instead for a first try.
  • Make a G29 T again and repeat the P2 or P3 commands until you have a full mesh.
  • Save the mesh in slot 1 (G29 S1)
  • Set your boot code to load slot 1 (G29 L1) and activate (G29 A). You might want to do a G29 J after it’s loaded and preferably after your bed is hot.
  • Print a test object. You might want to start again with a small centered object just to confirm you haven’t messed anything up. A bed flatness pattern is useful. Marlin has a “Mesh Validation” command that draws such a pattern (G26) and you could use that as well. However, any pressure on the flatness of the bed is fine for starters.
  • If you find some points are too high or too low, you can try editing them. If you stray too far from it, you can always go back to the saved copy in slot 2 and start over. For example, inductive sensors sometimes give strange results near the edge when partially removed from the metal bed.


Octoprint can edit meshes with a little help,

Note that I always try to do probing with a hot bed. Heat causes things to expand, so it’s probably not as accurate as you might want to study bed cold.

If you need a quick bed verification print there are plenty on sites like Thingiverse including mine. You can adjust the X and Y size to fit your bed instead of recreating it. Just scale the Z axis non-proportionally.

If you use Octoprint, you can view and edit meshes there with a plugin. There is also a plugin to visualize the mesh or you can do as above and use a website for this purpose.

That’s a wrap!

So are you using UBL? If no, why not? Sure, if you have a great bed, you could just make it parallel to the X axis and you’re done. But if you’re using beds that aren’t perfectly flat, you can’t just move the corners to make everything perfect.

The UBL system is a kind of “virtual lying surface” and this means that you can easily adjust it without any mechanical problems. If you don’t want PETG to stick so tightly, you can just move the mesh up a bit. If part of a model is very small and needs to be additionally pushed into the bed, you can do that too.

Of course, bed leveling is nothing new. But if you don’t use UBL, you should consider upgrading. The ability to tweak the mesh and save multiple bed leveling settings alone is worth the effort.

Leave a Comment