prusa3d / Prusa-Firmware

Firmware for Original Prusa i3 3D printer by PrusaResearch
GNU General Public License v3.0
2.02k stars 1.05k forks source link

Higher density mesh bed leveling #1239

Closed stahlfabrik closed 5 years ago

stahlfabrik commented 6 years ago

This seems like a low-hanging-fruit feature request

The MK3 mesh bed leveling is quite coarse, it only probes a 3x3 pattern. I had my heatbed exchanged because my old bed has a slight bow right where the PINDA does not probe - so the printer is blind to that. Also, in order for a super consistent first layer I generally wished I could configure the amount of leveling probe points.

The Klipper firmware makes the probe pattern configurable. I wished I could do that on my MK3, which runs the Prusa firmware.

Internally, the 3x3 grid is interpolated to a 7x7 grid. So an obvious way would be to add a "fine" MBL option in the printer settings, so that the printer scans a 7x7 grid and then does not interpolate anymore. It would be even better, if the number of probing points in X and Y direction would be configurable seperately. I would think in the range of 2 to 7.

I would love that - and I am sure the number of Heatbed replacements would go down if that would solve some first layer issues.

I think I remember a video on YouTube where Josef teased a menu config option for exactly that. It was when MK3 was still in internal beta.

Best regards

Pathogenius commented 6 years ago

Low hanging fruits are just as delicious and less chunks missing from bird bites!

The difficulty appears to be that the mainboard was already at capacity and clever work has already been done to facilitate recent development, leaving even less opportunity for increased function. Keep in mind that some like myself manually level the bed using wave washers or other methods long before we ask the mainboard to tighten up tolerances further. Given the above, it does suggest that this low hanging fruit is already on the ground rotting into worm food.

stahlfabrik commented 6 years ago

I know what you mean but I cannot agree. The 7x7 data structure is already in place so the amount of used RAM during printing should be exactly the same. The trick would be to not fill it by calculations (interpolations) but by measurements. I am of course not sure, but optimistic, that the little code changes and additions should fit into EINSYs flash. I also know the wave washer and other methods but even then: what do you do when the "Bow" is between two screws?

The optional "second stage" - allowing other grids as 3x3 or 7x7 need some more development in the interpolation function I think - I have not looked into the code. But the first stage (aka offering a 7x7 fine MBL) would make some users happy already.

RacingHell commented 6 years ago

This should be implemented as function for bed calibration. Taking a finer surface „snapshoot“ will also reduce the necessary points to measure in every day use if the code would be able to orientate the snapshooted surface by only scanning the 4 corners before starting a print, or even just one point?

mionut commented 6 years ago

I modified the command G80 to G80 N7 to measure with 7 points. But i didn't implement saving on power failure all 7x7 points, they are interpolated when power comes back. You can try it if you want. https://github.com/mionut/Prusa-Firmware . I am using this for some time, but i have an ups, i don't use power failure detection. The print bed surface warps with temperature change, i use 7x7 bed leveling all the time. I also wait 2 minutes in startup gcode for bed temperature to stabilize.

stahlfabrik commented 6 years ago

Very nice! I also thought about using a Gcode enhancement to make that function available - so I would not have to mess with the menu etc.

Still I hope that Prusa Research themselves provide a clean and nice implementation:-)

Crunch69 commented 6 years ago

mionut it looks like you also added another pinda temp offset 28c am I seeing that correctly if yes that is great that is also another feature that is needed

could you not just go to the configuration.h file and change the // set the number of grid points per dimension // I wouldn't see a reason to go above 3 (=9 probing points on the bed)

define AUTO_BED_LEVELING_GRID_POINTS 2 change this to a 3?

mionut commented 6 years ago

//#define ENABLE_AUTO_BED_LEVELING is commented in configuration.h , so AUTO_BED_LEVELING_GRID_POINTS is not used, also, this value is used for G29, not G80.

I will try to make a pull request with what i made for 7 points probing. Also my modifications work only with 7x7 or 3x3 points, because the internal matrix is 7x7. The current method is to measure only 3x3 points and interpolate the others.

stahlfabrik commented 6 years ago

@Crunch69 The whole idea of the feature request is to go over 9 measured points - optionally of course, cause it will take longer - most easily by using the "virtual"/interpolated 49 points that are used internally anyway by doing 7x7 (49) measurements. 3x3 is way to coarse if your bed surface is not perfect. Especially if the imperfection is happeing in between screws/standoffs. And yeah, there are also just 9 screws.

