Custom Z-probe question

edited April 12 in Repetier-Firmware
Hi, 
This is my 1st post here and I'd like to say BIG THANKS to the developers of Repetier-Firmware. I switched to Repetier 0.92 about 5 weeks ago after using different versions of Marlin and then Klipper and so far am extremely happy with Repetier's stability, reliability and performance. 

I am in the process of designing my own 3d printed touch-based z-probe and have a question about the output signals it should generate. 
During normal operation/printing, my z-probe's sensor-pin will be lifted and the output of z-probe will be HIGH. During bed leveling, when the pin is lowered, output will be LOW and will switch to HIGH when pin touches the bed. Could you please advice if such output from z-probe is supported and whether Z_PROBE_ON_HIGH should be set to 1 or 0. I have Z_max_endstop and will not be using z-probe as Z_min_endstop.
Another related question - does it matter whether z-probe's output is HIGH or LOW during the time when we are not running bed leveling?

Thanks

Comments

  • Good questions. First being not used for homing is good, so wrong signal will not hurt here.

    When probing start the signal must be low so it can switch high. However, there is a start and end gcode run to allow e.g. deploying the probe. I'm not 100% sure but think if you deploy it and add a small delay (G4) so that you know signal should be low when script finishes, I think the wrong signal on idle position should not hurt. I think the test happens after that.
  • Thanks for quick reply. I am still waiting for sensor PCB to arrive and will report the results once z-probe is ready.
  • After spending entire weekend soldering, googling for the info, tweaking configuration files and re-flashing firmware,  it all finally came together and my home-made 3d printed z-probe started to work. The process of collecting data for Octoprint Bed Visualizer plugin (timelapse) is shown here 

    I still have several questions and will post them here later this week.

  • edited April 25
    I used Marlin and Klipper firmware before switching to Repetier, but never had z-probe. Thus, this is the 1st time I am dealing with ABL. Here are few questions that I got after observing how firmware behaves when G32 and G33 commands are executed.

    1) To save time, I'd like to use 3x3 grid with G32 and 7x7 grid with G33. I know this is supported, but is this a good practice? What settings would work the best for 200x200mm heated bed?

    2) The directions of probe moves, while processing G32 and G33 gcodes, are different. The images below depict that. Point P1 is next to Xmin/Ymin, P2 is next to Xmax/Ymin and P3 is next to Xmin/Ymax.

    When running G32 head moves like this:


    When running G33 - like this:

    Is this expected behavior or I have something misconfigured?

    3) Also, just curious about design decision - why not to use the shortest path shown below?

    4) Finally, I got a problem with Octoprint's Bed Visualizer plugin. The bed is drawn flipped along Xmin/Ymin-Xmax/Ymax line, i.e. Xmin/Ymin and Xmax/Ymax corners appear at the right spots, other 2 corners are swapped. I posted question in Octoprint forum and waiting for the reply. Decided to mention it here as well in case somebody experienced the same and knows the solution. Plugin's FlipX and FlipY options do not help in this case. Could this be caused by the issue described in item 2) above?  Here is my gcode from plugin configuration:
     
    ----------------------------
    G28
    M155 S30
    G1 Z20 F400
    M140 S60 ;Start heating bed
    M190 S60 ;Wait for bed to reach temp before proceeding
    G1 X100 Y100 F6000 ; center printhead
    G1 X-9 S1 F4000 ; Pull probe down Step 1
    G1 Y-3 F4000 ; Pull probe down Step 2
    G1 Y20 F6000 ; Move head back to print area Step 3a
    G1 X20 S0 F6000  ; Move head back to print area Step 3b
    G1 X0 Y0 F4000  ; Move head to X0/Y0 Step 3c
    G32 S2 ; S2 Saves in EEPROM
    G1 X0 Y0
    G1 Z10 F400
    M322 S1 ; reset autolevel matrix
    G33
    M500 ; save config in EEPROM
    M155 S3 
    G1 X100 Y100 F6000 ; center printhead
    G1 X-9 S1 F4000 ; Pull probe up Step 1
    G1 Y204 F4000 ; Pull probe up Step 2
    G1 Y100 F6000  ; Move head back to bed center Step 3a
    G1 X100 S0 F6000 ; Move head back to bed center Step 3b
    ----------------------------

    Thanks

  • 1) Yes, you can do that. Just make sure G32 S2 is run before G33 and NO homing in between.
    2) Different routines and different definitions, so order can in deed differ, but that is no problem.
    3) Code was easier and did not think of it. Maybe I change it some time.
    4) Don't use Octoprint so can not say if the plugin has swapped something.
  • Thanks for quick response!
    If I get my Octoprint issue resolved, I post here the solution. 
  • I just fixed the issue with Octoprint plugin by swapping 2 lines of code in Distortion.cpp file. I replaced
    -----------------------
    void Distortion::showMatrix() { 
        for(int ix = 0; ix < DISTORTION_CORRECTION_POINTS; ix++) {
            for(int iy = 0; iy < DISTORTION_CORRECTION_POINTS; iy++) {
    -----------------------
    with 
    -----------------------
    void Distortion::showMatrix() {
        for(int iy = 0; iy < DISTORTION_CORRECTION_POINTS; iy++) {
            for(int ix = 0; ix < DISTORTION_CORRECTION_POINTS; ix++) {
    -----------------------
    Not sure if this needs to be fixed in Repetier or in the plugin. I reported the issue to plugin developer here

    Thanks 
  • I think the plugin should test the positions, that is why we write them down. You can not expect all firmwares to behave the same or to never change order. Imagine I would fix it now. Users with old firmware will fail and newer users will succeed.
  • edited April 26
    I think the plugin should test the positions, that is why we write them down.
    I concur with above statement.

    I was able to modify measureAutolevelPlane function in BedLeveling.cpp and make probe move is zig-zag manner. It works on my Core XY printer. Please review below code and feel free to use it. I will try to do similar change to the routine handling G33.

    Replace these lines: 
        for(int ix = 0; ix < BED_LEVELING_GRID_SIZE; ix++) {
            for(int iy = 0; iy < BED_LEVELING_GRID_SIZE; iy++) {
                float px = ox + static_cast<float>(ix) * ax + static_cast<float>(iy) * bx;
                float py = oy + static_cast<float>(ix) * ay + static_cast<float>(iy) * by;
                Printer::moveTo(px, py, IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed());
                float h = Printer::runZProbe(false, false);
                if(h == ILLEGAL_Z_PROBE)
                    return false;
                builder.addPoint(px, py, h);
            }
        }
    with these:
        int iydir = 1; // 1 if moving towards increasing Y, -1 when in opposite direction 
        int iy;
        for(int ix = 0; ix < BED_LEVELING_GRID_SIZE; ix++) {    
            if (iydir == 1) {
                iy = 0;
             } else {
                iy = BED_LEVELING_GRID_SIZE - 1;
            }
            while ((iydir == 1 && iy < BED_LEVELING_GRID_SIZE) || (iydir == -1 && iy >= 0)) {
                float px = ox + static_cast<float>(ix) * ax + static_cast<float>(iy) * bx;
                float py = oy + static_cast<float>(ix) * ay + static_cast<float>(iy) * by;
                Printer::moveTo(px, py, IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed());
                float h = Printer::runZProbe(false, false);
                if(h == ILLEGAL_Z_PROBE)
                    return false;
                builder.addPoint(px, py, h);
                iy += iydir;
            }
            iydir = -iydir;
        }
    Thanks.
  • edited April 27
    Below are 2 versions of modified block from Distortion.cpp file. The 1st version implements optimized, zig-zag shaped movement that starts from Xmin/Ymin. The directions of the movement are consistent with the movements performed after executing G32. The 2nd version implements zig-zag shaped movement, but keeps existing staring point at Xmin/Ymax. My personal preference would be to stay consistent, but it is up to developers to decide which option to pick (if any). Below snippets of the code replace the following block of lines.

    Replace these lines:
        for (iy = DISTORTION_CORRECTION_POINTS - 1; iy >= 0; iy--)
            for (ix = 0; ix < DISTORTION_CORRECTION_POINTS; ix++) {
    #if (DRIVE_SYSTEM == DELTA) && DISTORTION_EXTRAPOLATE_CORNERS
                if (isCorner(ix, iy)) continue;
    #endif
    #if DRIVE_SYSTEM == DELTA
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * step - radiusCorrectionSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * step - radiusCorrectionSteps);
    #else
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * xCorrectionSteps + xOffsetSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * yCorrectionSteps + yOffsetSteps);
    #endif
                //Com::printF(PSTR("mx "),mtx);
                //Com::printF(PSTR("my "),mty);
                //Com::printF(PSTR("ix "),(int)ix);
                //Com::printFLN(PSTR("iy "),(int)iy);
                Printer::moveToReal(mtx, mty, z, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed());
                float zp = Printer::runZProbe(false, false, Z_PROBE_REPETITIONS);
    #if defined(DISTORTION_LIMIT_TO) && DISTORTION_LIMIT_TO != 0
                if(zp == ILLEGAL_Z_PROBE || fabs(z - zp + zCorrection * Printer::invAxisStepsPerMM[Z_AXIS]) > DISTORTION_LIMIT_TO) {
    #else
                if(zp == ILLEGAL_Z_PROBE) {
    #endif
                    Com::printErrorFLN(PSTR("Stopping distortion measurement due to errors."));
                    Printer::finishProbing();
                    return false;
                }
                setMatrix(floor(0.5f + Printer::axisStepsPerMM[Z_AXIS] * (z - zp)) + zCorrection,
                          matrixIndex(ix, iy));
            }
    Option 1 (starting point Xmin/Ymin):
        int iydir = 1; // 1 if moving towards increasing Y, -1 when in opposite direction 
        for(int ix = 0; ix < DISTORTION_CORRECTION_POINTS; ix++) {    
            if (iydir == 1) {
                iy = 0;
             } else {
                iy = DISTORTION_CORRECTION_POINTS - 1;
            }
            while ((iydir == 1 && iy < DISTORTION_CORRECTION_POINTS) || (iydir == -1 && iy >= 0)) {
    #if (DRIVE_SYSTEM == DELTA) && DISTORTION_EXTRAPOLATE_CORNERS
                if (isCorner(ix, iy)) continue;
    #endif
    #if DRIVE_SYSTEM == DELTA
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * step - radiusCorrectionSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * step - radiusCorrectionSteps);
    #else
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * xCorrectionSteps + xOffsetSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * yCorrectionSteps + yOffsetSteps);
    #endif
                //Com::printF(PSTR("mx "),mtx);
                //Com::printF(PSTR("my "),mty);
                //Com::printF(PSTR("ix "),(int)ix);
                //Com::printFLN(PSTR("iy "),(int)iy);
                Printer::moveToReal(mtx, mty, z, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed());
                float zp = Printer::runZProbe(false, false, Z_PROBE_REPETITIONS);
    #if defined(DISTORTION_LIMIT_TO) && DISTORTION_LIMIT_TO != 0
                if(zp == ILLEGAL_Z_PROBE || fabs(z - zp + zCorrection * Printer::invAxisStepsPerMM[Z_AXIS]) > DISTORTION_LIMIT_TO) {
    #else
                if(zp == ILLEGAL_Z_PROBE) {
    #endif
                    Com::printErrorFLN(PSTR("Stopping distortion measurement due to errors."));
                    Printer::finishProbing();
                    return false;
                }
                setMatrix(floor(0.5f + Printer::axisStepsPerMM[Z_AXIS] * (z - zp)) + zCorrection,
                          matrixIndex(ix, iy));
    iy += iydir;
            }
    iydir = -iydir;
    }

    Option 2 (starting point Xmin/Ymax):
        int ixdir = 1; // 1 if moving towards increasing X, -1 when in opposite direction 
        for(int iy = DISTORTION_CORRECTION_POINTS -1; iy >= 0; iy--) {    
            if (ixdir == 1) {
                ix = 0;
             } else {
                ix = DISTORTION_CORRECTION_POINTS - 1;
            }
            while ((ixdir == 1 && ix < DISTORTION_CORRECTION_POINTS) || (ixdir == -1 && ix >= 0)) {
    #if (DRIVE_SYSTEM == DELTA) && DISTORTION_EXTRAPOLATE_CORNERS
                if (isCorner(ix, iy)) continue;
    #endif
    #if DRIVE_SYSTEM == DELTA
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * step - radiusCorrectionSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * step - radiusCorrectionSteps);
    #else
                float mtx = Printer::invAxisStepsPerMM[X_AXIS] * (ix * xCorrectionSteps + xOffsetSteps);
                float mty = Printer::invAxisStepsPerMM[Y_AXIS] * (iy * yCorrectionSteps + yOffsetSteps);
    #endif
                //Com::printF(PSTR("mx "),mtx);
                //Com::printF(PSTR("my "),mty);
                //Com::printF(PSTR("ix "),(int)ix);
                //Com::printFLN(PSTR("iy "),(int)iy);
                Printer::moveToReal(mtx, mty, z, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed());
                float zp = Printer::runZProbe(false, false, Z_PROBE_REPETITIONS);
    #if defined(DISTORTION_LIMIT_TO) && DISTORTION_LIMIT_TO != 0
                if(zp == ILLEGAL_Z_PROBE || fabs(z - zp + zCorrection * Printer::invAxisStepsPerMM[Z_AXIS]) > DISTORTION_LIMIT_TO) {
    #else
                if(zp == ILLEGAL_Z_PROBE) {
    #endif
                    Com::printErrorFLN(PSTR("Stopping distortion measurement due to errors."));
                    Printer::finishProbing();
                    return false;
                }
                setMatrix(floor(0.5f + Printer::axisStepsPerMM[Z_AXIS] * (z - zp)) + zCorrection,
                          matrixIndex(ix, iy));
    ix += ixdir;
            }
    ixdir = -ixdir;
    }
    Both versions of the code were successfully tested on CoreXY printer. 

    Finally, here is time-lapse video showing the sequence of G32 S2 and G33 commands running on my printer after implementing these changes https://www.youtube.com/watch?v=ChvEcDOx-rE

    Thanks 
  • edited April 27
    @Repetier Bed Visualizer plugin's developer is going to update the code to make it compatible with G33 command output. I provided him with the printout generated by Repetier version 1.0.3. Could you please confirm that the format of G33 printout did not change since it was 1st introduced in version 0.92.8? The goal is to make plugin compatible with all Repetier versions that support G33.
    Thanks


  • I think I'd prefer

    for (iy = 0; iy < DISTORTION_CORRECTION_POINTS; iy++)
    for (fast8_t iix = 0; iix < DISTORTION_CORRECTION_POINTS; iix++) {
    ix = iy & 1 ? DISTORTION_CORRECTION_POINTS - 1 - iix : iix;

    going over x left/right with increasing y.

    If it is same as G32 is not important. Selecting different points for G32 can rotate and mirror G32 behaviour. Hope this works as expected as I need to assemble the printer with z probe first.
  •  Selecting different points for G32 can rotate and mirror G32 behaviour.
    I run several tests with the original code and with the code that contains my modifications posted above. I don't see any difference in print quality and also in the way Bed Visualizer presents the measurements results. Based on this data I doubt any rotation or mirroring takes place.

  • I did not say the result will differ. Just the direction of points measured will change. As long as the edges are the same the result will be identical.
  • I did not say the result will differ.

    Sorry, looks like I misread you post from Apr 27. 

Sign In or Register to comment.