Skip to content

BLTouch Mesh Adjustment Tool

Posted in Tools

[April 10th: Updated to better reflect using the 4-point levelling positions as references]

This tool will help you to calibrate your BLTouch sensor and additionally produce the required GCodes to adjust for twisted x-carriage rails and resulting probe errors. See here for a detailed explanation of the issue you can address with this.

Please enter at least your BLTouch Z-readings for the left and right probes in the form below. In most cases you should be good with the default values for the other settings if you have a standard Anycubic Mega S setup with the BLTouch mounted in the hotted housing and followed the below calibration routine. Otherwise please don’t forget to change them as required, or the adjustments will not work properly.

We use the front left and right positions from the preceding manual 4-point levelling, which for this calibration we consider to be the gold standard for the perfectly levelled bed (because of course we did that very carefully 😊 ). If you have a different setup, please launch the 4-point levelling from special menu, go to points A and B and use M114 to read your positions and change them accordingly below in steps 6, 13 and 24, and set them in the calculation form.

Use a terminal interface for your printer (OctoPrint, Pronterface) to execute the following commands to setup BLTouch probe and adjustment data:

  1. Make sure you have a properly 4-point manually levelled bed and that the bed is either cold or warm now, but not still cooling down from manual levelling.
  2. Heat up the nozzle to preferred printing temp. (e.g. 200°C). The bed doesn’t need to be heated for the following calibration.
  3. G28 (homing)
  4. G90 (absolute positioning)
  5. G1 Z10 (lift printhead to height 10mm)
  6. G1 X17 Y40 F4000 (move BLTouch tip to front left 4-point levelling point <15,15>, i.e. X=15-(-2) and Y=15-(-25))
  7. M280 P0 S10 (release BLTouch probe)
  8. G91 (relative positioning)
  9. Slowly lower the probe with G1 Z-1 or G1 Z-0.1 or G1 Z-0.02 until the BLTouch sensor is triggered (blinking red). NOT FURTHER! Otherwise start all over!
  10. M280 P0 S160 (pull probe back)
  11. M114  (Read and note current z position of the nozzle, e.g. Recv: X:17.00 Y:40.00 Z:2.20 …)
  12. G90 (absolute positioning)
  13. G1 X15 Y15 F4000 (move nozzle to front left 4-point levelling position)
  14. G91 (relative positioning)
  15. Place a sheet of paper under the nozzle
  16. Slowly lower the nozzle with G1 Z-1 or G1 Z-0.1 or G1 Z-0.02 until the paper scratches when dragging
  17. M114 (Read and note current position of the nozzle, e.g. Recv: X:15.00 Y:15.00 Z:0.02 …)
  18. Subtract this Z value from the reading from step 11 -> 2.20 – 0.02 = 2.18 mm -> This is the Z offset between the nozzle and a triggered BLTouch probe on the left side.
  19. M851 Z-2.18 (set probe/nozzle offset)
  20. M500 (save data)
  21. Now we need to determine the correction value for the x-carriage twist impact on the right side
  22. G90 (absolute positioning)
  23. G1 Z10 (lift printhead to height 10mm)
  24. G1 X207 Y40 F4000 (move BLTouch tip to front right 4-point levelling point <205,15>, i.e. X=205-(-2) and Y=15-(-25))
  25. M280 P0 S10 (release BLTouch probe)
  26. G91 (relative positioning)
  27. Slowly lower the probe with G1 Z-1 or G1 Z-0.1 or G1 Z-0.02 until the BLTouch sensor is triggered (blinking red), like you did above already
  28. M280 P0 S160 (pull probe back)
  29. M114  (Read and note current z position of the nozzle, e.g. Recv: X:207.00 Y:40.00 Z:2.35 …)
  30. Use the values from step 11 and 29 (i.e. here 2.20 and 2.35) and enter them in the form below for the left and right BLTouch Z fields..
  31. Press “Generate GCode” and apply those adjustment commands after each G29 automatic bed levelling. You can do it now once using e.g. OctoPrints multi line terminal command plugin, but a better way is to create one printing profile for your slicer (Cura, Prusa) that will do a bed levelling ahead of printing. After the G29 for the bed levelling procedure, add the below GCodes to apply them right away. Another option is an OctoPrint custom bed levelling command button that heats up the bed, does the levelling procedure and then applies the generated fix commands.

Note: if you don‘t apply this to an Anycubic Mega S printer or have a different position for your BLTouch, you will likely need to adjust the other parameters also, like finding an appropriate right side x-coordinate close to your bed edge and the left and right corner x-coordinates of the mesh. See also the note above on using the correct 4-point levelling positions. If your BLTouch position does not allow you to move the tip to the exact 4-point levelling positions, use the closest possible position instead.

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 8

No votes so far! Be the first to rate this post.

