Marlin: Random loss of MESH settings

Created on 13 May 2016  Â·  47Comments  Â·  Source: MarlinFirmware/Marlin

There are a bunch of us using RC6 on the Robo3D forums and they have all gradually been moving to MESH bed leveling. All of us have seen strange behaviour that we cannot duplicate on a consistent basis. We do not even know how to make it happen. The issue is:

After performing the MESH routine, either on LCD screens or in terminal mode and then saving memory locations to EEPROM, we can all get a handful of prints that work perfectly. After a period of time a subsequent print will not print properly and upon investigation it is discovered that MESH is no longer enabled.

It can usually be restored by adding M501 to the start up gcode. Typical start up code will contain G28 followed by G29 (very useful to see if MESH is enabled). Most of us have made an adjustment to add M501 between the G28 and G29 commands. It does not appear to be 100% reliable. This is spread across several users, some with printers that stay on 24/7 (like mine) and others that are completely shut off between printing sessions.

We are at a loss to figure out why MESH leveling exhibits this behaviour and thought opening a ticket, despite having little details as to the circumstances might be the best approach to resolving this issue.

Confirmed ! Patch

Most helpful comment

@WheresWaldo Finally got around setting up my printer for testing this. So the code I have for you to test right now is here https://github.com/epatel/Marlin/commits/marlin/g28_single_axises

It is a clean config so you need to apply all your own configs. I added the MESH_G28_REST_ORIGIN option to keep it close to what is head of RCBugFix. Enabled the nozzle will travel to Z height 0, otherwise be left at Z endstop trigger position.

I also added a G29 S5 option to reset MBL. Just as an options to actually turning it off, otherwise with these changes that gets hard. M501 will load it again and G28 will enable it.

I also tried to fix so the display will show the correct Z just after a G28.

All 47 comments

I have seen a couple comments about mesh leveling turning off after a G28 when not all axis are homing. Which is by design, maybe not good but when I was implementing that part it's an open issue what the machine can be expecting the user want. Is doing homing for easy movement or am I homing because the axis is really unknown? Well, that part can definitely be improved. Personally I'd say homing to max endstops and allow homing individual axis would be good to do. I could look into that but...

Interesting. This is part of why I was also investigating save/restore the mesh with M503 and M421 in #3745 (I'm sure there is some history I'm not aware of the overlap between G29 and M421).

In any case, I've been experiencing this loss of the mesh and printing in mid-air. If it's related to non-G28 homing, that makes some sense as the XY and Z home buttons are in OctoPrint, but I don't think there is one to do all axis in one click, so I have been doing both occassionally.. ;)

It makes sense if this is due to not knowing where true home is relative to the mesh, but the UI/Pronterface should really show the mesh is magically no longer in effect.

Hmm, I can't say if this is a homing issue or not. What I can say is that if it isn't homing in all axis with a simple G28, then there is other issues involved. I do not home axes singly. They are always done as a set with a single G28 command, but I will keep an eye out for odd behaviour. What I do find is that if you issue a G29 and MESH isn't in memory it does correctly say mesh is not active. I have never had the MESH settings not restore when issuing an M501 command.

My problem may be related. It is homing all axis fine and never prints in the air but after a random number of prints the offset moves by itself and prints to close to the bed to extrude filament. Happens even with M501 in start code. After this happens iv even tried a G29 S4 Zx.xx to adjust the offset but it doesnt move the offset at all. Only fix is to rerun bed leveling where it works for a few more prints then reverts to the same issue.

Hmmm. Sounds really weird. Not sure I'd contribute that to MBL, as it is just an offset that is added to the position the printer think it is at. Doing a G29 S0 before and after things get weird should show an identical setup, I'd guess, because it should always be reading from the mesh values (nothing is changing values in the mesh). If it is not the same values before and after something is rotten in denmark (that meaning a severe bug exists that overwrite memory this memory somehow). The actually inject point for MBL is an expression as

print.z = model.z + mbl.z(model.xy)

