Bed Leveling an Ender-3 with Marlin Firmware

This was more painful than I thought, due to the Ender-3’s processor having only 128kBytes of program memory. Marlin barely fits in 128kBytes, bed leveling of any kind puts it over the edge. Long term it’s probably best to upgrade the control board.

Sensor:

I've got an inductive sensor: LJ12A3-4-Z/BX after going through Tom’s post on sensors. It’s definitely worth watching the entire video as well as reading the text. Note that’s a Normally Open probe, it should be Normally Closed.

It’s rated to trip at 4mm distance, but with the Ender-3 Pro magnetic bed cover it’s more like 1mm. I might switch to an 8mm rated probe; and get it Normally Closed. For now, I’ve ordered a spring steel cover with a PEI sheet.

Sensor mount:

I printed a thingiverse sensor mount that looked good to me. It appears to have less airflow blocked and I was able to reuse my old screws.

Here’s the sensor and mount:

unnamed.jpg





The sensor sits off to the left when the x axis is at zero, and it can’t reach the last 50mm of the bed on the right. This offset is defined here:

#define X_PROBE_OFFSET_FROM_EXTRUDER -45  // X offset: -left  +right  [of the nozzle]
#define Y_PROBE_OFFSET_FROM_EXTRUDER 6  // Y offset: -front +behind [the nozzle]

In order to use it as a z limit switch, Marlin offsets the x/y axis when it homes the z axis. This is configured by uncommenting the line:

#define Z_SAFE_HOMING

The final offset can’t be set until the probe distance is closer to 4mm. The gcode documentation on M851 explains how to calculate it, then it can be configured as a default in the firmware:

#define Z_PROBE_OFFSET_FROM_EXTRUDER 0   // Z offset: -below +above  [the nozzle]

Sensor Circuit:

3d - 1.JPG


Random Stuff:

I noticed this reuse of the old z height sensor as an extruder empty sensor, might try it with Octoprint down the road:

https://www.thingiverse.com/thing:3352422

There’s a lot more to configuring for bed leveling, and calibration in general, I think I’ll create a separate post for that.

Configuration:

I started sifting by looking at the "bed leveling" section of Marlin’s Configuration.h fil.  There are choices to make (see options at end of this email).

If automatic leveling is desired, note that the G28 "Home" command disables it each time.  I suppose that custom auto-leveling gcode needs to be set up in the slicer anyway, just remember to include re-enabling it, e.g. with "G28 A" for UBL.  (Edit: there's a compile flag "RESTORE_LEVELING_AFTER_G28" that can disable that behavior, but it's commented out by default.)

"Unified Bed Leveling" AUTO_BED_LEVELING_UBL claims to take the best of everything.  It builds a fine-grained mesh of bed curvature during calibration, and that gets saved in eeprom.  Before each print you tweak with a three-point automatic probe, to correct for tilt. See the three examples at the bottom of this link:  http://marlinfw.org/docs/gcode/G029-ubl.html

First example: automated full mesh creation during calibration.

Second example: I assume this is used post full mesh, to tweak bad areas after printing a test pattern.

Third example: adjust for tilt before each print?

Saving the mesh for UBL could be an EEPROM storage problem though.  All three examples use the "G29 S1" command to store the correction mesh in "slot 1".  UBL gratuitously allocates these slots at the top of EEPROM.  Note the examples also issue the regular M500 (save config to EEPROM), to save "UBL's state information".

/**
 * Choose one of the options below to enable G29 Bed Leveling. The parameters
 * and behavior of G29 will change depending on your selection.
 *
 *  If using a Probe for Z Homing, enable Z_SAFE_HOMING also!
 *
 * - AUTO_BED_LEVELING_3POINT
 *   Probe 3 arbitrary points on the bed (that aren't collinear)
 *   You specify the XY coordinates of all 3 points.
 *   The result is a single tilted plane. Best for a flat bed.
 *
 * - AUTO_BED_LEVELING_LINEAR
 *   Probe several points in a grid.
 *   You specify the rectangle and the density of sample points.
 *   The result is a single tilted plane. Best for a flat bed.
 *
 * - AUTO_BED_LEVELING_BILINEAR
 *   Probe several points in a grid.
 *   You specify the rectangle and the density of sample points.
 *   The result is a mesh, best for large or uneven beds.
 *
 * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling)
 *   A comprehensive bed leveling system combining the features and benefits
 *   of other systems. UBL also includes integrated Mesh Generation, Mesh
 *   Validation and Mesh Editing systems.
 *
 * - MESH_BED_LEVELING
 *   Probe a grid manually
 *   The result is a mesh, suitable for large or uneven beds. (See BILINEAR.)
 *   For machines without a probe, Mesh Bed Leveling provides a method to perform
 *   leveling in steps so you can manually adjust the Z height at each grid-point.
 *   With an LCD controller the process is guided step-by-step.
 */

But … I ran out of memory when I enabled any of the bed leveling approaches. I tweaked a few minor things without much reduction.  I've got two choices for major PROGMEM reduction:

- Disable the SD card (i.e. no print from SD).  So prints won't run without a supporting Raspberry Pi.

- Disable menus (only the status screen is displayed).  OctoPrint would kick things off but the printer would operate on its own.

As long as OctoPrint can give me the control and status I need, I think printing from SD is more important.

With menus disabled and SD supported, I can enable any of the bed leveling modes, including Unified.  So I'll try Unified, and see if OctoPrint gives me all the controls I need.

Here's the breakdown:

Unified requires ~41kBytes; Bilinear ~11kBytes. I had 7600 Bytes available before all this.
Saved ~14kBytes by disabling prints from SD:

//#define SDSUPPORT

Saved ~43kBytes by disabling the LCD menus.  Maybe slim menus are broken, they didn't save any memory: 

/**
 * LCD Menu Items
 *
 * Disable all menus and only display the Status Screen, or
 * just remove some extraneous menu items to recover space.
 */
#define NO_LCD_MENUS
//#define SLIM_LCD_MENUS

UBL Calibration without LCD:

The docs suggest that calibrating UBL without an LCD is difficult.  With no knob, you've got to issue "M421 - Set Mesh Value" repetitively to tweak mesh points.  M421 Q allows for a relative offset, so while it may be painful I don't think it's impossible.  Plus there's a comment: "Manual probing of locations USUALLY NOT NEEDED!!!!", so maybe it's not all that bad.

http://marlinfw.org/docs/features/unified_bed_leveling.html#ubl-without-an-lcd

http://marlinfw.org/docs/gcode/M421.html

http://marlinfw.org/docs/features/unified_bed_leveling.html

Tom Doyle