In an ideal world, the bed of your FDM 3D printer would be perfectly parallel to the plane of motion of the print head. We normally say the bed is “level”, but it doesn’t matter whether it is level in the traditional sense, as long as the head and bed are the same distance at every point. Of course, nothing is perfect in practice.
The next best situation is when the bed is perfectly flat but tilted relative to the printhead. While this isn’t ideal, the software can move the printhead up and down linearly to compensate for the tilt. Things are way worse when the bed itself is not flat and has irregular bumps up and down all over it.
To counter this, some printer firmware helps examine the bed to determine its shape and adjusts the printhead up and down as it moves across the map. Of course, you can’t probe the bed at every possible point, so the printer has to interpolate between the measured reference points. Marlin’s bilinear bed leveling is an example.
However, if you have enough flash space and are using Marlin, then you should try Unified Bed Leveling (UBL). This is like a bilinear leveling with steroids. Unfortunately, the documentation for this mode isn’t as simple as you might want. Everything is out there, but it’s hard to get started and the information is scattered over a few pages and videos. Let’s fix that.
The basic idea
The idea is simple. The printer scans the bed in many places. Ideally, you will do this using a sensor that is not too far from your printhead. They can be up to 225 points, although 100 or 49 are common sizes – so 15 x 15, 10 x 10 or 7 x 7 and the bed doesn’t have to be square. The firmware saves the probe values in the EEPROM. In fact, it can store more than one mesh, which is useful when you have multiple printing surfaces: for example, you can store a mesh for a glass bed in one slot and one for a PEI bed in another.
Once the exploratory data is in, you shouldn’t have to re-examine it for a long time, at least. There are a few potential problems, however. First, your bed may not be able to probe every point precisely. More likely, your probe may not be able to reach every point on the bed that the nozzle can. After all, things change over time. Your bed can sink a little on its brackets. The system can adapt to anything, but it is a bit complex to get used to.
Everything old is new again
Of course, bed leveling isn’t exactly a new technology. Printers have long had the ability to do some versions of this. If your bed is perfectly flat, simply tilting the virtual bed may be enough. This is common for glass surfaces, for example, where it is possible to only calculate the inclination of the X and Y inclinations and apply them linearly.
UBL is a little different. It uses many points and linearly interpolates between each set of points. Think of each measurement point as part of a larger grid. As the printhead moves in the grid, the printer adjusts based on the slope of the imaginary lines that connect the next grid dot to its neighbors.
But it’s not just the many points that make UBL what it is. First, UBL allows you to easily fine-tune points. Since the correction between points is only an estimate, there are cases where the estimate is wrong and you need to edit the point to correct a particular point more or less.
This editing has several effects that may not be obvious at first glance. For one, you can set up UBL without a Z-probe. Sure, it’s a chore, but you can measure all points manually and the printer has provisions to help you with that measurement. Ideally, however, you will have some sort of Z-probe. Inductive probes are just as popular as BL-Touch and its many imitators. The photo shows a typical inductive sensor.
The other thing that editing can do for you is setting points that your Z probe cannot reach. Most probes have some offset from the printhead and cannot reach every point the printhead can reach. For example, if the probe is 10mm to the right of the head and the head can only go to 0mm, the probe can only measure X coordinates of 10mm or more.
It turns out that if your bed is fairly even, you might not need to measure these extra points, but you can if you need to. Marlin is pretty good at guessing the missing values, and even if it’s wrong it may be easier to start by estimating and then making adjustments.
An interesting side effect is that once you have a net you have several different options for imagining how your bed will look. Then you may want to make your bed flatter, but if you do you will have to rebuild your network. I’ll show you a couple of ways you can get some act like this next time.
You should already know how to build marlin for your machine. If not, you have to start there. Once you can get Marlin to build normally, you’ll need to deal with these configuration parameters:
configuration.h (with a few notes for clarification):
#define AUTO_BED_LEVELING_UBL // and turn off or remove other AUTO_BED_LEVELING_* defines #define RESTORE_LEVELING_AFTER_G28 // pick one of these if you want Home to restore level or turn it on //#define ENABLE_LEVELING_AFTER_G28 //#define PREHEAT_BEFORE_LEVELING // you can enable this section or just preheat manually #if ENABLED(PREHEAT_BEFORE_LEVELING) #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time #define LEVELING_BED_TEMP 50 #endif #define MANUAL_PROBE_START_Z 0.2 // Manual probes will start here so if this value is large, you will waste a lot of time #define ENABLE_LEVELING_FADE_HEIGHT // When to fade leveling effect to zero (10mm is good) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. #endif #define SEGMENT_LEVELED_MOVES // split moves into small pieces instead of entire grid #define LEVELED_SEGMENT_LENGTH 5.0 // This section sets the parameters for the mesh validation pattern if you want to use it #define G26_MESH_VALIDATION #if ENABLED(G26_MESH_VALIDATION) #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26. #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26. #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves. #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves. #define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements. #endif #elif ENABLED(AUTO_BED_LEVELING_UBL) // settings for UBL //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh #define MESH_INSET 0 // Set Mesh bounds as an inset region of the bed -- to avoid clips or other margins // Set the # of rows/columns to use #define GRID_MAX_POINTS_X 7 // Don't use more than 15 points per axis, implementation limited. #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X //#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points #define UBL_MESH_EDIT_MOVES_Z // If you turn this off, the nozzle could scrape the bed while moving between edit points #define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500 //#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // You can force a height when there is no data for a point #define UBL_MESH_WIZARD // add a wizard for setup to the menu // more menu setup #define LCD_BED_LEVELING #if ENABLED(LCD_BED_LEVELING) #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment #define MESH_EDIT_MENU // Add a menu to edit mesh points #endif // What do do after a Z probe #define Z_PROBE_END_SCRIPT "G1 Z10 F12000nG1 X15 Y200nG1 Z10"
There are also a couple of settings in
configuration_adv.h if, for example, you need to override the corners of the three-point probe and the like. You can usually leave them alone. If you have an 8-bit controller, you may not have enough memory to create UBL. There are a few ways to reduce memory footprint, but not by much. Better to upgrade to a bigger board.
Once you’ve created the firmware and downloaded it to your printer, you’re good to go, right? Not exactly. Even though the printer now knows UBL, you’ll need to set it up, which includes setting a Z-height and measuring your first grid. I’ll show you how to do it next time.