Marlin removes Z endstop when I set probe to same pin.

Created on 9 Aug 2018  路  16Comments  路  Source: MarlinFirmware/Marlin

I connected my Z-max endstop and my calibration probe to the same pin as my board doesnt have extra connectors. I used`#define Z_MIN_PROBE_ENDSTOP

define Z_MIN_PROBE_PIN 20` to set my probe pin. Pin 20 is my Zmax endstop pin. When I run M119 to check endstops Z-max is missing and it is being replaced by the probe. I expected this to just add the probe not replace my zmax. Because of this I can't home as z-max is not present. They both trigger fine when I trigger the switch or probe. I can read it off of the probe endstop with M119.

I've seen other posts where people say they've done it so I assume I am just doing it incorrectly and the above code is either incomplete or not the way to do it.

Any help would be greatly appreciated.

Most helpful comment

sorry but I deleted my marlin that I had working the probe with the same pin as z_max. I got everything to work except G33. I really needed G33 so I went another route and used one of the display pins instead since this printers don't have a display. but to help you out this is what I had to do:

  • enable z_probe and set pin in config.h file.
    -HAS_Z_MAX gets disabled after doing that so I commented out the line that defines HAS_Z_MAX and just redefined it set to true. you can find it with ctrl f and click search all files.
    -then I went to endstops.h and declared a boolean variable.
    -then went to endstops.cpp and declared the variable. down in the code you can see where it checks for probe pin being the same as endstop pin. if they are the same it won't update endstops so you won't be able to use g28. you have to comment out that if statement and just add an "else" instead so that it always updates the endstop regardless of pins.
  • That is all you need to get it to work I think but the variable I added was to stop updating z_max when I wanted.
    -If you follow those instructions, if the probe is touching the bed it won't home properly as it will think the endstop is being triggered. So I added the variable to disable at a certain spot and re enable it when it was needed. I did the enable disable in marlin_main.cpp and I added an if statement that enables and disables z_max checking in endstops.cpp.

Just keep in mind, endstops.cpp checks for the pins twice so you have to comment that out twice. Then if you wan't autoleveling done you have to disable Z_MAX on the autoleveling code. It works but it's not ideal. And getting G33 to work proved to be a nightmare so I ditched that. I just connected the probe to a display pin and everything works great as it should. I just had to set the display pin to -1 because it was causing problems. Good luck. It took me a few days to figure all that out but I gotta say that using the display pin is soooo much easier and less trouble.

All 16 comments

Try removing your manual Z_MIN_PROBE_PIN define.
From Configuration.h, in the description for Z_MIN_PROBE_ENDSTOP:

Enable this option for a probe connected to any pin except Z-Min. (By default Marlin assumes the Z-Max endstop pin.)

I tried doing that but I get an error saying Z_MIN_PROBE_PIN needs to be defined. I narrowed down the problem to the line #define HAS_Z_MAX HAS_STOP_TEST(Z,MAX) on the file Conditionals_post.h. That seems to define whether an endstop is available or not. Since it was being set to false for some reason I commented out that line and added #define HAS_Z_MAX true. This brought back z_max when I run the Gcode M119.
Now it shows all 3 towers and probe and it triggers accordingly. I thought I was done but surprisingly enough G28 is not using the z_max endstop at all so I can't even home just like before. That leads me to believe the variable HAS_Z_MAX didnt affect G28 only M119 oddly so I might have missed another variable that affects both.

I narrowed down the problem to #define PIN_EXISTS(PN) (defined(PN ##_PIN) && PN ##_PIN >= 0) in Macros.h. This line is disabling my Z tower but I can't figure out how it works or what it does so I don't know how to fix it. There are no comments explaining it.

Did you define a Z_MAX pin? That whole stack of macros is ensuring that Marlin has an address for each input it needs. If you force it to be true, that doesn't solve the root problem of there not being an address.

The PIN_EXISTS(x) macro just checks to see if x_PIN is defined and positive. For example, PIN_EXISTS(Z_MAX) is true if Z_MAX_PIN is defined and positive.

I appreciate your responses. Let me walk you through my thought process. Through the code that executes with the M119 command, I figured out HAS_Z_MAX is being set to false when I set the probe pin to the same as the z-endstop pin with #define Z_MIN_PROBE_PIN 20 Z_MAX pin is set to 20 in the board pin file. This enabled the z_probe as a switch but disabled Z_Max. I went to where HAS_Z_MAX is defined as the likely culprit to figure out why it was being set to false. This is the line that defines it #define HAS_Z_MAX HAS_STOP_TEST(Z,MAX). My thinking is that if HAS_Z_MAX is false it is because HAS_STOP_TEST(Z,MAX). I'm not exactly sure what this does but it is defined a few lines before HAS_Z_MAX. #define HAS_STOP_TEST(A,M) (PIN_EXISTS(A##_##M) && !IS_X2_ENDSTOP(A,M) && !IS_Y2_ENDSTOP(A,M) && !IS_Z2_OR_PROBE(A,M)). If PIN_EXISTS just returns true like you said then my problem could be the last code snippet. I just don't know what that last code snippet is doing. If that last code snippet is not my problem then something else is setting HAS_Z_MAX to false when the zprobe pin is 20. If you could shed some light on that you would be my hero. I really need to finish this project but that is really holding me back.

I've thought more about what you want to do, and it's not possible in current Marlin. Marlin doesn't have the ability to distinguish between multiple working sensors on the same digital input, and it would take a lot of logic to get it to that point, because each instance where the endstop is used would need to distinguish between the two cases.

