Marlin: [bugfix-1.1.x] Bed leveling keeps defaulting to Off

Created on 13 May 2018  路  34Comments  路  Source: MarlinFirmware/Marlin

Description

For some reason, on bugfix-1.1.x (checked out a week ago), whenever i restart, the bed leveling defaults to off for manual mesh leveling.

Steps to Reproduce

  1. Use manual mesh leveling
  2. Level the bed
  3. Store to EEPROM
  4. Restart the board

Expected behavior:

Bed leveling stays on.

Actual behavior:

Bed leveling defaults to off. Sometimes, the bed leveling on/off toggle is missing completely in the menu, and shows up after a few homes. Could not reproduce that bit consistently, though.

I am not 100% sure if this is a legitimate bug / regression, or me missing some step since the UBL was introduced.

Bug? Feature! Calibration Question

Most helpful comment

After a reboot, and a G28, bed leveling is still off, and i need to turn it on manually.

Correct! You _always_ need to turn on leveling manually (M420 S1) at some point. It's not turned on automatically on reboot because the machine has no idea of its position. As I tried to explain earlier, RESTORE_LEVELING_AFTER_G28 only enables leveling after G28 if it was _already_ turned on _before_ G28.

If what you're looking for is to have leveling _always_ be enabled after G28, we don't have such an option at this time. If that's what you prefer, make the following change to gcode_G28:

- #if ENABLED(RESTORE_LEVELING_AFTER_G28)
-   set_bed_leveling_enabled(leveling_was_active);
- #endif
+ if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
+   set_bed_leveling_enabled(true);

as MBL is (soon to be) deprecated?

No, it is never going to be deprecated. It is small and therefore useful for small boards that can't use the more resource-demanding ABL and UBL.

All 34 comments

UBL allows you to control the default state of the bed leveling activation. This is a departure from the past where the printer powered up with no bed leveling. If you want the printer to power up with UBL Bed Leveling Active, do this:

  • G28
  • G29 L 1 (load your mesh from the appropriate slot)
  • G29 A (turn bed leveling on)
  • G29 S 1 (store your mesh into the same slot)
  • M500 ( Re-save configuration settings)

Reset your printer.... And do a G29 W It should say you have Mesh 1 loaded and bed leveling is active.

Ah! Thanks, will try that.

I thought that opening the bed leveling menu, toggling on bed leveling and re-saving from menu yielded the same result.

Well... The problem is there needs to be a way to provide backward compatability. Most people expect bed leveling to be inactive when the printer powers up. And some people feel very strongly they don't want it active until they explicitly turn it on.

So... I set it up where you can make it active at power up. But it won't happen by itself. In future releases... It might make sense to flip that. If you really want it inactive at power up, you can make that happen, but you have to take action to make that the case.

Most people expect bed levelling to be inactive when the printer powers up.

That's... Odd. What's the use case?
Why do people set up bed leveling and then want it off by default? o_O

Anyways, i'd swear it was on by default in RC6 or RC8, whichever i had before switching to 1.1.x.
Might just be my bad memory, though.

No... It pertains more to the history of bed leveling. The original G29 was for 3-point leveling. G28 turned off any bed leveling (if it was on). Then came grid based bed leveling. And it was the same story. G28 turned it off if it was on.

Next came mesh based bed leveling. And G28 turned it off if it was on. And in all cases up to this point, the printer powered up with no bed leveling active.

With UBL... I wanted to change that. Or at least allow people to power up their printers with bed leveling enabled. But it is important to respect past history and people's expectations. So right now, you have to jump through a small hoop to make that happen.

We may be at the point in time where we can change the default for UBL to be on at power up. But still allow people to make it the opposite if they choose.

Anyways, i'd swear it was on by default in RC6 or RC8, whichever i had before switching to 1.1.x.
Might just be my bad memory, though.

If you followed the 'cheat sheet' to bring up UBL... The instructions do lead you down a path where it is turned on by default.

Also worth remembering that the state of bed levelling after a G28 is now a configuration option (RESTORE_LEVELING_AFTER_G28), I can't remember what the default is. But it could be that a G28 is turning it off even if you have it on when the printer powers up.

Since the machine has no idea what the current position is on startup, it would make little sense to enable leveling right at boot time. The spec for G28 is to disable leveling, but as @gloomyandy points out, we now have the RESTORE_LEVELING_AFTER_G28 option to restore the state of bed leveling to whatever it was just before G28. The one guaranteed way to ensure that bed leveling is enabled, when there exists leveling data, is to use G28, M420 S1. There is no option that forces bed leveling to be turned on by G28.

Also worth remembering that the state of bed levelling after a G28 is now a configuration option (RESTORE_LEVELING_AFTER_G28), I can't remember what the default is.

I think this might be my actual problem.
Because (and i realize now i've formulated my issue badly) i don't actually mind bed leveling being off in post-boot state, but it being off after homing.

Thanks for the tip!
And thanks everyone for the explanations!

I'm not crazy after all.

Turns out i had RESTORE_LEVELING_AFTER_G28 enabled after all.
Bed leveling is not on after a G28.

I've tried:
G29 L1
G29 A
G29 S1
M500

After a reboot, and a G28, bed leveling is still off, and i need to turn it on manually.
Additionally, after doing G28, G29 L1, G29 A, G29 S1, M500, the leveling on/off item disappears from the menu until the next G28.

There's other weirdness too...
I just got this on another try:

Send: G29 S1
Recv: echo:enqueueing "G28"
Recv: ok
Recv: echo:enqueueing "G29 S2"
Recv: echo:Active Extruder: 0
[...]
Recv: echo:Active Extruder: 0
Recv: X:150.00 Y:100.00 Z:0.00 E:0.00 Count X:15038 Y:35821 Z:0
[...]
Recv: MBL G29 point 1 of 9
Recv: X:10.00 Y:10.00 Z:0.00 E:0.00 Count X:1003 Y:3582 Z:0
[...]

Additionally, whenever i do G29 A, i get "State: Off".

Send: G29 A
Recv: State: Off

Okay, correction...

I've just realized i've got MBL enabled, not UBL (must've accidentally reverted Configuration.h last time i've reflashed).

Even so, original question remains - State is always Off until i turn it on via the menu. On every boot. Also, the menu item disappears occasionally. I assume that's all normal, as MBL is (soon to be) deprecated?

Just reflashed and confirmed that with UBL the suggested sequence (G29 L1, G29 A, G29 S1, M500) works as expected (UBL enabled after a reboot and a home).

So that leaves just one question - how do i get MBL to retain its on state after a reboot and a home? That is, if MBL is not getting scrapped completely any time soon...

By the way... I've noticed this remark by @Roxy-3D in another issue:

Historically... G29 always is disabled by a G28.

This is simply not true. I've had MBL on since RC4 at least, never ever used G29 in my gcode, and MBL was always active on boot, and after a G28. So no, historically, G29 has not always been disabled by a G28, and retained last state upon a reboot (at least for MBL, can't say for ABL, as i don't use probes nor see a point in running BL calibration more than once every 3-4 months). I'm guessing this got changed somewhere along the line, and no one remembers anymore, as their upgrade path was more gradual. I skip whole years between Marlin releases, so i notice drastic changes in behaviour more readily.

This is simply not true. I've had MBL on since RC4 at least, never ever used G29 in my gcode, and MBL was always active on boot, and after a G28. So no, historically, G29 has not always been disabled by a G28, and retained last state upon a reboot (at least for MBL, can't say for ABL, as i don't use probes nor see a point in running BL calibration more than once every 3-4 months).

I'm not sure how that can be the case. Looking at v1.1.8 the code at the start of G28 is:
https://github.com/MarlinFirmware/Marlin/blob/1.1.x/Marlin/Marlin_main.cpp#L3987-L3994

  // Disable the leveling matrix before homing
  #if HAS_LEVELING
    #if ENABLED(AUTO_BED_LEVELING_UBL)
      const bool ubl_state_at_entry = planner.leveling_active;
    #endif
    set_bed_leveling_enabled(false);
  #endif

And at the end of G28, the only bed leveling system that is turned back on is UBL. That is done here: https://github.com/MarlinFirmware/Marlin/blob/1.1.x/Marlin/Marlin_main.cpp#L4139-L4142

  #if ENABLED(AUTO_BED_LEVELING_UBL)
    set_bed_leveling_enabled(ubl_state_at_entry);
  #endif

Maybe you were using UBL?

After a reboot, and a G28, bed leveling is still off, and i need to turn it on manually.

Correct! You _always_ need to turn on leveling manually (M420 S1) at some point. It's not turned on automatically on reboot because the machine has no idea of its position. As I tried to explain earlier, RESTORE_LEVELING_AFTER_G28 only enables leveling after G28 if it was _already_ turned on _before_ G28.

If what you're looking for is to have leveling _always_ be enabled after G28, we don't have such an option at this time. If that's what you prefer, make the following change to gcode_G28:

- #if ENABLED(RESTORE_LEVELING_AFTER_G28)
-   set_bed_leveling_enabled(leveling_was_active);
- #endif
+ if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
+   set_bed_leveling_enabled(true);

as MBL is (soon to be) deprecated?

No, it is never going to be deprecated. It is small and therefore useful for small boards that can't use the more resource-demanding ABL and UBL.

I'm not sure how that can be the case. Looking at v1.1.8 the code at the start of G28...

Yes, that's how it's now.
Look at older releases (e.g. 1.1.0 RC4):

  // For manual bed leveling deactivate the matrix temporarily
  #if ENABLED(MESH_BED_LEVELING)
    uint8_t mbl_was_active = mbl.active;
    mbl.active = 0;
  #endif

and then...

  // For manual leveling move back to 0,0
  #if ENABLED(MESH_BED_LEVELING)
    if (mbl_was_active) {
      current_position[X_AXIS] = mbl.get_x(0);
      current_position[Y_AXIS] = mbl.get_y(0);
      set_destination_to_current();
      feedrate = homing_feedrate[X_AXIS];
      line_to_destination();
      st_synchronize();
      current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
      sync_plan_position();
      mbl.active = 1;
      #if ENABLED(DEBUG_LEVELING_FEATURE)
        if (marlin_debug_flags & DEBUG_LEVELING) {
          print_xyz("mbl_was_active > current_position", current_position);
        }
      #endif
    }
  #endif

So no, it was not always that way, and behaviour did change.
In general, if a feature is not to be deprecated, changes to other features should not introduce backwards incompatible changes in them. Don't get me wrong, though, i applaud the effort poured into UBL and getting the BL code straight. I was just trying to:

  1. figure out if i was going crazy, and
  2. understand the reasoning and use case behind not persisting the bed leveling state

That is interesting! I didn't realize the original Mesh Bed Leveling did that. I guess this is proof of how hard it is to stay on top of things.

In general, if a feature is not to be deprecated, changes to other features should not introduce backwards incompatible changes in them.

Philosophically, I think everybody is in agreement. The problem comes from the fact there is so much shared code. Even though there are 5 different bed leveling systems, they all share large pieces of code such as the probing and G28. It is real easy to make a change for one thing and have side effects show up somewhere else.

uint8_t mbl_was_active = mbl.active;

Well, it's the same thing. (mbl.active is replaced by planner.leveling_active) If leveling wasn't active before G28 then it won't be turned on at the end of G28. At some point before that G28, an M420 S1 would be needed. And when !axis_known_position or !axis_homed it would seem best to disallow enabling bed leveling.

Yes, we did attempt at some point to save and restore the leveling enabled state to EEPROM, but this made little sense since the machine really should be homed before ever enabling leveling.

Well, it's the same thing...

It's a bit more complicated than that.
MBL had the described behaviour. ABL, however, would just reset the BL matrix to identity matrix pre-home, and that's it. I believe that's where the confusion arose over time - since most people have probes and use ABL, the majority got used to doing a G29 post-G28 and it became the norm.

Yes, we did attempt at some point to save and restore the leveling enabled state to EEPROM

No, not just attempt. It was a normal part of Marlin at least until RC8.

this made little sense since the machine really should be homed before ever enabling leveling.

That's technically correct (the best kind of correct), but completely irrelevant to the end-user use case. Having to insert G29 after a G28 into every print gcode is completely superfluous whichever way you look at it.

If you're operating a single machine, you want it with BL on after the home. Always. There is simply no use case where you occasionally want it off, justifying having it in the gcode prefix block in your slicer.

If you're operating multiple machines, you don't want the BL turned on via gcode because then gcode isn't portable. Again, no point in having G29 in your print job prefix.

Yes, the leveling makes no sense in unhomed state.
No, machine should not be homed before ever enabling leveling.
Machine should be homed before applying leveling.

Look at it from an end-user perspective - if you've set up bed leveling and have it on, the next time you start up your printer and home it, you expect bed leveling to still be set up, and you expect it to be applied.

Yes, this is nitpicking, but the point is, having to do G29 after a G28 before every print job offers 0 advantages, and is completely superfluous. I know what you'll say next - "then G28 is superfluous too". But that's apples and oranges, as G28 doesn't restore a state, it's a direct, mechanical action. It would be the same thing for ABL, if you were to do bed-leveling calibration on each power-on or before each print, but it's not the same thing for MBL, where it's simply a reload of a previous (saved and calibrated) state.

I ramble... Does any of this make sense?

Philosophically, I think everybody is in agreement. The problem comes from the fact there is so much shared code. Even though there are 5 different bed leveling systems, they all share large pieces of code such as the probing and G28. It is real easy to make a change for one thing and have side effects show up somewhere else.

Yes, it's (was) a complete mess, no argument there. If anything, all this "Marlin archeology" only makes me appreciate the effort going into UBL more. It's not perfect, but it's getting there, and the end result seems way tidier.

No, not just attempt. It was a normal part of Marlin at least until RC8.

Yes, well, including it in some releases was part of our "attempt."

Having to insert G29 after a G28 into every print gcode is completely superfluous

This is one reason got around to saving the leveling result to EEPROM so you can simply re-enable it with M420 S1. I've not had a G29 in my slicers' Start G-code since that change.

If you're operating a single machine, you want it with BL on after the home. Always.

M420 S1 will do it, at a cost of an additional 7 bytes in the G-code.

Look at it from an end-user perspective

Look at it from a standards perspective. G28 is specified to disable leveling. Adding an option to re-enable leveling after G28 is a compromise.

the [UBL] end result seems way tidier

In some ways, certainly. In others, not so much.

G28 is specified to disable leveling

Permanently, or during homing state?

Permanently, or during homing state?

G28 does single, clean, rapid moves till it hits the endstops to establish a known position, so of course it resets the involved axis to "unknown" then disables leveling before the move.

After G28 leveling is meant to be disabled. It's a reset of the machine state.

But by all means, feel free to alter your own installation according to your personal preferences so that G28 also does M420 S transparently. No one will begrudge you for it.

In a nut shell... With mesh based leveling systems... It makes sense to allow the bed leveling to be turned on automatically after G28. Right now, UBL has it turned on after power up but before the G28. I think ThinkHead is correct and this doesn't really make sense. But having it turn on automatically after the G28 does make sense (for some users).

I'm not sure when I'll get around to doing it... But I think I'll make it so UBL does not have bed leveling turned on until after G28.

After G28 leveling is meant to be disabled. It's a reset of the machine state.

Why doesn't it also disable all offsets as well, then?
After all, bed leveling is just an offset (dynamically calculated one, but an offset nevertheless).

Completely agree bed leveling in unhomed state makes no sense, by the way.

feel free to alter your own installation according to your personal preferences so that G28 also does M420 S transparently

Thanks, will do.

Why doesn't it also disable all offsets as well, then?

It does. G92 offsets are reset to 0. But not M206 (obviously).

Does it reset the hotend and probe offsets?

Try G28 and see for yourself whether it does or not. We've got a lot of work to do today.

This might be specific to Feb commits (need to test with newer ones), but M420 S1 doesn't really work as expected. I've included M420 S1 in my init gcode in the slicer, and after a boot, i still find the prints starting with MBL off.

I need to go into the menu (via the LCD), and turn on the bed leveling from there.

Only then does M420 S0 and M420 S1 start working as expected.
Very weird. Going to poke around more over the weekend.

but M420 S1 doesn't really work as expected

All it does is set a boolean to true. If you still can't solve the mystery after the weekend, post the G-code so we can try it.

The prefix G-code is literally:

;home
T0 ; select extruder 0
G28
M420 S1

After which the print starts without bed leveling. There are no further G28's anywhere in the gcode, until the postfix (after the print ends). Hence the mystery.

I don't think the issue is with M420, i think it might be some kind of an odd regression in set_bed_leveling_enabled. Will know more over the weekend.

When M420 S1 cannot enable bed leveling, it prints a message to console that bed leveling could not be enabled. Check for that in the output.

I had the same problem. My slicer puts gcode TX on extruder change (T0, T1, ...) and the auto leveling grid turns off after changing extruder! Maybe it's the same problem. Check gcode for T0, T1, ... string after G29.

I though I was going crazy too. I'm new to 3D printing, and I fell into the same trap.

While I disagree that the MBL matrix should not be applied after G28, I can understand why t was done thios way in the past. But I totally agree with @orcinus, especially since I'm a novice user that the MBL matrix should always be applied once manual bed levelling has been done. Because I feel this is the natural expectation for a novice user like me once manual mesh bed levelling was done.

At first I though the data just had not been stored, so I manually performed MBL every time I turned the printer on, which seemed odd. Then I found the option "bed levelling: off", but it is sometimes there and sometimes not, which is even stranger.

What I found now to work is:

  • turn printer on
  • auto home
  • THEN go to bed levelling and turn it on, it is not available before
  • then print.

But again, since auto homing is done anyway before every print, it seems tedious to home, then enable MBL manually, just so it auto homes again each print.

I don't use octoprint and only print from SD. I assume manual G Code can be added in the slicer, but since all of that is new to me, I haven't touched that.

EDIT: I just compiles bugfix-2.0.x, the issue is there too. is there a flag I can set during compilation that defaults mesh bed leveling to on?

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings