Bed Correction with three motors - little error left


I have a three Z-axes BedLevelcorrection Printer, Motor Setup like this

|          M1           |
|                         |
| M2               M3|

M1 connected  to  the official z-stepper place

It almost does like intended when doing the G32. Only that the M1 position is about 0.1 mm lower and stays there, no matter how often I do the G32. As I observed, only M2 and M3 are working when doing correction, M1 just holds position (Is this correct or part of the problem?). I tried to move the M1 Position in the the configure.h to abount a 100mm to y wich seems to work a bit. But the M1 Position / backside of the bed is still lower. Higher tilt will be reduced, that works fine, but the remaining Z Height error is a little to big (I think it is acceptable aroung 0.06 difference (- am I to picky?))

Is there a GCode for giving M1 a few extra steps after bed levelling? Is there a way to compensate?


  • It is correct to not move M1. This is taken as given height and M2/M3 are modified to go to same level. That is also why you only define these 2 motors for extra driver in addition.

    Have you tried repeated autoleveling? It should converge with each leveling to tho optimal solution.
  • May be the problem is caused because I do only one cycle at a time (but doing 3 times the G32 via starting script.

    I crawled into the source code, adding a maxdiff with "do no correction under 0.05 maxdiff" and multiplying the h2 and h3 - height correction for the motors, by 1.5. 
    And I use the direct measured values for h1, h2, h3 (declared in global scope):

    Works for me, but is not very elegant.  Should have used at least the EEProm instead of h1,h2,h3.
    Seems that there is no way to mask a  ZMin-Endstop-before-Z-Probe-Event. With badly distorted bed's one probably need a switch to bypass the Z-min endstop. (yeah, we should all home to zmax. I dont't want to. Homing Z min after G32 and having a good adjustable endstop is just to nice to have).

    Here the changed snipplets form BedLevelling.cpp:

    #if BED_LEVELING_METHOD == 0 // 3 point
        float h;
        h = Printer::runZProbe(false,false);
        if(h == ILLEGAL_Z_PROBE)
           return false;
        h = Printer::runZProbe(false,false);
        if(h == ILLEGAL_Z_PROBE)
            return false;

        h = Printer::runZProbe(false,false);
        if(h == ILLEGAL_Z_PROBE)
            return false;


    void correctAutolevel(GCode *code,Plane &plane) {
    #if BED_CORRECTION_METHOD == 0 // rotation matrix
    #elif BED_CORRECTION_METHOD == 1 // motorized correction
    #if !defined(NUM_MOTOR_DRIVERS) || NUM_MOTOR_DRIVERS < 2
    #error You need to define 2 motors for motorized bed correction
        Commands::waitUntilEndOfAllMoves(); // move steppers might be leveling steppers as well !
       //the usual way, but not to overwrite our h1, h2, h3:
        float h11 = plane.z(BED_MOTOR_1_X,BED_MOTOR_1_Y);
        float h22 = plane.z(BED_MOTOR_2_X,BED_MOTOR_2_Y);
        float h32 = plane.z(BED_MOTOR_3_X,BED_MOTOR_3_Y);
        h22 -= h11;
        h32 -= h11;
        //Com::printFLN(PSTR(" h1 plane = "),h11,4);
        //Com::printFLN(PSTR(" h2 plane = "),h22,4);
        //Com::printFLN(PSTR(" h3 plane = "),h32,4);
        // h1 is reference heights, h2 => motor 0, h3 => motor 1
        h2 -= h1;
        h3 -= h1;
        Com::printFLN(PSTR(" h1 = "),h1,4);
        Com::printFLN(PSTR(" h2 = "),h2,4);
        Com::printFLN(PSTR(" h3 = "),h3,4);

       float maxdiff;
        float absh2 = abs(h2);
        float absh3 = abs(h3);
        if (absh3>absh2) maxdiff= absh3;
        else maxdiff = absh2;
        Com::printFLN(PSTR(" MaxDiff left: = "),maxdiff,4);

        if (maxdiff<0.06) { //ready!
             Com::printFLN(PSTR(" Ready, diff left: = "),maxdiff,4);

  • Looking in my code I think it should have nearly perfect correction in first pass. But to be that good you need to configure it correctly. I think your error might be no knowing the difference between probing points and BED_MOTOR_x.
    Probing points should be a grid or points at maximum distance to each other.
    BED_MOTOR_x is where the 3 motor spindels are located in relation to the printing coordinate system. That is more to the outside. This gives them also a multipilcator to measured values. In your case maybe 1.5 but I doubt it is that linear in all cases.

    In your sample code I see not where h1, h2 and h3 come from. h11 seems to have value of h1.
  • I've declared h1,h2,h3 just at the beginning of the text, making them global. So they have exactly the Z-Probe Distances from the first snipplet.

    The exakt Positions of the motors are not easy to tell, because the coordinates on the xy plane does nut mean anything. Just imagine a bed onto two bars at the front and the backsiide. The bars have some width. The true rotation axis would depend on that bars and to the degree of their ability to turn. Otherwise, it's either the front or back upper edge of the bar defining the tilt, not it's middle.
    That having said, I come as close as 10 mm to the Position of the motors :-)

    Now - even with wrong positions for the motors, iterative the plane gets more and more horizontally, dimishing possible errors from faulty motor positions. At least with my blunt try. Depending of the scope of the bed tilt, it always come to a horizontal solution. Ready on first try with a small tilt, up to five with a really big one (let's say 5 mm max difference).
    But calculating over the planes, it does not, the around-0.1-mm fault just remains. As I checked that, I had no explanation for this.
    If my printer tends to absorb smal z steps z upward, would be possible. On the other hand, after probing and correcting, it goes about 10 mm down and up. And the last steps of my formulae are very tiny in the end also. And I see nothing irregular in the z-layer shapes of the print.
    Even wrong steps/mm for the additional 2 Motors would'nt explain. It should come to a horizontal plane also, only that you need more iterations.

    On the other hand, I'd find it possible that during all the operations with the geometrical plane, rounding errors occur. Especially with only floats (I would use instincly doubles, whenever tan, sin and cos are at stage). Don't know. Only that the plane solution, even with the factor of 1.5, one edges remains lower.

    If I find the time, I will go through again tomorrow, switching back to your original code but with doubles instead of floats in all plane operations. If it is THAT, I want you to lower the "You must home to Z-Max-Commandment"-restrictions :-)
  • edited March 2018

  • Origin is exactly defined. Home, G1 X0 Y0 and you know where on bed it is. Motor positions must not be reachable, that is why we have test positions AND motor positions. A bit tilt makes no big difference with respect of errors. Also a mm error of spindle position to bed origin is not the biggest matter, especially if you optimize every repeat and normally it is still in level from last correction anyway.

    AVR has no double - double is just float for them.

    There is also no you MUST home z max. It is just the best solution with bed leveling. Only drawback are few more seconds during homing. But that is neglible thinking about the time to print. Also you can start heating, then home, go down and then wait for temperatures to be reached. Normally homing is quicker then heating process.

    If you do z min homing with autolevel you must use a z probe for this along with ensuring all the side problems like using a position where you can activate z probe, eventually go up before deploying z probe, but it is possible.
  • It is not a matter of avoiding the extra time in homing to zmax. It's about having a  hand-adjustable distance to the bed, in my case with a micrometer screw via adjustable ZMin Endstop.  It's very nice to have.
    The problem left is that you cannot mask out the ZMin-Exdstop while going for zProbe, wich results in errror & interrupted probe sequence when ZEndstop is hit before Z-Probe. Saving the time a a zMax-Homing is no reason for changes, but the additional function -- may be. Sequence is Homing ZMin, BedCorrect, Homing Z-Min again with a hot bed, starting print.
  • Yes, that is the problem with z min and z probe. Since it is a safety guard it must stop and would do so in prints so it must trigger below bed (with bed on springs) or it will prevent legitimate moves and disturb what you need.

    That is why I say for z min homing the endstop must be the probe.
Sign In or Register to comment.