Please let us not talk about PINDA temperature here!

edspeds commented 6 years ago

I modified the command G80 to G80 N7 to measure with 7 points. But i didn't implement saving on power failure all 7x7 points, they are interpolated when power comes back. You can try it if you want. https://github.com/mionut/Prusa-Firmware . I am using this for some time, but i have an ups, i don't use power failure detection. The print bed surface warps with temperature change, i use 7x7 bed leveling all the time. I also wait 2 minutes in startup gcode for bed temperature to stabilize.

@mionut ..

As one who has issues with first layer consistency I was excited to try this... However, I run in to the following error when I try to compile your firmware,

sketch\Marlin_main.cpp: In function 'void process_commands()':

Marlin_main.cpp:4450: error: 'verbosity_level' was not declared in this scope

 if (verbosity_level >= 1) {

     ^

Marlin_main.cpp:4500: error: 'verbosity_level' was not declared in this scope

if (verbosity_level >= 10) {

    ^

Marlin_main.cpp:4515: error: 'verbosity_level' was not declared in this scope

if (verbosity_level >= 1)

    ^

Marlin_main.cpp:4534: error: 'verbosity_level' was not declared in this scope

if (verbosity_level >= 20) {

   ^

exit status 1 'verbosity_level' was not declared in this scope

To ensure the error wasn't due to the operator I decided to try to compile the latest official pull and was able to do so without issue.

Thanks for effort.

mionut commented 6 years ago

@edspeds, I remade the commits with every modification that i have locally, separated by logical function. I also fixed the compilation error. Please try now.

edspeds commented 6 years ago

@edspeds, I remade the commits with every modification that i have locally, separated by logical function. I also fixed the compilation error. Please try now.

It compiled without issue, thanks. I'll put this to the test this weekend.

edspeds commented 6 years ago

@edspeds, I remade the commits with every modification that i have locally, separated by logical function. I also fixed the compilation error. Please try now.

All compiled well but flash failed, multiple times...

CCS86 commented 6 years ago

Another vote for this feature request.

edspeds commented 6 years ago

@edspeds, I remade the commits with every modification that i have locally, separated by logical function. I also fixed the compilation error. Please try now.

@mionut are you still working on your firmware? Was kind of hoping to try a fix as your code compiles but errors out during flash.

Tinker999 commented 5 years ago

Wow, love the concept of just measuring and would like to try the G80 N7 but not sure how to get started. Is there a already compiled copy I could try. Sorry if this is a bit of a newbie question. I also have a UPS.

F0x06 commented 5 years ago

Hi, awesome work @mionut ! I tried to implement this myself before i've seen your work, im trying right now your version, this is a must have by default imho... Interpolated 3x3 is way too bad, for those that are unable to compile the firmware, here you go: firmware.hex.zip

Also, its possible for you to mege with the latest 3.5.0 version :) ? Thanks !

Pathogenius commented 5 years ago

Decent. For noobs like me who didn't change their Start G-Code 'G80' instruction to 'G80 N7', well just go right ahead and do that!

edspeds commented 5 years ago

Something must be up with my MK3 as the firmware posted by F0x06 still doesn't install correctly...

Any suggestions?

F0x06 commented 5 years ago

@edspeds You flashed it with Slic3r prusa edition?

Also ensure that any other apps using the serial communication such as pronterface are closed during flash

edspeds commented 5 years ago

Yep and I get a flash failed warning same as when I compile it. I flashed stock firmware without issue after the failed flash. I guess I’ll try again this weekend

F0x06 commented 5 years ago

@michalxfanta Any plans to implement this ? I really need this feature :)

Adrian-at-CrimsonAzure commented 5 years ago

I would also like this feature, I've noticed that there are some areas in my print bed (on diagonals between points) that my first layer has a lot of separation. If I lower my Z adjust, then I end up hitting the print bed at the calibration points, while still being a bit too high on the low spots.

Maybe make an option in the menu with 3x3, 5x5, 7x7, etc?

F0x06 commented 5 years ago

Thanks @mionut for your awesome work !, I saw that you merged the latest Prusa 3.5.1 into your repo, i tested it, this is the result:

20181228_165024 20181228_165013

And the pre-compiled firmware fro those with compilation issues (Don't forget to edit your start GCODE script in Slic3r to enable the 7x7 probing, G80 N7: Prusa-Firmware-3.5.1-7x7.zip

I just have the 2 bottom one are a bit rough on bottom edges, not a problem. My bed is almost perfect.

stahlfabrik commented 5 years ago

If only Prusa would understand the problem (acknowledge it I mean) and then provide an option to the customers. I would be happy if it would be JUST an gcode enhancement to get 7x7. But an 5x5 option would also be stellar...

F0x06 commented 5 years ago

If only Prusa would understand the problem (acknowledge it I mean) and then provide an option to the customers. I would be happy if it would be JUST an gcode enhancement to get 7x7. But an 5x5 option would also be stellar...

Totally agree ! In addition, Prusa technical support can save a lot of time and money, as many users suffer from bed-leveling issues.

Tinker999 commented 5 years ago

Thanks @mionut for your awesome work !, I saw that you merged the latest Prusa 3.5.1 into your repo, i tested it, this is the result:

20181228_165024 20181228_165013

And the pre-compiled firmware fro those with compilation issues (Don't forget to edit your start GCODE script in Slic3r to enable the 7x7 probing, G80 N7: Prusa-Firmware-3.5.1-7x7.zip

I just have the 2 bottom one are a bit rough on bottom edges, not a problem. My bed is almost perfect.

Thank you for posting the link and instructions. I’m going to give it a try this weekend. I agree an official response would be appreciated.

I have clone texture coating spring steel which I very much like but due to a slight warp the really good print surface is limited to about 7x7(must have if you print PETG). Hoping this will expand that out a bit.

Also just to save time would you consider posting your 5x5 test STL on Thingiverse.

F0x06 commented 5 years ago

@Tinker999 It's an openscad modular calibration pattern, I don't remember the link, il post the file here later.

edspeds commented 5 years ago

@mionut and @F0x06 Thanks a million! This updated successfully and works like a charm...

F0x06 commented 5 years ago

@edspeds You're welcome 👍

edspeds commented 5 years ago

I found this test pattern on thingiverse not as nice as F0x06’s but it’s a good start

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

F0x06 commented 5 years ago

Sorry for the delay, this is the parametric test i used https://www.thingiverse.com/thing:3141591

And the settings

/*[printer]*/
//bed x size[210]
bed_xsize=250;
//bed y size[270]
bed_ysize=210;
//bed margin[15]
bed_margin=15;

/*[layer and line]*/
//first layer thickness[0.24]
first_layer_thick=0.20;
//line size [multiplier of nozzle size]
line_size=0.8;

/*[element shape]*/
//element shape
element_shape=0; //[0:square,1:circle]
//element size[12]
element_size=18;
//element thickness[0.84]
element_thick=first_layer_thick;

/*[array pattern]*/
//number of array x size[3]
array_xsize=5; //[2:1:5]
//number of array y size[3]
array_ysize=5; //[2:1:5]

And the pre-generated STL (same on my pictures, 5x5) BedLevelTest-5x5.zip

codiac2600 commented 5 years ago

Thanks @mionut for your awesome work !, I saw that you merged the latest Prusa 3.5.1 into your repo, i tested it, this is the result:

20181228_165024 20181228_165013

And the pre-compiled firmware fro those with compilation issues (Don't forget to edit your start GCODE script in Slic3r to enable the 7x7 probing, G80 N7: Prusa-Firmware-3.5.1-7x7.zip

I just have the 2 bottom one are a bit rough on bottom edges, not a problem. My bed is almost perfect.

I just tried flashing my firmware on my MK3 with this and I get an error even though it shows it's updated so I tried to save the error log but command + C closed the window. I ran it again and this time it shows successful.

F0x06 commented 5 years ago

@codiac2600 This generally happens if you have another application trying accessing the printer via serial during flash process, for ex pronterface, or repetier, octoprint etc

stahlfabrik commented 5 years ago

Am I on the wrong track here?

It seams that @minout might have taken the mesh bed leveling out:

 lround((z/*+mbl.get_z(x, y)*/)*cs.axis_steps_per_unit[Z_AXIS]) :

In planner.cpp

So I wonder why you all find it to work well:-)

What does this line do? Am I wrong?

I am not a fan of all changes in his repo. I took just the 7x7 changes in my firmware. Awesome work of @minout.

edspeds commented 5 years ago

Not sure but I see a definite improvement and running the PrusaMeshMap in Octoprint shows a more detailed bed map...

@stahlfabrik mind sharing your firmware?

edspeds commented 5 years ago

Prusa MeshMap with a 3x3 and 7x7 level appears to show something is being checked. I'm going to run a test print each way using my 3rd party powder coated sheet that causes me all kinds of first layer grief to see if it's real or placebo...

heatmap 3x3 heatmap 7x7

stahlfabrik commented 5 years ago

The mesh map output is isolated from the planner, who does the work while printing . I will soon share!

edspeds commented 5 years ago

much obliged. I'm testing it on my 3rd party sheet as I type, I'll post pictures of both ways. Tentatively I have to say I see a difference, though I haven't used the sheet in months due to my only being able to get a good first layer on a small portion of the sheet.

stahlfabrik commented 5 years ago

Maybe no bed leveling is better than 3x3 leveling in some cases:-)

But I still wonder about that change in planner.cpp. Please comment if you understand that!

stahlfabrik commented 5 years ago

So my firmware fork is uploaded to GitHub. There is a branch "HD-MBL" were I implemented JUST the 7x7 workaround by @mionut - the rest the the current Prusa firmware 3.5.1:

https://github.com/stahlfabrik/Prusa-Firmware/tree/HD-MBL

From my commit log:

Thanks to @minout for the live-saving 7x7 gcode workaround to get 7x7 MBL

I JUST took the changes in your firmware fork that actually provide the change.

So there is no PINDA temperature filtering/smoothing and no shifting of the temperature levels of 35 to 60C.

I also did NOT overtake your changes in planner.cpp, which seem to me like you deactivated the influence of the MBL during printing?! Please care to comment:

lround((z/+mbl.get_z(x, y)/)*cs.axis_steps_per_unit[Z_AXIS]

EDIT: Here is my hex file for your convenience. Use at your own risk: firmware.hex.zip

EDIT2: To sum up my understanding of the issue:

There are multiple parts in Prusa firmware that are hard coded to the 3x3 mesh bed leveling: First is the XYZ calibration. Which stores MBL jitter in the EEPROM Second is Power Panic which stores the 3x3 points in EEPROM. These functions also work on the internal 7x7 interpolated points - so it is also not easy to change those 7x7 points. Third is of course the MBL itself and the "upsample_3x3" function that it calls. Also @minout was really genius in how he calculates the PINDA probing points. Stock firmware has them hardcoded which blows my mind. One thing to point out is that stock firmware compares the MBL values taken during XYZ calibration to Gard against the nozzle crashing in the bed (if I understand that jitter business correctly). So the 7x7 workaround does NOT provide that extra security. So maybe be ready to press "reset" IF your nozzle digs into your heatbed.

So Prusa Research it is your part now to implement that in a nice way: 3x3, 5x5 and 7x7 MBL would be what I would imagine was configurable from the menu. And make the densest mesh bed leveling during XYZ calibration to get the reference points in memory so that the jitter check works. And power panic...

@edspeds

EDIT3: I also did the nyloc nut bed leveling today. My bed is really flat now.

This is with 3x3 MBL:

ohne titel

codiac2600 commented 5 years ago

So my firmware fork is uploaded to GitHub. There is a branch "HD-MBL" were I implemented JUST the 7x7 workaround by @mionut - the rest the the current Prusa firmware 3.5.1:

https://github.com/stahlfabrik/Prusa-Firmware/tree/HD-MBL

From my commit log:

Thanks to @minout for the live-saving 7x7 gcode workaround to get 7x7 MBL

I JUST took the changes in your firmware fork that actually provide the change.

So there is no PINDA temperature filtering/smoothing and no shifting of the temperature levels of 35 to 60C.

I also did NOT overtake your changes in planner.cpp, which seem to me like you deactivated the influence of the MBL during printing?! Please care to comment:

lround((z/_+mbl.getz(x, y)/)*cs.axis_steps_per_unit[Z_AXIS]

EDIT: Here is my hex file for your convenience. Use at your own risk: firmware.hex.zip

EDIT2: To sum up my understanding of the issue:

There are multiple parts in Prusa firmware that are hard coded to the 3x3 mesh bed leveling: First is the XYZ calibration. Which stores MBL jitter in the EEPROM Second is Power Panic which stores the 3x3 points in EEPROM. These functions also work on the internal 7x7 interpolated points - so it is also not easy to change those 7x7 points. Third is of course the MBL itself and the "upsample_3x3" function that it calls. Also @minout was really genius in how he calculates the PINDA probing points. Stock firmware has them hardcoded which blows my mind. One thing to point out is that stock firmware compares the MBL values taken during XYZ calibration to Gard against the nozzle crashing in the bed (if I understand that jitter business correctly). So the 7x7 workaround does NOT provide that extra security. So maybe be ready to press "reset" IF your nozzle digs into your heatbed.

So Prusa Research it is your part now to implement that in a nice way: 3x3, 5x5 and 7x7 MBL would be what I would imagine was configurable from the menu. And make the densest mesh bed leveling during XYZ calibration to get the reference points in memory so that the jitter check works. And power panic...

@edspeds

EDIT3: I also did the nyloc nut bed leveling today. My bed is really flat now.

This is with 3x3 MBL:

ohne titel

After posting the initial fork and testing Josef Prusa commented that the 7x7 may be skewed base don the placement of the magnets in the bed which would throw off the Pinda.

My initial tests of the 7x7 vs 3x3 are promising. I have the clone textured bed which is very uneven and this seemed to help out quite a lot but still wasn't as good as I'd like it.

Would there be a benefit to increasing the amount mesh bed leveling corrects? I believe it's locked in at 0.05mm. Perhaps allowing correction up to 0.1mm would be better?

stahlfabrik commented 5 years ago

It is indeed very promising! First layer has not been so consistent before:-)

I hope you can convince Jo to check this out and implement a good solution covering all aspects of the features. As mentioned above! Thanks!

Edit: Klipper users tend to use 5x5 upsampled to 12x12 or so. Anyway: it seams not to be a problem with the magnets

@codiac2600

edspeds commented 5 years ago

Below are my results, the 7x7 definitely makes a difference, judge for yourself from the pictures below... I'll try your firmware next. I'm with @codiac2600 I like the clone sheet but the surface is uneven as sh...

7x7 img_0133 img_0134 img_0135

3x3

img_0136 img_0137 img_0138 img_0139 img_0140

stahlfabrik commented 5 years ago

Looking forward to your test of my build:-) if my understanding is right you will then have the effect of MBL. I wonder still about the change he made in planner?!🤷‍♂️

F0x06 commented 5 years ago

Am I on the wrong track here?

It seams that @minout might have taken the mesh bed leveling out:

 lround((z/*+mbl.get_z(x, y)*/)*cs.axis_steps_per_unit[Z_AXIS]) :

In planner.cpp

So I wonder why you all find it to work well:-)

What does this line do? Am I wrong?

I am not a fan of all changes in his repo. I took just the 7x7 changes in my firmware. Awesome work of @minout.

Apparently you're right, if i understand this piece of code, MBL is disabled because it not retrieve value from mbl.get_z(x, y)... But lol maybe it improves the print quality, I've heard about people disabled their mesh leveling and got better results.

Any inputs on this @mionut ?

stahlfabrik commented 5 years ago

Thanks for your confirmation. So my firmware should have a visible effect:-)

codiac2600 commented 5 years ago

Thanks for your confirmation. So my firmware should have a visible effect:-)

I'll load your firmware in next. I'm finishing a print first.

codiac2600 commented 5 years ago

It is indeed very promising! First layer has not been so consistent before:-)

I hope you can convince Jo to check this out and implement a good solution covering all aspects of the features. As mentioned above! Thanks!

Edit: Klipper users tend to use 5x5 upsampled to 12x12 or so. Anyway: it seams not to be a problem with the magnets

@codiac2600

I'll post it in the Prusa Dev chat and see if I can get anyone at prusa to test a final version of this firmware build.

stahlfabrik commented 5 years ago

Awesome!

This firmware is just a robust workaround. Prusa developers will surely come up with an implementation covering all cases of functionality and hopefully even menu support to make the density configurable.

edspeds commented 5 years ago

@stahlfabrik, Just tested your firmware and it performs the similar to @mionut's, but I give a slight edge to yours... See pictures below, sorry to flood this thread with so many photos by the way, but in this case I feel a visual is in order. img_0143 img_0144 img_0145