Since you're still getting hung up on the macros I can explain what they do. They're basically a way to replace text in the code before compiling. When you define Z_MAX_PROBE (for example), all instances of Z_MAX_PROBE get set to whatever you define. Macros can have parameters, and the ## means to concatenate those parameters with the surrounding text. So HAS_STOP_TEST(Z, MAX) is expanded at compile time to (PIN_EXISTS(Z_MAX) && !IS_X2_ENDSTOP(Z, MAX) && !IS_Y2_ENDSTOP(Z, MAX) && !IS_Z2_OR_PROBE(Z, MAX)), and each of the macros inside are further expanded until all that's left is plain code.

So you have two options: use Z_MAX (or something unnecessary) for probing and Z_MIN for homing, or to use your probe for both leveling and homing (and possibly having to enable Z_SAFE_HOMING.

I find it odd that this doesnt work in marlin. If HAS_Z_MAX is set to true M119 seems to work properly. It shows all 4 switch variables and they trigger accordingly. G28 just seems to not see Z_MAX while M119 does. I'm thinking of either setting the probe to an unused pin to allow it to compile while keeping it connected to pin 20 and just setting the probe equal to Z_MAX when marlin checks for switch values. Or using one of the LCD Pins as This printer design has no LCD.

Again, the problem is detangling which triggers are from the probe and which are from the endstop.

By forcing HAS_Z_MAX to true, you're not changing the behavior of G28, because HAS_Z_MAX isn't meant to be manually set.

I'm thinking of either setting the probe to an unused pin to allow it to compile while keeping it connected to pin 20 and just setting the probe equal to Z_MAX when marlin checks for switch values.
This will run into problems if the probe is triggered when you initiate homing, or the endstop when you initiate probing. If you still want to risk lots of unexpected behavior, the modification is much simpler: remove the && !IS_Z2_OR_PROBE(Z, MAX) clause from the HAS_STOP_TEST macro, which is meant specifically to prevent people from overloading endstops like this.

I don't see why it would have to detangle which is which. The pin is set to 5V when either is triggered. The probe is only going to trigger the pin when doing calibration as it is removable. And Z_max shouldnt be able to trigger when probing a calibration. There must be something I am failing to grasp. I am making progress on setting the probe to a different pin and just setting the probe variable equal to the z_max. I just can't find how the line that updates the switch works. I don't see a variable I can just set. It's functions over functions. If this doesnt work I'll have to directly wire the probe to the LCD Pins.

I found the solution. I set #define HAS_Z_MAX to true to enable my endstop. In Endstops.cpp on the update function towards the bottom there are checks for each endstop that checks if the endstop pin is the same as the z probe. If that is the case it won't run some code. I commented that line and another that also made the comparison and made it so that it always run even if the pins are the same. That seemed to fixed my problems. My only problem now is that my autocalibration stops because Z_max is triggered when the probe hits the bed. I just have to find out how to disable the endstops during calibration. Thank you for your help. Even though you didn't solve the problem directly, you made me think of different solutions.

I couldnt find the part where it checks for the endstops so I added my own code that prevents marlin from reading the z_max endstop during calibration. its a simple boolean expression that is only enabled during calibration.

I added my own code that prevents marlin from reading the z_max endstop during calibration. its a simple boolean expression that is only enabled during calibration.

Could you please share a file name and line/function name?
I plan to try to add z-probe to Anet A4 printer. The problem that it is Delta and homes to Z_MAX and mainboard has only 3 endstop plugs and I will need to do the same you did and want to have some sure guidelines.

Thanks in advance.

I connected my Z-max endstop and my calibration probe to the same pin as my board doesnt have extra connectors.

It's not a supported configuration currently, but if you can get it working, great! It's not a very common setup, as both the endstop and the probe must use Normally Open switches (parallel, NC in series) for it to work.

sorry but I deleted my marlin that I had working the probe with the same pin as z_max. I got everything to work except G33. I really needed G33 so I went another route and used one of the display pins instead since this printers don't have a display. but to help you out this is what I had to do:

  • enable z_probe and set pin in config.h file.
    -HAS_Z_MAX gets disabled after doing that so I commented out the line that defines HAS_Z_MAX and just redefined it set to true. you can find it with ctrl f and click search all files.
    -then I went to endstops.h and declared a boolean variable.
    -then went to endstops.cpp and declared the variable. down in the code you can see where it checks for probe pin being the same as endstop pin. if they are the same it won't update endstops so you won't be able to use g28. you have to comment out that if statement and just add an "else" instead so that it always updates the endstop regardless of pins.
  • That is all you need to get it to work I think but the variable I added was to stop updating z_max when I wanted.
    -If you follow those instructions, if the probe is touching the bed it won't home properly as it will think the endstop is being triggered. So I added the variable to disable at a certain spot and re enable it when it was needed. I did the enable disable in marlin_main.cpp and I added an if statement that enables and disables z_max checking in endstops.cpp.

Just keep in mind, endstops.cpp checks for the pins twice so you have to comment that out twice. Then if you wan't autoleveling done you have to disable Z_MAX on the autoleveling code. It works but it's not ideal. And getting G33 to work proved to be a nightmare so I ditched that. I just connected the probe to a display pin and everything works great as it should. I just had to set the display pin to -1 because it was causing problems. Good luck. It took me a few days to figure all that out but I gotta say that using the display pin is soooo much easier and less trouble.

as both the endstop and the probe must use Normally Open switches for it to work.

when they are connected in parallel. When they are connected in series use normally closed ones and change the polarity of the pin.

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings