prusa3d / Prusa-Firmware-Buddy

Firmware for the Original Prusa MINI, Original Prusa MK4 and the Original Prusa XL 3D printers by Prusa Research.
Other
1.13k stars 218 forks source link

[BUG] MK3.5 Bed Leveling Error #3772

Closed SnowB0und14 closed 5 months ago

SnowB0und14 commented 6 months ago

Printer type - [Mk3.5 (from MK3S+)]

Printer firmware version - [5.2.0]

Original or Custom firmware - [Original]

Optional upgrades - [Mk3s+ to Mk3.5]

USB drive or USB/Octoprint [USB drive]

Describe the bug Bed leveling with magnetic probe appears to be skewed to the far right, presumably since the Super PINDA sensor is on the right side of the nozzle. This is causing uneven first layer height on the far left side of the bed. I can confirm my printer had a perfect first layer calibration before the upgrade (MK3S+ 8 bit board). I believe that this is occurring because the MK4 uses the nozzle to calibrate the first layer, which is offset to the left of the magnetic probe. I'm finding that no matter what I do to get a clean first layer the entire left side (1/10 of the bed) is slightly lower than the rest of the bed. It's the area that the probe isn't checking.

Another reason I suspect that it is partially using the MK4 bed level routine is it will cool the nozzle / hot end down to 170 for the bed calibration. This is something it didn't do with the old 8 bit board. I suspect that it wants the hot end at 170 since the MK4 uses the nozzle pressure to calibrate the bed, but this seems unnecessary since the MK3.5 is using a magnetic probe.

How to reproduce First layer calibration for new steel sheet (I'm using Prusa branded sheets not aftermarket). I've double checked that all the screws are tightened and the new expansion joints are installed properly.

Expected behavior I expect that the print head would move all the way to the left when doing a bed level and suspect that it is using the MK4 routine.

G-code First layer calibration built into the board.

Crash dump file N/A

Photo I've attached a photo of the first layer, you can see on the left that the nozzle is slightly too high, the rest of the sheet its slightly low.

IMG_6529

magistersmax commented 6 months ago

I think I'm experiencing the same issue. OP, can you count the number of points that the printer checks when bed leveling? Mine is only checking 42 points (a 6x7 grid - 6 across the X direction and 7 across the Y direction.) rather than 49 (7x7).

In my case, I'm getting a 6x7 mesh bed leveling with edges that seem to drop off badly enough that the Z offset pattern doesn't work as intended. The final square is noticeably lower than the zig zags leading up to that point, which makes it difficult to properly set the Z offset.

I think the behavior of changing the nozzle temperature to 170C is expected, this prevents oozing during bed leveling. I'd actually built that in to my start GCode on my MK3S+ before the upgrade, it makes a huge improvement.

SnowB0und14 commented 6 months ago

@magistersmax I'm printing right now, but I will count the number of points when it's done. I'm experiencing the exact same issue with the Z offset pattern, and the final square is stringy and not adhered to the bed well, but the rest of the pattern is perfect.

Thanks for the heads up on 170C and oozing during leveling. I didn't notice that it was improved with the lower temps but now that you mention it, it is way better.

magistersmax commented 6 months ago

I think your reasoning on the nozzle position vs. the PINDA/SPINDA sensor is spot on (granted, I'm not a firmware programmer and have never dug around the source code). If that's the actual problem and you're getting a 6x7 grid too, then I think both problems could be directly related. Basically, the measured Z offsets would be shifted from the actual bed by a significant amount and one column of measurements falls completely outside the bed area so it's skipped.

SnowB0und14 commented 6 months ago

I just ran a first layer calibration and it is indeed 6 wide and 7 tall. So it's skipping the entire left side of the bed. I'm glad you noticed that.

It also seems to only probe the area it's going to print, and it also seems to be skipping the left side of the bed there as well. This is harder to measure, I might put masking tape down on the bed and mark it with a pen as it's going and see where it probes compared to where it prints. I'll print something wide that isn't the calibration Z and see how it the underside looks on the left side.

Kooshballer commented 6 months ago

I am expereincing the same issue Screenshot 2024-02-20 084848

My bed, top left corner is significantly farther away from the bed.

I have an e3d revo hotend on my pritner but I am 100% that is not a factor in this issue. I checked all the heat expansion joints on my bed and they are all the same height and also in the ccorrect orintation. I also reflashed new firmware and facotry reset the machine.

None of the troubleshooting steps worked. I spent about 10 hours on the support chats with prusa and they did not help.

https://github.com/prusa3d/Prusa-Firmware-Buddy/assets/160615903/0faab89f-05c8-49f4-b388-5a88c86cfabf

BlueFyre commented 6 months ago

I am seeing the same issue. See the following photos:

PXL_20240222_012140082 PXL_20240222_012149347 PXL_20240222_012200574 PXL_20240222_012221672 PXL_20240222_012206510

SnowB0und14 commented 6 months ago

I found the sensor offset in the Marlin config file for the MK3.5. Looks like the offset for the probe is set.
#define NOZZLE_TO_PROBE_OFFSET \ { 23, 5, -0.4 } I'm not super familiar with how the config file works (there is a lot related to bed leveling), maybe someone else could take a look.

kritoke commented 6 months ago

I have also found that the first layer calibration does show the left side points much thinner than the right side. Doesn't seem to matter which left point, though the top left is worse than the others. It is newly upgraded to 3.5, never had an issue with this prior.

SnowB0und14 commented 6 months ago

Some more pictures with measurements if this helps anyone figure this out. This first picture is (0,0).

73079118216__8557B088-24C1-4545-834C-10CE85DAE948

This picture is (23,5) the stated probe offset. The X under the probe is the farthest left and forward probe point it will do during a mesh (only 6 wide 7 tall).

73079123540__D16203A8-3BE6-495D-90AA-8BAAAA15BB42

Pottebaum commented 6 months ago

I am seeing the exact same behavior with the recent upgrade from the MK3+ to the MK3.5. Prior to the upgrade no issues with bed level or first layer.

After the upgrade the entire left 4.5cm of the print is quite a bit off from the rest of the bed. In addition, if I do a full bed print the bed calibration only does a 6x7 grid, despite the LCD saying it is doing 49 total points. It appears the far left side of the bed calibration is simply skipped.

Full image image

Left Side image

Right Side image

cozmo14047 commented 6 months ago

@gudnimg @3d-gussner please come and fix this.

gudnimg commented 6 months ago

@cozmo14047 sorry to say I can’t help with this issue 🙁. My MK3S+ is still stock and I am likely keeping it that way.

If this were the 8-bit firmware I’d suggest to run Z axis calibration in case the two motors are not aligned. But this isnt the 8-bit firmware.

TehH4rRy commented 6 months ago

I'm facing the same issue on my 3.5 upgrade. Middle of the bed it's a perfect first layer, these expansion joints do a fantasic job, better than the nylock mod I had on there before I'd say. But yes, the left side of the bed is unusable, please fix!

cozmo14047 commented 6 months ago

@cozmo14047 sorry to say I can’t help with this issue 🙁. My MK3S+ is still stock and I am likely keeping it that way.

If this were the 8-bit firmware I’d suggest to run Z axis calibration in case the two motors are not aligned. But this isnt the 8-bit firmware.

ok thanks, i thought you would have been given a mk3.5, as for the calabration so many people are having the problem (pretty much everyone) that it has to be software

johnboiles commented 6 months ago

Seeing the same thing on my 3.5. I posted on the forum. Seems like ~50mm from the left edge of the bed my leveling gets wonky.

Prusa-Support commented 6 months ago

Thanks for reporting. This issue is already being investigated internally.

Could you please specify your Mesh Bed Levelling settings and whether you have a PINDA v2 (4 wires, with thermistor) or a Super PINDA (3 wires, temperature independent)?

Michele Moramarco Prusa Research

BlueFyre commented 6 months ago

SuperPINDA and stock settings for me. I don't believe there are any values we can change

magistersmax commented 6 months ago

SPINDA here, firmware 5.2.0 is locked to 7x7 mesh bed leveling for the MK3.5 at the moment, so I doubt there will be any variation there.

SnowB0und14 commented 6 months ago

@Prusa-Support I have the SPINDA as well. It’s skipping the left side when I do a z height calibration for a new steel sheet.

My friend was helping me look at this and we looked up MESH_MIN_Y and MESH_MAX_Y for the Prusa MINI which uses the inductive probe as well. It looks like the MK 3.5 doesn’t have any values set for those parameters whereas the MINI has some values on the config.

BlueFyre commented 6 months ago

Adding some additional information in case it helps. The mesh appears to be a 6x7 grid using 3 probe points

After running G29 P1 we can see the 6x7 mesh with missing values for presumably column 1 G29 P1.txt

After running G29 P3.2 and G29 P3.13 we can see the values are considerably higher than nearby values after interpolate and extrapolate.txt

Plotting this we can see a really flat and strange looking part on the left side plot

SnowB0und14 commented 6 months ago

I just flashed the 5.2.1 firmware, the problem still persists.

BlueFyre commented 6 months ago

@ChipWallace I don't think your conclusion in the video is quite right. It's missing going over to the left for that last column. See the mesh I posted previously

Speaking of which, I wonder if we could have even more points on the grid instead of just 7x7 (not entirely relevant to this issue but maybe a future request would be good; same with number of probes though being allowed to go from the current 3 to old max of 5 would be better already)

Anyhow, just need to wait for devs to fix it as it seems they're now aware of the issue

amoiseiev commented 6 months ago

Same issue here, SPINDA, stock settings.

ByPS128 commented 6 months ago

My printer has the same problem after upgrade to MK3.5. The left side is not leveld well. The dot matrix is not 7x7 but 7x6. Before the upgrade I had, so to speak, a perfect first layer over the whole surface. Now no matter what I do I am not able to achieve the same quality. Please hurry up and fix it, it's crucial for the printer and for all of us who decided to upgrade.

I've attached pictures below with a ruler, where you can see that the bad is mostly pretty flat. Something else will straighten the plate.

PXL_20240306_000554219

PXL_20240306_000601338

PXL_20240306_000649792

PXL_20240306_074601695

PXL_20240306_000655181

Photos with rule: PXL_20240306_080852329

PXL_20240306_080859990

PXL_20240306_080905745

PXL_20240306_080910246

PXL_20240306_080915881

PXL_20240306_080924342

PXL_20240306_080929235

PXL_20240306_080944083

Matrixrs commented 6 months ago

@Prusa-Support Seeing the same problem I was Searching for Pinda warmup g-code in the new xBuddy and it seems to have no information about the temp . M860 is just ignore...

I have MK3S+ (original Pinda v2) Upgraded to the MK3.5 with My old Pinda v2 I have cunted 6 row of meshbed on the X axis and 7 on the Y (I dont see where thers option to change it).

Might replace the Pinda in the future since it seams not longer possible to mesh bed at Pinda temp 35 deg C

is the xBuddy able to read the pinda temps ?

Doubledutched commented 6 months ago

I have the same problem as everybody else (not being able to level the bed). On top of that, after manually setting Z, whenever I change the nozzle and adjust the corresponding setting, the printer will push the nozzle into the print plate during the bed leveling before printing. It ignores the PINDA probe and Z settings. It ruined 2 print plates already. Original MK3S+ upgraded to MK3.5.

cozmo14047 commented 6 months ago

@Prusa-Support When will this be fixed, please release a version to fix this quick

TimW55 commented 6 months ago

Like you all I am experiencing a problem on the LHS of my prints following the MK3.5 upgrade. I think we have at least 2 issues:

1. Looking at the Mesh Bed Levelling calibration: Y stops: 199.5, 168.0, 136.5, 105.0, 73.5, 42.0, 10.5 => Increment: 31.5mm Range: 189mm X stops: 237.5, 200.0, 162.5, 125.0, 87.5, 50 => Increment: 37.5mm Range: 173.5 The reason that we are missing a calibration point on the LHS is that the next point would position: Probe @ 50.0 - 37.5 = 12.5mm. Hotend @ 12.5 - ProbeOffset = 12.5 - 23.0 = -11.5mm This point cannot be physically reached. If instead of an X stop spacing of 37.5 it was reduced to 35.5 we could have 7 stops instead of 6 Adjusted X stops: 237.5, 202.0, 166.5, 131.0, 95.5, 60.0, 24.5 A final stop @ 24.5mm would put the hot end @ 1.5mm, which is a reachable point, and the probe 25.5mm closer to the LHS.

2. In addition to the issue of 6 instead of 7 sampling points I think that:

image

image

TimW55 commented 6 months ago

I have now conducted one further test. I sliced the single layer test model and in the Start G-code commented out the line G29 P3.13 ; extrapolate mbl outside probe area so that no extrapolation would take place. The end result is so much better.

20240310_231131

20240310_231138

20240310_231142

In conclusion there is at least one problem with the MBL routines but fortunately there seems to be an adequate work around whilst Prusa work on a proper solution.

SnowB0und14 commented 6 months ago

@TimW55 I really think it has to do with the MESH_MIN_Y and MESH_MAX_Y. The Prusa MINI which uses the inductive probe as well has values entered in the firmware and the MK 3.5 doesn’t. I’m don’t know how to compile my own firmware to test it though.

Thanks for finding the gcode work around.

TimW55 commented 6 months ago

@SnowB0und14, yes I agree that there seems to be an issue with MESH_MIN_X. This parameter refers to the position of the probe which if set too low can result in the problem of the hot end being outside its reachable area.

I expect you have read this helpful article https://marlinfw.org/docs/features/unified_bed_leveling.html.

Prusa also seem to have extended the default Marlin behaviour with the introduction of the undocumented commands G29 P3.2 and G29 P3.13. Several other Marlin commands are not accessible.

nathanielstepp commented 6 months ago

Context: MK3S+ -> MK3.5 Upgrade | Firmware Build: 5.2.1 + LOCAL (e.g., Custom Build) | Toolhead uses SuperPINDA Z-Probe | Currently Operating Prints via USB Drive

Like many here, I also purchased the Prusa MK3.5 upgrade kit and spent the majority of evenings last week installing the upgrade and performing some much-needed maintenance and reconfiguration on my customized machine (was previously a customized MK3S+, purchased back in approximately December of 2019).

Included in the myriad of community and third-party customizations I’ve installed was a Bondtech LGX Shortcut extruder, featuring a Slice Engineering Mosquito hotend, a PT1000 RTD temperature sensor (purchased from Slice Engineering), a 24VDC 50W industrial heater cartridge (purchased from Slice Engineering), as well as higher static-pressure / flow hotend and part cooling fans. All this to say… while I was hoping some MK3.5 firmware (FW) variants would be released to support third-party toolheads (with varying extruder and hotend configurations), I understand this type of development takes time and I let my impatience get the better of me 😅; I fully expected to have to break the PCB Appendix on my upgrade’s xBuddy Board and dig into loading some custom FW to support the upgrades I had previously installed.

Like all those posted and viewing this ticket, I too experienced the issue of the desired 7x7 mesh-bed-leveling (MBL) routine not probing all the desired 49 points, instead only completing a 42-point 6x7 grid (6 probed “columns” along the x-axis, and 7 probed “rows” along the y-axis). Moreover, I experienced poor first-layer performance/adhesion on a ~52mm swath of the left side of the print area. I assumed this was due to poor extrapolation of the mesh via the actual probed location, adjacent to the un-probed area by whatever the math the mesh bed algorithm in the FW utilized.

Well… This past weekend, I broke the appendix and dug in, and think I have a candidate solution. This may be a moot point at this point since I fully expect the Prusa FW dev team already has an internal solution in the pipeline undergoing quality control. However, digging into the FW and implementing the fix I did, I’m still a bit confused concerning the fix implementation. The parameters I adjusted (in particular, their values) to implement the fix don’t exactly make physical sense with regards to what I assume the parameters physically describe with regards to the printer dynamical system.

Most changes I implemented in the FW were minor and only concerned the _ConfigurationMK3.5.h and _Configuration_MK3.5adv.h header files, located in include/marlin of the FW stack. Regarding the MBL configuration and routine, it looks like the firmware still has firm roots in Marlin, implementing Marlin’s Unified Bed Leveling (UBL) system (as @TimW55 previously pointed out).

Prusa’s UBL implementation utilizes an overall software mesh comprised of 21x21 evenly-spaced points, with 7 evenly-spaced major points along each axis (which are physically sampled by the toolhead probe), and 3 intermediate points (“steps”) between sets of major points along each axis, presumable for high-resolution nonlinear curve-fitting between physically probed samples for better leveling performance for areas of the bed not physically sampled.

Pertinent to Prusa’s configuration of Marlin’s UBL system, from _ConfigurationMK3.5.h:

image

And:

image

And, as previously pointed-out by @SnowB0und14, from _Configuration_MK3.5adv.h:

image

Which, again, as @SnowB0und14, pointed out, bares a difference in value relative to the same section of code from the associated Prusa MINI configuration file, _Configuration_MINIadv.h:

image

Through a process of considering the values stored in _NOZZLE_TO_PROBEOFFSET, additional machine physical dimension/limit settings (in particular, _X_BEDSIZE, _Y_BEDSIZE, _X_MINPOS, _Y_MINPOS, _X_HOMEGAP, _Y_HOMEGAP, _X_ENDGAP, and _Y_ENDGAP), considerations of toolhead parking location with regards to _Z_SAFEHOMING configurations (all defined in _ConfigurationMK3.5.h), and some trial-and-error testing, I believe I have a fix for this bug.

I was able to successfully amend, compile, and flash the firmware such that a full, evenly spaced, 7x7 mesh (sampled out to the extremities of the Sheet print-area, where possible, with a 1mm gap tolerance) is sampled, using Prusa’s implementation of Marlin’s UBL, and a satisfactory first-layer performance is achieved without significant issue using the following settings for _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY, in _Configuration_MK3.5adv.h:

image

Pictures of first-layer performance results via Prusa’s bed leveling test print on Printables (forgive/ignore the slight over extrusion… I still need to calibrate the steps-per-mm/flow/extrusion-length relationship):

Bed, after immediately after bed level test print: MK3 5_UBL_BUG_FIX_TEST_1

Bed, quadrant, bottom-left: MK3 5_UBL_BUG_FIX_TEST_2

Bed, quadrant, bottom-right: MK3 5_UBL_BUG_FIX_TEST_3

Bed, quadrant, top-left: MK3 5_UBL_BUG_FIX_TEST_4

Bed, quadrant, top-right: MK3 5_UBL_BUG_FIX_TEST_5

Bed, test-square, top-left: MK3 5_UBL_BUG_FIX_TEST_6

Bed, test-square, top-center: MK3 5_UBL_BUG_FIX_TEST_7

Bed, test-square, top-right: MK3 5_UBL_BUG_FIX_TEST_8

Bed, test-square, center-right: MK3 5_UBL_BUG_FIX_TEST_9

Bed, test-square, center: MK3 5_UBL_BUG_FIX_TEST_11

Bed, test-square, center-left: MK3 5_UBL_BUG_FIX_TEST_12

Bed, test-square, bottom-left: MK3 5_UBL_BUG_FIX_TEST_13

Bed, test-square, bottom-center: MK3 5_UBL_BUG_FIX_TEST_14

Bed, test-square, bottom-right: MK3 5_UBL_BUG_FIX_TEST_15

Test print, removed, flipped, and bottom layer assessment with reference labels: MK3 5_UBL_BUG_FIX_TEST_17

MK3 5_UBL_BUG_FIX_TEST_18

MK3 5_UBL_BUG_FIX_TEST_19

MK3 5_UBL_BUG_FIX_TEST_20

MK3 5_UBL_BUG_FIX_TEST_21

MK3 5_UBL_BUG_FIX_TEST_22

MK3 5_UBL_BUG_FIX_TEST_23

MK3 5_UBL_BUG_FIX_TEST_24

MK3 5_UBL_BUG_FIX_TEST_25

MK3 5_UBL_BUG_FIX_TEST_26

My only standing concern, even those these configuration values fix this bug (at least, in my case), is I’m struggling to make physical sense of the values. According to the comments in the code snippet as well as Marlin’s UBL documentation, _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY, are utilized to set the bounds of the meshable area in the case where a custom mesh area inset is desired with respect to the printable area and default meshable area, or there are linear swaths of the bed that need to be avoided due to mechanical/geometric interferences. The values that proved successful here don't appear to immediately make physical sense with that context in mind.

My guess, given my success with these values, and considering also the somewhat nonsensical associated values defined for the Prusa MINI, this is a (and I genuinely mean no offense to the Prusa FW dev team by this… Nothing but admiration and respect to the team!) an implementation “band-aid” solution, at least with regards to the MINI.

Given my understanding of Marlin’s UBL system, the values in the current release of the MK3.5 firmware (all 0’s) should work and make physical sense. I suspect these values I found success with make no sense due to previously stated offset and machine dimension/limit values either not properly being passed to or being considered in the Marlin UBL implementation, deeper in the firmware stack such that this bug presents itself.

Regardless, I am now back in production with my custom MK3.5 an currently have a full bed of parts happily printing! I hope all this information proves useful, if not to the Prusa FW dev team (assuming you already have a solution in the pipeline), to users looking for potential answers/solutions to this issue. 😁

And by no means am I recommending this as the definitive solution and casual or novice users break the xBuddy Board PCB Appendix (voiding their warranty with Prusa) and load custom firmware. This is just the solution that worked for me. If you choose to do so, I take no responsibility and do so at your own risk!

If there is any interest in the firmware build I amended, compiled, and flashed, I would be happy to fork / post later this evening.

I also have the G29 T and G29 P5 terminal outputs with the mesh results and statistics that I can post later if those prove helpful to others.

nckltcha commented 6 months ago

@nathanielstepp I would be interested in your modified firmware!

TimW55 commented 6 months ago

@nathanielstepp, I hope your well worked fix helps Prusa to release an official update in the very near future.
Does your fix also mean that the First Layer Calibration works correctly?

SnowB0und14 commented 6 months ago

@nathanielstepp Nice work actually putting this all together. My friend who knows the firmware way better than me helped me find the missing settings in there. I think you're right, the offsets don't make sense. I was thinking they needed to be:

#define MESH_MIN_X -23 #define MESH_MIN_Y -5

That was from measuring the closest (front, left) probe point from the 6x7 to where the closest 7x7 point should have been. Just out of curiosity how did you come up with +11 and -10? I'm still a little fuzzy on how this part of the Marlin works. I thought it was a way to give it the full available probe area, which since the nozzle is offset needs to be wider than the actual print area. @nathanielstepp Did you have to use different offsets with your mods?

Anyways thanks for actually figuring it out. I learned something!

toficly commented 6 months ago

I'm also facing these issues. Just finished my upgrade yesterday ( MK3s+ with SuperPINDA to MK3.5 ) and was wondering why I was not able to do a proper 1st Layer Calibration. I also noticed that the orientation of the 1st Layer Calibration Test Pattern is now upside down ( compared to before - square is now on top instead of bottom ). Until now I have always set the Z Offset so that the full square looks corresponding to the photos in the manual. Since yesterdays upgrade I was not able to achieve the correct Offset: Before I had a Offset around -1.5 ( depending on the Sheet ). But now I even went up to -1.95 but the square was still "too high". But the other parts of the test pattern where actually too low ( so low that I couldn't remove parts of it from the sheet anymore ). So for me it looks like the mesh bed leveling is actually not working. To be honest I'm actually a bit angry about this: I had a perfectly working printer with no issues regarding first layer or whatsoever. But after investing about 3 days of my free time and looking forward to enjoy the promised improvements that were stated in the blog post I now have a unusable printer that I can't use anymore. A rollback to the old 8bit Board is not an option. For me it looks like the prusa team have done the Firmware for the MK3.5 in a rush without proper testing. So please fix this ASAP so that we can use our printers again. Thanks.

TimW55 commented 6 months ago

@toficly, unfortunately I agree with you.
Whilst the whole upgrade kit and instructions are up to the usual very high Prusa standards the firmware has a half-baked feel to it. Prusa have not done themselves, or their reputation, any favours by releasing the firmware in this state with such fundamental bugs.

TimW55 commented 6 months ago

@Prusa-Support, could you please give us a progress report on the provision of a fix for this issue. Given the emphasis which Prusa have always placed on getting the first layer right I find it very surprising that this problem has occurred.
Thank you.

Kooshballer commented 6 months ago

@Prusa-Support I think prusa should give us a partial refund or store credit since the upgrade kit was half baked. The software I have been waiting for a month to come out should have been finalized before the kits even shipped. They really dropped the ball with this.

nathanielstepp commented 6 months ago

@nckltcha, @TimW55, @SnowB0und14, I got a chance to work this some more last night and have (maybe?) some new insights:

First, @nckltcha, I've forked the Prusa's Prusa-Buddy-Firmware repository and navigated the repo to the Tag associated with the v5.2.1 release (commit SHA: fb97a2d02bb0df53bc601695b66250f69cec7263) which is not associated with any current branch in the repository (which seems a little odd based on my Git experience but probably a product of an internal development pipeline that's not public?).

Regardless, I've branched this commit on the fork and working to make the bare minimum edits to the associated configuration files (_ConfigurationMK3.5.h and _Configuration_MK3.5adv) and will release the compiled binaries and frozen source code. I'm starting from a fresh pull of the associated source code so the only edits that persist are the edits to fix Prusa's implementation of Marlin's UBL system... I didn't want to post my current working repo for my machine since that has several additional edits to cover all the divergent features of my custom toolhead relative to the migrated stock MK3/S/+ toolhead... I will post that one as a release also based on another separate branch, but one build at a time, and this first one seems more pertinent 😅.

@TimW55, I think this should fix the first layer calibration? I was able to successfully finish (i.e., get the "green checkmark") with a build of the original firmware, catered to my toolhead, but without the addition of the UBL bug fixes. So the test "passed" in a software sense but failed by my standards when visually reviewing the the first layer results. After implementing my UBL bug fix, the calibration passed on both criteria for me 😁.

@SnowB0und14, good question! Honestly, I was originally, like you inferred, manipulating the values based on the specified in _NOZZLE_TO_PROBEOFFSET, _X_MAXPOS, _X_MINPOS, _Y_MAXPOS, and _Y_MINPOS in _ConfigurationMK3.5.h, then, through a process of trial-and-error adding or subtracting values in 1mm increments until I was seeing the performed UBL routine either move the probe to the extremities of the bed (e.g. +X/+Y) or reach the axes physical limits (e.g. -X/-Y). But your question led me down a rabbit hole that provided some additional insight... So... Buckle up:

First, to explicitly address your question regarding my offsets (assuming you were referring to my values stored in _NOZZLE_TO_PROBEOFFSET in _ConfigurationMK3.5.h), I was previously using the default offsets of { 23, 5, 0 }, but have now realized that's incorrect after reviewing the Bondtech's most recent stack of their implementation of Prusa's MK3/S/+ firmware (v3.13.3). For context, that's the firmware source code I typically build from since that's the baseline supported firmware for the toolhead I utilize. In their firmware build equivalent parameters for a NOZZLE_TO_PROBE_OFFSET of { 23, 12, 0 } is utilized. I have since updated my offsets in my Prusa-Buddy-Firmware build to match this and have verified with physical measurements of the offset on the toolhead.

Overall, thanks for this question and for leading to this catch, @SnowB0und14!

Now... Time for some "meat-and-potatoes"...

To start, let's look at the terminal output (G29 T) of an initial G29 P1 of Prusa's implementation of Marlin's UBL system using the default UBL configuration parameters. For context, with the new _NOZZEL_TO_PROBEOFFSET of { 23, 12, 0 }, but all other UBL-related parameters at the default Prusa values, per the official v5.2.1 build.

Bed Topography Report:
    (  0,210)                                                                                                                                                      (250,210)
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
20 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
19 |   .       .       .       .     +0.155    .       .     +0.220    .       .     +0.217    .       .     +0.247    .       .     +0.172    .       .     +0.160    .
   |
18 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
17 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
16 |   .       .       .       .     +0.117    .       .     +0.165    .       .     +0.130    .       .     +0.175    .       .     +0.175    .       .     +0.082    .
   |
15 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
14 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
13 |   .       .       .       .     +0.055    .       .     +0.087    .       .     +0.090    .       .     +0.095    .       .     +0.100    .       .     +0.012    .
   |
12 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
11 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
10 |   .       .       .       .     +0.047    .       .     +0.067    .       .     +0.077    .       .     +0.060    .       .     +0.065    .       .     +0.020    .
   |
 9 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 8 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 7 |   .       .       .       .     +0.055    .       .     +0.080    .       .     +0.037    .       .     +0.072    .       .     +0.037    .       .     -0.078    .
   |
 6 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 5 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 4 |   .       .       .       .     +0.045    .       .     +0.067    .       .     +0.052    .       .     +0.037    .       .     -0.020    .       .     -0.163    .
   |
 3 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 2 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 1 |   .       .       .       .    [+0.022]   .       .     +0.052    .       .     -0.000    .       .     -0.003    .       .     -0.090    .       .     -0.170    .
   |
 0 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
    (  0,  0)                                                                                                                                                      (250,  0)

And, this will be important in a moment, the final X- and Y-Position (as reported by the MK3.5 screen under the "Move Axis" menu is:

X =  27mm
Y =  -2mm

This immediately made me realize an assumption I was operating on was incorrect. I had previously assumed the UBL routine was generating a mesh and attempting to probe out to the farthest reaches of the four corners of the build plate. With the default Prusa values, this isn't true and further proved by the parameter #define GRID_BORDER 1 // border we are never gonna probe, only border of size 1 is currently supported in the _ConfigurationMK3.5.h header file which always set an unprobed border of one grid point in the generated 21x21 software mesh. Moreover, with the default configuration parameters for the UBL routine, each corner will always be inset by at least one increment of the UBL-calculated evenly-spaced mesh grid increment in the respective x- and y-axes.

And from the G29 T results, we see the bug: the left-most column remains unproged with the default Prusa values... But why? To answer, we can run some calculations based on some UBL algorithm math:

If I'm understanding the underlying UBL algorithm correctly, mesh grid increments in the respective x- and y-axes are calculated as follows:

X Grid Spacing = (X_BED_MAX) / (GRID_MAX_POINTS_X - 1) = (250mm) / (21 - 1) = 12.5mm

and

Y Grid Spacing = (Y_BED_MAX) / (GRID_MAX_POINTS_Y - 1) = (210mm) / (21 - 1) = 10.5mm

Now, assuming again I'm understanding the UBL implementation correctly, because the default Prusa values of _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY are set in Configuration_MK3.5_adv.h as follows,

// @section leveling

#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
// Override the mesh area if the automatic (max) area is too large
#define MESH_MIN_X 0
#define MESH_MIN_Y 0
#define MESH_MAX_X X_BED_SIZE
#define MESH_MAX_Y Y_BED_SIZE
#endif

and the results of the G29 T command show mesh covers the entirety of the print area of the bed (e.g, no considerations for the values stored in the _NOZZEL_TO_PROBEOFFSET with regard to mesh generation (based on the corner coordinate values displayed in the Bed Topology Report above).

I gained confidence this was the case when calculating the theoretical nozzle position based on the firmware parameters and my understanding of the UBL algorithm implementation:


Final X-Position (X = 4th GRID POINT) = (4*GRID_DELTA_X) - NOZZEL_TO_PROBE_OFFSET.X = (4*12.5mm) - 23mm = 27mm

Final Y-Position = (Y = 1st GRID POINT) = (1*GRID_DELTA_Y) - NOZZEL_TO_PROBE_OFFSET.Y = (1*10.5mm) - 12mm = -1.5mm => -2mm

My previous assumption was they were considered in UBL mesh generation and, while they appear to be considered by the UBL algorithm when filling the mesh with physically measured probings, reviewing both the imported Marlin UBL portions of the Prusa-Buddy-Firmware source code and the actual Marlin Source Code, I'm not sure that's the case anymore.

If we consider this insight, the issue becomes apparent as to why the first column of the physically measured probes is missed. Along the x-axis, for the nozzle to physically move to the first probe location in that column (X = X MESH GRID 1; Y = Y MESH GRID 1) the nozzle would have to move to:

Nozzle Position X @ (1, 1) Probe Mesh Grid Location = 12.5mm - NOZZLE_TO_PROBE_OFFSET.x = 12.5mm - 23mm = -10.5mm

Nozzle Position Y @ (1, 1) Probe Mesh Grid Location = 10.5mm - NOZZLE_TO_PROBE_OFFSET.y = 10.5mm - 12mm = -1.5mm

While the nozzle is physically able to go to the Y = -1.25mm location (since Y_MIN_POS = -4 in _ConfigurationMK3.5.h) the nozzle physically cannot navigate to X = -10.4 (since X_MIN_POS = -1 in _ConfigurationMK3.5.h) and, therefore, the UBL algorithm ignores the left-most column of desired physical probe locations, you end up with a 6x7 probed mesh instead of the desired 7x7, and you have 4 UBL software-defined mesh columns on the left side of the bed that is, per Prusa's start MBL GCode routine, subject to bilinear extrapolation... And that can become a bit chaotic numerically with "free-hanging edges."

So... Utilizing the previous bug fix implementation, we can set the values needed for _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY as follows, rounding-up absolute to the nearest millimeter:

// @section leveling

#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
// Override the mesh area if the automatic (max) area is too large
#define MESH_MIN_X (11) // NSTEPP || 2024/03/11
#define MESH_MIN_Y (-2) // NSTEPP || 2024/03/11
#define MESH_MAX_X X_BED_SIZE // NSTEPP || 2024/03/11
#define MESH_MAX_Y Y_BED_SIZE // NSTEPP || 2024/03/11
#endif

And this results in the following Bed Topology Report via a terminal output (G29 T) of another G29 P1 command:

Bed Topography Report:
    ( 11,210)                                                                                                                                                      (250,210)
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
20 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
19 |   .     +0.052    .       .     +0.167    .       .     +0.215    .       .     +0.212    .       .     +0.227    .       .     +0.167    .       .     +0.155    .
   |
18 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
17 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
16 |   .     +0.042    .       .     +0.117    .       .     +0.155    .       .     +0.125    .       .     +0.167    .       .     +0.165    .       .     +0.077    .
   |
15 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
14 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
13 |   .     -0.003    .       .     +0.067    .       .     +0.085    .       .     +0.085    .       .     +0.082    .       .     +0.087    .       .     -0.000    .
   |
12 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
11 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
10 |   .     -0.025    .       .     +0.040    .       .     +0.072    .       .     +0.075    .       .     +0.037    .       .     +0.040    .       .     -0.000    .
   |
 9 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 8 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 7 |   .     +0.007    .       .     +0.067    .       .     +0.070    .       .     +0.020    .       .     +0.055    .       .     +0.015    .       .     -0.083    .
   |
 6 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 5 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 4 |   .     -0.010    .       .     +0.035    .       .     +0.050    .       .     +0.035    .       .     +0.017    .       .     -0.043    .       .     -0.180    .
   |
 3 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 2 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 1 |   .    [-0.045]   .       .     +0.030    .       .     +0.035    .       .     -0.035    .       .     -0.033    .       .     -0.113    .       .     -0.193    .
   |
 0 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
    ( 11,  -2)                                                                                                                                                      (250,  -2)

Seems like a solid solution (as you suggested @SnowB0und14) even though I still think UBL should consider the _NOZZEL_TO_PROBEOFFSET and compensate for these offsets by virtue of the values in _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY seems ideologically incongruent with their Marlin-documented intent.

BUT WAIT! THERE'S MORE 😁:

Still following the assumption that the values in _NOZZEL_TO_PROBEOFFSET should be ideologically somehow passed somehow to the UBL routine code stack deeper in the firmware, I found the following in the _Conditionalpost.h header file in the Marlin firmware stack:

/**
 * Default mesh area is an area with an inset margin on the print area.
 */
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
  #if IS_KINEMATIC
    // Probing points may be verified at compile time within the radius
    // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(PRINTABLE_RADIUS),"bad probe point!")
    // so that may be added to SanityCheck.h in the future.
    #define _MESH_MIN_X (X_MIN_BED + (MESH_INSET))
    #define _MESH_MIN_Y (Y_MIN_BED + (MESH_INSET))
    #define _MESH_MAX_X (X_MAX_BED - (MESH_INSET))
    #define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
  #else
    // Boundaries for Cartesian probing based on set limits
    #define _MESH_MIN_X (_MAX(X_MIN_BED + (MESH_INSET), X_MIN_POS)) // UBL is careful not to probe off the bed. It doesn't
    #define _MESH_MIN_Y (_MAX(Y_MIN_BED + (MESH_INSET), Y_MIN_POS)) // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions.
    #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
    #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
  #endif

  // These may be overridden in Configuration.h if a smaller area is desired
  #ifndef MESH_MIN_X
    #define MESH_MIN_X _MESH_MIN_X
  #endif
  #ifndef MESH_MIN_Y
    #define MESH_MIN_Y _MESH_MIN_Y
  #endif
  #ifndef MESH_MAX_X
    #define MESH_MAX_X _MESH_MAX_X
  #endif
  #ifndef MESH_MAX_Y
    #define MESH_MAX_Y _MESH_MAX_Y
  #endif
#else
  #undef MESH_MIN_X
  #undef MESH_MIN_Y
  #undef MESH_MAX_X
  #undef MESH_MAX_Y
#endif

and from the equivalent _Conditionalpost.h header file in the Prusa-Buddy-Firmware stack (located in lib/Marlin/Marlin/src/inc/:

/**
 * Default mesh area is an area with an inset margin on the print area.
 */
#if HAS_LEVELING
  #if IS_KINEMATIC
    // Probing points may be verified at compile time within the radius
    // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
    // so that may be added to SanityCheck.h in the future.
    #define _MESH_MIN_X (X_MIN_BED + MESH_INSET)
    #define _MESH_MIN_Y (Y_MIN_BED + MESH_INSET)
    #define _MESH_MAX_X (X_MAX_BED - (MESH_INSET))
    #define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
  #else
    // Boundaries for Cartesian probing based on set limits
    #if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS))  // UBL is careful not to probe off the bed.  It does not
      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS))  // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
    #else
      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + nozzle_to_probe_offset.x))
      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + nozzle_to_probe_offset.y))
      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + nozzle_to_probe_offset.x))
      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + nozzle_to_probe_offset.y))
    #endif
  #endif

  // These may be overridden in Configuration.h if a smaller area is desired
  #ifndef MESH_MIN_X
    #define MESH_MIN_X _MESH_MIN_X
  #endif
  #ifndef MESH_MIN_Y
    #define MESH_MIN_Y _MESH_MIN_Y
  #endif
  #ifndef MESH_MAX_X
    #define MESH_MAX_X _MESH_MAX_X
  #endif
  #ifndef MESH_MAX_Y
    #define MESH_MAX_Y _MESH_MAX_Y
  #endif

#endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL

My understanding is the _Conditionalpost.h, also rooted in the Marlin firmware stack, is for additional definitions outside of Configuration.h and _Configurationadv.h, that isn't meant for user input (e.g., calculated definition). Examining Prusa's implementation of the _Conditionalpost.h header file, it looks like there is a conditional statement with logic to account for the values stored in the _NOZZLE_TO_PROBEOFFSET definition. However, the way the conditional logic is currently setup, the offset values would never be considered since the first condition would be met before the second, given the comparison statement.

Additionally, while I think the logic in the "else" portion of the condition statement does account for the values stored in the _NOZZLE_TO_PROBEOFFSET definition, this would ultimately limit the mesh by an unnecessary amount such that additional x- and y-axis distance at the -X/-Y bed extremities wouldn't be utilized in the software-defined mesh (even at the unproped boarder), leaving unaccounted and uncorrected swaths at the left and front extremities of the bed.

Moreover, I decided to re-write that section as follows:

/**
 * Default mesh area is an area with an inset margin on the print area.
 */
#if HAS_LEVELING
  #if IS_KINEMATIC
    // Probing points may be verified at compile time within the radius
    // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
    // so that may be added to SanityCheck.h in the future.
    #define _MESH_MIN_X (X_MIN_BED + MESH_INSET)
    #define _MESH_MIN_Y (Y_MIN_BED + MESH_INSET)
    #define _MESH_MAX_X (X_MAX_BED - (MESH_INSET))
    #define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
  #else
    // Boundaries for Cartesian probing based on set limits
    // #if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
    //   #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS))  // UBL is careful not to probe off the bed.  It does not
    //   #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS))  // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
    //   #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
    //   #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
    // #else
    //   #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + nozzle_to_probe_offset.x))
    //   #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + nozzle_to_probe_offset.y))
    //   #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + nozzle_to_probe_offset.x))
    //   #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + nozzle_to_probe_offset.y))
    // #endif
    #if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) && ENABLED(FIX_MOUNTED_PROBE) // NSTEPP || 2024/03/11
      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + nozzle_to_probe_offset.x - ( (X_MAX_LENGTH) / (GRID_MAX_POINTS_X - GRID_BORDER) ) )) // NSTEPP || 2024/03/11
      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + nozzle_to_probe_offset.y - ( (Y_MAX_LENGTH) / (GRID_MAX_POINTS_Y - GRID_BORDER) ) )) // NSTEPP || 2024/03/11
      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + nozzle_to_probe_offset.x + ( (X_MAX_LENGTH) / (GRID_MAX_POINTS_X - GRID_BORDER) ) )) // NSTEPP || 2024/03/11
      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + nozzle_to_probe_offset.y + ( (Y_MAX_LENGTH) / (GRID_MAX_POINTS_Y - GRID_BORDER) ) )) // NSTEPP || 2024/03/11
    #else
      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS))  // UBL is careful not to probe off the bed.  It does not
      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS))  // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
    #endif
  #endif

  // These may be overridden in Configuration.h if a smaller area is desired
  #ifndef MESH_MIN_X
    #define MESH_MIN_X _MESH_MIN_X
  #endif
  #ifndef MESH_MIN_Y
    #define MESH_MIN_Y _MESH_MIN_Y
  #endif
  #ifndef MESH_MAX_X
    #define MESH_MAX_X _MESH_MAX_X
  #endif
  #ifndef MESH_MAX_Y
    #define MESH_MAX_Y _MESH_MAX_Y
  #endif

#endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL

Something important to note, the second chunk of code here in the overall code snippet checks to see if _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY is already defined in the associated _Configuration_MK3.5.hadv header file and opts for the values defined there rather than those calculated in the previous chunk of the code snippet. Since I want the second part of the code snippet to utilize the values calculated in the first part of the code snippet, I commented out the associated lines in the _Configuration_MK3.5.hadv

And, in short, SUCCESS!!! This bug fix implementation performed a successful UBL routine flawlessly and the resultant first layer looked perfect, in my opinion 😁. Here is the resultant Bed Topology Report via a terminal output (G29 T) of another G29 P1 command:

Bed Topography Report:
    ( 10,210)                                                                                                                                                      (250,210)
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
20 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
19 |   .     +0.060    .       .     +0.182    .       .     +0.227    .       .     +0.227    .       .     +0.247    .       .     +0.185    .       .     +0.170    .
   |
18 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
17 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
16 |   .     +0.052    .       .     +0.135    .       .     +0.167    .       .     +0.140    .       .     +0.180    .       .     +0.180    .       .     +0.095    .
   |
15 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
14 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
13 |   .     +0.012    .       .     +0.080    .       .     +0.102    .       .     +0.097    .       .     +0.110    .       .     +0.105    .       .     +0.022    .
   |