19 Comments

  1. AxelLenaerts
    AxelLenaerts

    Can you please make another one but for the Y axis

    June 14, 2021
    |Reply
    • Hansi
      Hansi

      Any systematic difference between BLTouch and Nozzle wouldn‘t change for Y-movements (as only the plate is being moved). Any deviation for the plate over Y should be detected by the BLtouch and accounted for accordingly (basically what you actually have it for).

      June 14, 2021
      |Reply
      • AxelLenaerts
        AxelLenaerts

        That’s what I thought but no, in the back it is perfect and in the front it is printing on air.

        June 14, 2021
        |Reply
        • Hansi
          Hansi

          Can you post the Mesh visualisation?
          In theory that is exactly why you have a BLTouch. It should compensate for such deviations of the print bed. With the twisted X-Axis there is one additional error creeping in that it just can’t “know” and that is not static, but changes linearly over X. Can’t think of how that should happen for Y. Of course the bed rails can be bent also, the bed can be inaccurate on the sled…but BLTouch should just measure that and compensate. That (and “potholes” in the bed) is what it should detect and eliminate. Otherwise you wouldn’t need it at all 😉

          June 14, 2021
          |Reply
          • AxelLenaerts
            AxelLenaerts

            I tried instaling Octoprint but found out it uses a razbabery pi and I don’t have one laying around so is there another way far a bed vizualizer other then octopi. Sorry if I’m making a lot of spelling mistakes I normally speek Dutch and I’m 13.

            June 14, 2021
          • AxelLenaerts
            AxelLenaerts

            Maybe I can just lower the nozzle even more and live with it, I need to try that.

            June 14, 2021
  2. elhanan
    elhanan

    marlin has a z offset wizard that does a very similar thing you do to detect the z offset (only if does it for the center) can i use that instead , and just probe the left and right corners?

    September 30, 2021
    |Reply
    • Hansi
      Hansi

      Hm — not sure. The Z-Offset wizard is a new thing, and I haven’t tried it out so far at all. The Z-offset we’re detecting here is in the end the difference between nozzle and BLTouch, so not sure the wizard will help you for this. You can try, but in the end the described way is easy and straight forward also.

      September 30, 2021
      |Reply
  3. Danke für diesen Beitrag! Hat mir SEHR geholfen – nun ist der Druck wieder gleichmäßig. 🙂 Ich war schon kurz davor den BLtouch in die Tonne zu treten. 😂 Auf dieses Problem muss man erstmal kommen… 😅

    October 6, 2021
    |Reply
  4. mrpilipo
    mrpilipo

    Hansi, you are a life saver, knutwurst pointed me here after almost two days of frustrations (-_-;)
    Now I just need an elegant way to implement it in klipper (no M421 commnand)…
    For now made two macros, that make it easy to get z-offset reading for left and right side, maybe it will come handy for someone:

    [gcode_macro twist_left]
    description: Left leveling point for x-carriage twist fix
    gcode:
    {% set probe_x_offset = printer.configfile.settings.bltouch.x_offset|float %}
    {% set probe_y_offset = printer.configfile.settings.bltouch.y_offset|float %}
    {% set point_x = 15 %}
    {% set point_y = 15 %}
    BED_MESH_CLEAR
    G0 Z10
    G0 X{point_x – probe_x_offset} Y{point_y – probe_y_offset} F4000
    PROBE_CALIBRATE

    [gcode_macro twist_right]
    description: Right leveling point for x-carriage twist fix
    gcode:
    {% set probe_x_offset = printer.configfile.settings.bltouch.x_offset|float %}
    {% set probe_y_offset = printer.configfile.settings.bltouch.y_offset|float %}
    {% set point_x = 205 %}
    {% set point_y = 15 %}
    BED_MESH_CLEAR
    G0 Z10
    G0 X{point_x – probe_x_offset} Y{point_y – probe_y_offset} F4000
    PROBE_CALIBRATE

    February 1, 2022
    |Reply
    • Dan M
      Dan M

      Thanks so much! Have you had any progress regarding the automatic adaptation of the measured mesh data? I tried to do the calculations in an excel spreadsheet, but its still a lot of manual work. It’s close to impossible to hand-tweak a 5×5 map, especially if you have to switch nozzles a lot.

      May 31, 2022
      |Reply
  5. Zaf
    Zaf

    Hello, I read your guide which is quite comprehensive but the end result on octoprint bed visualizer is almost identical with the probing prior implimenting the M421 commands in my code.
    To be specific:
    1. i have installed the X-carriage MK4 from ML (thingiverse) and i have installed the BLT with offsets X29 Y-20 and Z-1.36.
    2. My Anycubic i3 Mega S has Trigorila 1.0, TMC2208 drivers (5 in total) and Marlin 2.0.9 (by knutswurst).
    3. I have heated the bed up to 60 Celcius and performed the 4-point manual bed leveling (twice just to be sure).
    4. I used the G42 I0 J0 F4000 and M114, so position is X29 Y10 and BLT Z-offset is -1.36
    5. I used the G42 I4 J0 F4000 and M114, so position is X200 Y10 and BLT Z-offset is -1.14
    6. I used the above values into your calculator as per below:
    a) BLTouch setup, X-offset from nozzle: 29
    b) Measurement 1, Nozzle X: 0, BLTouch Z: -1.36
    c) Measurement 2, Nozzle X: 171, BLTouch Z: -1.14
    d) Mesh Data, Grid X:5, Grid Y:5
    e) Mesh left X: 29 , Mesh right X: 200

    The calculator’s outcome was as per below:
    ; apply x-carriage twist fixes

    M421 I0 J0 Q+0.00
    M421 I0 J1 Q+0.00
    M421 I0 J2 Q+0.00
    M421 I0 J3 Q+0.00
    M421 I0 J4 Q+0.00
    M421 I1 J0 Q-0.06
    M421 I1 J1 Q-0.06
    M421 I1 J2 Q-0.06
    M421 I1 J3 Q-0.06
    M421 I1 J4 Q-0.06
    M421 I2 J0 Q-0.11
    M421 I2 J1 Q-0.11
    M421 I2 J2 Q-0.11
    M421 I2 J3 Q-0.11
    M421 I2 J4 Q-0.11
    M421 I3 J0 Q-0.17
    M421 I3 J1 Q-0.17
    M421 I3 J2 Q-0.17
    M421 I3 J3 Q-0.17
    M421 I3 J4 Q-0.17
    M421 I4 J0 Q-0.22
    M421 I4 J1 Q-0.22
    M421 I4 J2 Q-0.22
    M421 I4 J3 Q-0.22
    M421 I4 J4 Q-0.22

    M500 ; save it

    However, again the bed visuallizer on octoprint is the same prior applying the corrections of your calculator. My bed is displayed with the left side to be high and right side to be descenting with M420 V readings:

    Recv: 0 1 2 3 4
    Recv: 0 +0.006 -0.188 -0.381 -0.509 -0.441
    Recv: 1 +0.022 -0.152 -0.380 -0.519 -0.458
    Recv: 2 +0.033 -0.124 -0.349 -0.463 -0.417
    Recv: 3 +0.047 -0.118 -0.324 -0.451 -0.397
    Recv: 4 +0.073 -0.124 -0.322 -0.457 -0.410

    Am I using your calculator erroneously?
    Thank you in advance.

    April 17, 2023
    |Reply
    • Hansi
      Hansi

      Hard to say w/o knowing your exact setup. From the mesh matrix you posted, the correction values are roughly only half of what they should be (+ your bed seems to have another „real“ bending in addition, as you can see with values decreasing again from col. 3 to 4). As this calculation is no magic overall, it means that rather your input values are not completely correct. Just from a quick glance (and it might be just a coincidence) it seems e.g. strange that your mesh starts with x=29 only, and that also happens to be the offset Nozzle-BLT. It‘s very important to provide the correct values (I might need to add another graphics to show where to exactly read/derive them from…)
      If you have a standard Mega S, just change the nozzle offset to 29 (negative, if BLT has a larger x-coord. than the nozzle. 29 seems pretty huge, BTW…), and enter your z values (which on the other hand seem to have a pretty small delta, given how tilted your bed appears). Leave everything else as it was (as the defaults are for this printer anyways…)

      April 17, 2023
      |Reply
      • Zaf
        Zaf

        thank you for your fast reply!
        My carriage is 3d printed from thingiverse widely used as an upgrade to i3 megas (https://www.thingiverse.com/thing:3537449). the X-offset seems huge but the BLT is installed on the dedicaded position on this 3d printed carriage (on the right of the nozzle).
        I think that the x:29 mesh starting is not coinsidence, because i set the X,Y-offsets of BLT in the fw prior compiling it.
        My main question is if i put my values correctly into your calculator, because it is not so clear to me the fields that need to be filled.

        April 17, 2023
        |Reply
        • Hansi
          Hansi

          X-offset needs to be -29 (not 29) in your case (first value in sheet). I still have my doubts regarding your mesh data, but then I don‘t have this printer type myself. Maybe someone else with a similar setup to yours can provide more input here.

          April 17, 2023
          |Reply
  6. Martin
    Martin

    I’m not understanding step 31. Could you elaborate please? I’m using Pronterface and Cura. I just don’t know how to add code to printer.

    June 8, 2023
    |Reply
    • Hansi
      Hansi

      I can‘t tell for sure for Cura, as I usually use Prusa. But there should be a a way to change the profiles that contain the commands that are sent to the printer ahead of each print. So you just need to make sure that before each print the set of Gcodes containing the offset fixes are supplied to the printer.

      June 11, 2023
      |Reply
  7. ahmed sameh
    ahmed sameh

    I was wondering when I use ( M500 ; save it ) doesn’t that make the code accumulate becuase i put is in the profile in Cura.
    for example if i use this the first time and save it (M421 I2 J0 Q-0.11 ) and then when i print agine the same code will run agine and use the(M421 I2 J0 Q-0.11 ) and ( M500 ; save it )
    does it mean the the overall it will be (M421 I2 J0 Q-0.22 ) Q-0.22? or i am wrong.

    and really thank you for everythng.

    November 22, 2023
    |Reply
    • Hansi
      Hansi

      No, there can be just one set of correction values, they are not accumulative.

      November 24, 2023
      |Reply

Leave a Reply

Your email address will not be published. Required fields are marked *