But a sidenote, 2 yrs ago I was testing "raise when travel" or similar feature in Slic3r. Doing this on an old Sells Mendel w/o MBL (not implemented back then). When enabled raised Z/the Nozzle and then lowered it again. This had a weird effect I did not expect because it drifted, so I stopped using that. What My reasoning or expectation back then was that the floating point number calculations in the Z axis wasn't good, and probably really bad for relative movements. I always do a G28 with all axis as part of starting a print. This should sync the left part of the above formula. There is really two coordinate systems in play here, the 3D model/gcode and the printer hardware which is the integer counters in the steppers routine. I expect doing many relative movements is hard to keep track of absolut position, i.e. moving X axis 10 times +0.1 and then going back a single -1.0 (see https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). So this was what I expected happening when I enabled those extra lift (specially bad for Z that is moved in small small increments). Some numbers being worse than others, i.e 0.1 is really bad compared to 0.125. I haven't investigated the full path how the numbers go from gcode coordinates to stepper counters but that path is very important, and absolut positioning is definitely preferred I believe. (and starting with a G28 is a way to sync these two coordinate systems when doing a print)

I can see that mbl.active was made to a bool in this commit.
https://github.com/MarlinFirmware/Marlin/commit/0493fccc0bde14bdd390abcf2b1e59855faed7c7 but I think he forgot a couple other places (i.e. in EEPROM saving and reseting it at end of G28). I selected a unit8_t in the original implementation just to be sure so there would not be any questions about sizes etc. But, in theory it looks like these changes should work anyway, still, keeping it as a uint8_t wouldn't add this nagging feeling.

This https://github.com/MarlinFirmware/Marlin/blob/1.1.0-RC6/Marlin/Marlin_main.cpp#L2562
and this https://github.com/MarlinFirmware/Marlin/blob/1.1.0-RC6/Marlin/Marlin_main.cpp#L2866
and this https://github.com/MarlinFirmware/Marlin/blob/1.1.0-RC6/Marlin/configuration_store.cpp#L205

Hi epatel, just installed RC6 (previously used RC3) and found with my start config:-
G28 X0 Y0
G1 X141 Y178 F4000
G28 Z
Mesh bed level, when Printing, does not work at all, even though EEPROM contains the MBL data.
I read Brian Dowling's post and added the M501:-
G28 X0 Y0
G1 X141 Y178 F4000
G28 Z
M501 ; Reads Parameters from EEPROM, with this command added (in my case) MBL will then function while printing

I have a RAMBO v1.2 board in a MendelMax-3 printer

Regards - Bruce

https://forum.e3d-online.com/index.php?threads/marlin-fw-1-1-0-rc6-and-mesh-losing-its-mind.1330/

WADZoQUADZ and I are in the same group using RC6 on a Robo3D R1 series. It is basically a Mendel90 clone. Mesh is working perfectly when it works. When I first started using it I removed the G29 command from my startup, because I saw no need to display the MESH values on every print. But then experienced the same issues that he has, either printing too high or not high enough. I got fed up, on one such print and cancelled it during layer 1, then decided to investigate by issuing individual command from OctoPrint terminal, first a G28 which seemed to work perfectly then a G29 which told me MESH was inactive. At that time I didn't think that MESH setting might still be in EEPROM and I redid the MESH procedure. This happened multiple times during the next week and became very tiring redoing a procedure that essentially should not need to be redone if all we are doing is printing. That is at the same time seeing others complain about losing MESH on their printers. We came up with the M501 work around but have found that it too is inconsistent. So that is why I opened a ticket here. We must be close to seeing RC6 either become RC7 or a gold release and this is a real annoyance that needs diagnosis and a solution before that time. As a result of my involvement in the Robo forums we have a willing but small group of dedicated users that are using RC6 properly configured for our printers and using MESH. Any changes made can be tested with us and we will quickly be able to tell the team if they are successful. We also have a very active thread about Marlin 1.1.0 on our forums.

If we can get this into RCBugFix I am sure our group can test it there. It only takes me a couple of hours to generate the multiple sets of configuration files for the various revisions of printers that Robo3D all call the R1.

A side question for @bruce356 and @bdowling Why an M503? Doesn't that just echo what is already stored in EEPROM rather than re-implement it as M501 would?

@WheresWaldo I think i was the only one using 503. That was my initial attempt at viewing and wanting to do save/restore from CLI due to the headaches I was experiencing with mesh not seeming to work consistently. I thought 503 output could be replayed, but then found M421 not working.

I had also spent the time to do a very precise mesh level and restored eprom just to do a compare to what it was and then wanted to input the last one back. I ended up doing so by mapping to M29 S3 index based commands.