12 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
11 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
10 |   .     -0.008    .       .     +0.057    .       .     +0.087    .       .     +0.090    .       .     +0.050    .       .     +0.055    .       .     +0.017    .
   |
 9 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 8 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 7 |   .     +0.022    .       .     +0.075    .       .     +0.087    .       .     +0.047    .       .     +0.070    .       .     +0.032    .       .     -0.070    .
   |
 6 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 5 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 4 |   .     +0.007    .       .     +0.055    .       .     +0.072    .       .     +0.052    .       .     +0.035    .       .     -0.023    .       .     -0.160    .
   |
 3 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 2 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
   |
 1 |   .    [-0.020]   .       .     +0.052    .       .     +0.067    .       .     +0.005    .       .     -0.001    .       .     -0.085    .       .     -0.163    .
   |
 0 |   .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .       .
        0       1       2       3       4       5       6       7       8       9      10      11      12      13      14      15      16      17      18      19      20
    ( 10,  0)                                                                                                                                                      (250,  0)

Additionally, I prefer this bug fix implementation over the former since it solely incorporates the values defined in NOZZLE_TO_PROBE_OFFSET (such to not quasi-duplicate the definition by virtue of the _MESH_MIN/MAXX/Y values, further generalizes the implementation (having potential applications across different printer models), and makes the overall firmware code stack not reliant on _MESH_MINX, _MESH_MINY, _MESH_MAXX, and _MESH_MAXY values for compensation to fix this bug (which seems ideologically incongruent with their intended purpose).

With regards to any firmware releases I perform on my fork of the Prusa-Buddy-Firmware (v5.1.2), I will be using the second implementation.

Saying this again just to cover myself with regards to flashing custom firmware builds: By no means am I recommending this as the definitive solution and casual or novice users break the xBuddy Board PCB Appendix (voiding their warranty with Prusa) and load custom firmware. This is just the solution that worked for me. If you choose to do so, I take no responsibility and do so at your own risk!

TimW55 commented 6 months ago

@nathanielstepp, you have done a great job. Thank you so much for all your effort. Please let me know when you have a build available as I would be very keen to try it. BTW have you tried running G29 P1 V4? as I would like to compare the reported probe positions wrt the default which are:

Y stops: 199.5, 168.0, 136.5, 105.0, 73.5, 42.0, 10.5 => Increment: 31.5mm Range: 189.0mm
X stops: 237.5, 200.0, 162.5, 125.0, 87.5, 50.0       => Increment: 37.5mm Range: 173.5mm

Thanks again.

nathanielstepp commented 6 months ago

@TimW55, I'm spending some time this morning to wrap up the binaries for the custom firmware releases. Just to confirm, you're running a stock setup and the only issue is with the UBL bug, correct?

TimW55 commented 6 months ago

@nathanielstepp, that is excellent news. Yes, apart from a Revo Six hotend, which has calibration issues, my machine is a standard MK3.5. The only show stopping issue for me is the UBL bug. Thanks again.

nathanielstepp commented 6 months ago

@TimW55, had a similar issue, assuming the calibration you are referring to your hotend heater self-test. Mine was due to the closed-system time-constant and associated firmware-defined hotend heating PID gains, specific for the Mosquito hotend (integrated using Bondtech's LGX Shortcut configuration) using a PT1000 temperature sensor and 50W 24V industrial heater (e.g., not the stock migrated MK3/S/+ style V6 hotend). I was able to get by this by widening the margins on the associated parameters for the associated code in the self-test (namely, increasing the rise time criteria by 10 seconds and decreasing the setpoint temperature by 10 deg C). Want me to integrate that same change in the associated *.bff binaries?

TimW55 commented 6 months ago

@nathanielstepp, yes please!

nathanielstepp commented 6 months ago

@TimW55, will do! Having some issues getting the build to finish on a different computer right now, but nearly there. Not any showstoppers. Just the pains of setting up the build sequence on a different machine.

nathanielstepp commented 6 months ago

@nckltcha, @TimW55, @SnowB0und14, I've released custom firmware builds on my github page implementing my UBL bug fix. Two releases are there, one for the default HW configuration and one (possibly?) applicable to Revo hotends (per this conversation with @TimW55 : https://github.com/prusa3d/Prusa-Firmware-Buddy/issues/3772#issuecomment-1994874687 ... @TimW55, you'll have to test this and let me know how it goes!).

Just covering for myself one last time...

_Since this is custom firmware, you will have to break the Appendix on the xBuddy board (voiding the warranty with Prusa). These firmware builds have not been through a full software test campaign and quality control pipeline like what Prusa would most likely do. I have only tested with my aforementioned hardware setup and have found success in my testing._

If anyone decides to flash these files, do so at your own risk (I, as Prusa has also stated before, disclaim responsibility for any possible damage done to the printer and/or its surroundings).

Otherwise... Good luck and (hopefully) happy printing! Let me know how it goes and if you have any issues with my releases.

TimW55 commented 6 months ago

@nathanielstepp, Thank you so much.

nathanielstepp commented 6 months ago

@TimW55, let me know how it goes if you decide to flash the firmware (assuming you don't mind being a quasi-beta tester 😅).

TimW55 commented 6 months ago

@nathanielstepp, I will certainly let you know what I do.
However, I am slightly concerned about removing the xBuddy board's appendix, not because its tricky but because, in principle, I don't like invalidating warranty. A couple of hours ago I spoke to Prusa Support. They said that a fix is being tested and that a new FW version will be released before the end of the month and possibly in a few days. Irrespective I greatly appreciate all your efforts to get to the root of this issue.