@bruce356 - Is your separate Z and XY homing done there because your z probe is out of bounds at 0,0 or just because you don't want to coast across the print bed to center? That separated homing action is what is triggering the disablement of mesh...

Hi bdowling, I use an IR sensor and yes when X & Y are at 0,0 the sensor is out of bounds and has nothing to sense but air. I therefore then move X & Y so that the IR sensor is over the center of my bed and then initiate homing of Z.
regards - bruce

@epatel at the end of G28 should you be checking for axis_homed across all three rather than home_all_axis was done in one shot? Would seem to support the cases in the wild where folks do their homing independently for various reasons.

https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L2863
Eg as in here https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L3975

Edit: of course you'd need to also keep track of mbl wa_ active in the MBL object across calls to G28 in that case.

@bdowling It might or it might not be that simple. Is it really safe turning MBL on and off at any point? Maybe it is, but I haven't thought through all those special cases. i.e. only homing a single axis independent of the others. By homing all axis we _(I)_ am sure that we are at a "known" position. In this case I wanted to be on the safe side first. When I added MBL the first time I was hoping to get it in and then be able to improve it after people started to use it. But the process just to get it in the repo the first time I had to have long discussions about the ins and outs and people not seeing its worth or believe it was good for Marlin. Even questioning the code size (though it obviously is very short). I did try to improve it a couple if times later but those times also required long discussion so those improvements never got in. They did get in recently now in RC when I created a PR again (MBL being more interesting these days I guess) https://github.com/MarlinFirmware/Marlin/pull/3232
My coding process is to think about it first and then code and test before I do a PR. I rather not be involved in long fruitless discussions. @Roxy-3DPrintBoard has flagged that she is implementing a auto measuring step for MBL which would be very nice. So I am also a little reluctant to change things in MBL before she is ready (others don't seem to think like this). I did make one myself but I never even tried to get that in, for various reasons. http://www.thingiverse.com/thing:1120142

I see this and another thing that could definitely be looked into for MBL

  • Homing to max endstops
  • Homing individual axis

https://github.com/MarlinFirmware/Marlin/issues/3750#issuecomment-219083523

Why I not just do it, is that I'd like to think through its effects, to be sure it will behave as expected.

Well, for title topic I have no answers. MBL is in its implementation very simple and there are so few places that turns it on/off so either there is another (i.e severe pointer bug) or something thats makes the printer take a path that turns MBL off. The places to look for is mbl.active = false; and mbl.reset();

I would so like to see @Roxy-3DPrintBoard's changes working and integrated. That's the one thing holding me back from trying this feature and continuing to use ABL instead.

@bdowling If I don't misinterpret you, this line https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L3975 actually require all axis to be homed for ABL, and the comment above also says so, see https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L3968

!axis_homed[X_AXIS] || !axis_homed[Y_AXIS] || !axis_homed[Z_AXIS]
has the same logic as
!(axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
which there means, if any axis is not homed report the error and exit.

@epatel -- Yes exactly, I understand why you want to insure that all axis have been recently homed for MBL to be enabled, it's a good safety check. Using the axis_homed[] array test establishes that for you. People have reason to do independent G28 as has been shown by the bug reports.

!(X && Y && Z) reads cleaner in my view. There are also a number of places that this test occurs in the code -- perhaps there should be a ALL_AXIS_HOMED MACRO or simple function applied and used in those cases?

I think part of the problem that is not clear to me yet -- haven't dug into it -- is what is the behavior when MBL is disabled? With MBL compiled in, there's really no z_offset setting? so I'm not clear I understand where the heads end up on Z in relation to the bed. e.g. is it Safer? or is this why some are seeing head crashes?

@bdowling No offset setting? No not really, MBL is basically an adaptive offset over the whole bed. So it all depends of the probed points what the "offset" is in each probed point and then MBL interpolates between those points. MBL has the G29 S4 that can be used to tweak the overall offset if one i.e. would like a first layer closer/pressed to the bed.

Yes, but when mbl.active == false. What does it fallback to using as an offset?

@bdowling About head crashes my initial commit required the Z endstop to be slightly above the bed just to safe guard against this. Some seem to have skipped that part I think. See this for recent changes and some rationale behind old and new setup https://github.com/MarlinFirmware/Marlin/pull/3488

@bdowling Offset when MBL is disabled? Nothing = 0, so it depends on where the nozzle happen to be (or we can call this the hw coordinate system)

Something is amiss here with this as well..

M501
G28
--> Z=0

G28 Z ; force mbl to disable ; Nozzle is further (~1.5mm) from bed than when MBL is enabled.
--> Z = -3,99 ; M114 reports Z = -4
G0 Z1 ; Z=1 M114 reports Z = 1
G0 Z-2 ; Z=1.99 M114 reports Z = -2

Also Note: Even when MBL is active, I can set G0 Z-4 to crash the heads into the deck (unless I dock them first).

@bdowling I am trying to make sense of the code. Lets break it down.

These lines https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L2862-L2876 will only take effect if MBL is enabled (compiled in) and will be enabled (active) after these lines has been executed, homing-all-axis. So, MESH_HOME_SEARCH_Z will not be used on line 2864 if homing only the Z axis

But, it is used on line 2628 https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L2628 and set on line 2646
https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L2646
And...Homing Z might not finish if you have Z_SAFE_HOMING enabled it looks like, not actually doing the homing on line 2810 https://github.com/MarlinFirmware/Marlin/blob/RC/Marlin/Marlin_main.cpp#L2810 thus leaving the current position on MESH_HOME_SEARCH_Z.

Well, just a theory.

To validate you could for a test hard code two different values at those lines and see what value M114 will report. i.e put 3 and 5. If you get either you know which, and if you still get 4 you know it's from somewhere else.

Maybe the better condition is to ask if all axes are homed now, instead of which axes we ordered to home in this G28.

  // For mesh leveling move back to Z=0
  #if ENABLED(MESH_BED_LEVELING)
-    if (mbl_was_active && home_all_axis) {
+    if (mbl_was_active && (axis_homed[X_AXIS] && axis_homed[Y_AXIS]) && axis_homed[Z_AXIS])) {
      current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
      sync_plan_position();

@Blue-Marlin Not sure that will work, say you didn't home Z but it was "homed" from before, so its position could be anywhere along the Z axis, then the lines beneath would screw things up.

if (mbl_was_active && (home_all_axis || (axis_homed[X_AXIS] && axis_homed[Y_AXIS]) && homeZ)) {

???

Hi, I've also noticed that the mesh is lost after homing not all axes in RC6.
I think that the main issue with this from a user's point of view is that the mesh bed leveling isn't just deactivated, but the mesh is really lost and can not be recovered, i.e. the leveling process has to be run through again (if the mesh hasn't been saved to the EEPROM of course).
Would it be possible to re-activate MBL with the previous mesh values after homing all axes (G28) again?
Besides this, I think that the most proper solution would be a dedicated G-code command do activate/deactivate MBL.
Btw, @epatel Many thanks for having made MBL possible. I consider this to be a true killer-feature and it is the main reason for me using Marlin.

@winxi01 why do we need special handling of short-term mesh settings? If they are good, save them to eeprom. You can reactivate mesh from eeprom with:

G28 ; home
M501 ; load eeprom
G29 ; check mesh enabled

I'm going to be testing some of the other suggestions for not disabling mesh provided the global homing states are good, add this seems like a crux cause to some issues being seen in the wild.

Unfortunately, M501 loads more things besides MBL, so it's not an ideal solution. Force-writing the current settings (transparently) at the end of MBL to save the matrix is also not ideal for the same reason. Users must always be aware —and should always initiate— writing their current settings to EEPROM.

Btw, @epatel Many thanks for having made MBL possible.

Ditto. I really appreciate this feature, which really makes a modest RepRap work better.

Btw, @epatel Many thanks for having made MBL possible.
I would all so like to add my gratitude for this great very accurate MBL, I only use this and no longer the ABL.
@thinkyhead yes you are right M501 did have some (for me) unforeseen consequences as it loads other things saved to eeprom that one does not necessarily want loaded.
What about using M420 S1 to enable MBL or M420 S0 to disable MBL, would this be a better option to use.
regards - bruce

@winxi01 @bruce356 Thanks for the kind words. Great to actually hear people using and liking MBL.

One option could be to make mbl.active a uint8_t again and use that as bitfield. Where 0x01 could mean than MBL contain numbers from a probe-session, and 0x02 for flagging it being in active use. This way we can remove the mbl_was_active flag and only look for mbl.active & 0x01 in G28 and then turn 0x02 on (and adding the check so mbl is only added when 0x02 is set). The result would be that one just do a G28 and then MBL should be on again, if one happened to turn 0x02 off (somehow, i.e. with a single G29 Z). If we get homing single axis working this might not be needed though.

I just ran a test running RCBugFix from Sunday May 15. Here were the steps and result. Compiled firmware and uploaded it. Warmed the bed and hotend. Ran MESH procedure, saved to EEPROM. Verified MESH by issuing a couple of commands from an OctoPrint terminal. G28 homed all axes. G29 showed MESH settings. Upon completion of first print ran G28 to home all axes, then issued a G29 which informed me that MESH was not active. Used the workaround of issuing an M501 and now MESH is back. This is repeatable behavior.

@WheresWaldo Could you perhaps have some "End G-code" (i.e. Slic3r) that might do a G28 X Y?

@epatel Yes that was it, my end gcode had a G28 X0 which seems to turn it off and remove the mesh from memory. I will switch this to a G1 X0 instead.

Still, why would there be a need to turn the MESH off? Especially since every job usually starts with a G28 to home all axes.

@WheresWaldo It's one of those safety precautions. I haven't thought through the ins and outs of a single axis homing case and my gut feeling is that it can be edge cases that could cause it all to get shifted. Maybe it is simple maybe it's not. I haven't had time to think that though (and I haven't had my dev system setup for Marlin in a long time) Will try to do that now. Would you like to be my tester for this?

Rationale for turning MBL off is because a G28 really means the nozzle is at an unknown position, so doing the MBL compensation if basically wrong and can be dangerous.

@epatel As I mentioned earlier, I have a willing group of about four or five people that are convinced MESH is the best leveling method for our machines. I would be happy to test code to make MESH more robust.

Sorry, I did not mean to close this as it is still in need of resolving. I hit the wrong button.

@WheresWaldo OK, I'll start to look into making this. Make it possible to home axis separately. Did some thinking about it today and it might be special cases are only homing Z or not Z. Need to get the logic right. And right now I think home Z is basically what we have and I hope not homing Z do not require any math/offsets.

@epatel I already have a few people interested in testing this.

@WheresWaldo Yesterday I started chisel out a path to do this. Looks like I will need to run a couple tests on my own machine first just to figure out a couple things. So hopefully I can get to it this weekend.

@WheresWaldo Finally got around setting up my printer for testing this. So the code I have for you to test right now is here https://github.com/epatel/Marlin/commits/marlin/g28_single_axises

It is a clean config so you need to apply all your own configs. I added the MESH_G28_REST_ORIGIN option to keep it close to what is head of RCBugFix. Enabled the nozzle will travel to Z height 0, otherwise be left at Z endstop trigger position.

I also added a G29 S5 option to reset MBL. Just as an options to actually turning it off, otherwise with these changes that gets hard. M501 will load it again and G28 will enable it.

I also tried to fix so the display will show the correct Z just after a G28.

@epatel I downloaded your code this morning and created some easy to follow instructions on the Robo3D forum for the few of us there to test. It includes instructions on replacing the default configuration files with ones appropriate for all flavors of the Robo3D R1 printers that exist. We should have a few testing it by this evening.

The particular post is located here: http://community.robo3d.com/index.php?threads/marlin-firmware-upgrade-1-1-0-release-candidate-6-for-r1-r1-plus.5806/page-25#post-76965

@epatel I have been testing all evening with your patch and cannot make MESH fail in any normal usage scenarios. I also really like the true position after homing display. It actually works the way I always expected my printer to work. I will see if there is more feedback on the Robo forums tomorrow.

@WheresWaldo Great to hear, I'll look into making a PR into RCBugFix

@WheresWaldo Created PR here https://github.com/MarlinFirmware/Marlin/pull/3835 a couple of commits between previous test and this + minor tweaks to fix the conflicts that appeared. Would be great if you could test this too.

My symptoms have gone away and no longer manifest themselves with RCBugFix from a few days ago. As far as my portion of this discussion, it can be closed.

Short: Tested and working.

@WheresWaldo Yes, It seems to have been merged now. So you may close it I think.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mpm1396 picture mpm1396  Â·  729Comments

alexxy picture alexxy  Â·  192Comments

Liger0 picture Liger0  Â·  169Comments

Squid116 picture Squid116  Â·  172Comments

kAdonis picture kAdonis  Â·  169Comments