Laundry List of small Requests
-
Some background. The machine I am working on is an Wanhao i3 Mini, operating on a custom Melzi controller. There are three 35mm N17 motors, and one 40mm on the Z. There are three end stop switches at zero, they are all SPST normal open, momentary. The bed moves from back to front, the switch being under the leading front of the bed. The X is mounted to an arm, that extends from Right to left, and the switch is on the head zeroing hard right. Z moves bottom to top zeroing at bottom. There is no Z-Probe. There is no need of it. The bed is mechanically leveled using 4x spring loaded thumb screws, and setting the head to 4 corners. In days past I had bad fans that created a lot of vibration on the head, and this made for an awesome bed leveling tool, as I could tune based on when the hum from the fan was transmitted into the build plate, and it worked great. Today however there is something dying on the Melzi board and I have chosen to switch out the board with a Duet2Maestro purchased from M3D durring their Crane preorder campaign, so I can assure I am not working on a clone. I have configured the MicroSD folder structure using instructions posted here: https://duet3d.dozuki.com/Wiki/Firmware_Overview#Section_SD_card_structure The firmware was installed to the folders from: https://github.com/dc42/RepRapFirmware/tree/dev/Driver then following notes on: https://duet3d.dozuki.com/Wiki/Installing_and_Updating_Firmware The files to the card were populated with files from: https://github.com/T3P3/Duet/blob/master/Duet2/SD Card Contents/SD_Card_Contents.zip then edited to weed out non applicable file with: https://duet3d.dozuki.com/Wiki/Firmware_Overview#Section_Duet_Generation_Num_2. Lastly setup was configured with: https://configurator.reprapfirmware.org/ and the files within hand tweaked following prior experience and information posted here: https://duet3d.dozuki.com/Wiki/Gcode
By observation your comment fits observable behavior.
- If you put a numeric argument in quotes, usually it won't be parsed and zero will be assumed. There are currently only a very few places in RRF GCode where numeric parameters in quotes are permitted; whereas string-valued parameters may always be quoted (and must be quote in many commands).
Yes, this seems to be what is happening and this is why I said it is a bug. This causes OTHER axis to act up when they behave just fine in single digits.
- If you set the minimum limit of an axis higher than the maximum limit, you can expect strange things to happen. Perhaps this is what you did when you used digits over 9 or negative numbers?
The RRF Config said to use X0 if I do not use anything other than a plain switch. If you use RRF to generate a generic profile, it will output M574 x0 y0 z0 s0. Please understand I am not a programmer and there are years of programmers efforts in this mess, it's not like any one took the time to organize this CNC to FDM dogpile of 50 years worth G/M code, and with so many opinions of how the codes should work there are obvious overlapping functions that some respect and others don't. -Understand that M569 P1 S1, M574 X2 Y0 Z0 S0 is one solution to the Inversion issue. It is not the problem. -I never said anything about having trouble homing Y, this is only an issue when the S flag bit is set to 1, on M208, and the X axis bit is set to anything greater than 9. If this is done then other axis develop strange an unexpected behaviors like acting in parallel, or performing logical axis flip flops with each home request.
- Your command "M574 X2 Y0 Z0 S0" says there are no Y or Z endstop switches. So no wonder you can't home Y.
I am sorry, I am not quite sure what you are saying here. But I think this was in response to my comment about flipping the values in the home commands and yes it works fine right now, as described previously.
- The direction of the G1 S1 commands in the homing files and the selection of e.g. X2 vs X1 in the M574 command must be consistent. Please read https://duet3d.dozuki.com/Wiki/ConfiguringRepRapFirmwareCartesianPrinter#Section_Homing_files if you haven't already.
I keep tabs to https://duet3d.dozuki.com/Wiki/Gcode open at all times as reference until this is all wrapped up. I also have the original RepRap wiki book marked as from days passed in learning G-Code.
-
I think there is a misunderstanding between us of the terms "switch", "active high" and "active low".
- Any sort of endstop that detects when a carriage has reached the end if its travel and is connected to an endstop input is a "switch". That includes mechanical switches, optical switches, and Hall effect switches.
- Endstop switches come in two forms: "active high" and "active low". This refers to the logic level at the STP input of the endstop connector. With an active high switch, there is +3.3V on the endstop STP pin when it is triggered, and 0V when it is not triggered. With an active low switch, it's the other way round. There is an LED and pullup resistor between STP and +3.3V. A normally-closed mechanical switch connected between STP and GND produces an active high input. A normally-open mechanical switch connected between STP and GND produces an active low input. The S parameter in the M574 command tells the firmware whether the endstop input is active low (S0) or active high (S1).
- The firmware also needs to know whether each endstop switch is at the low or min end of the axis, or at the high or max end of the axis. For example, X2 means that the X axis has an endstop at the high or max end. Y1 means the Y axis has and endstop at the low or min and. Z0 means the axis has no endstop switch.
So your line M574 X2 Y0 Z0 S0 means that X has an endstop which at the high or max end of the axis (X2) and it is an active-low switch (S0). Y and Z have no endstop switches at all. As you are using normally-open switches, S0 is correct and S1 would be wrong. If you use S1 then the firmware will think that the switch is triggered when it isn't, and vice versa.
More at https://duet3d.dozuki.com/Wiki/Gcode?revisionid=HEAD#Section_M574_Set_endstop_configuration.
HTH David
-
@dc42 said in Laundry List of small Requests:
Thus I have tried to explain what I have as specific as possible. No argument to anything you said other than that i have never set the S flag on M574 to bit 1. -However RRF does, If I try to set this up, Then the bit must be set manually to S0 as the end stops are NOT active. Just mechanical termination.
The only S flag bit 1 I have referred to is on the M208 command. Thus setting the Low values.
- Any sort of endstop that detects when a carriage has reached the end if its travel and is connected to an endstop input is a "switch". That includes mechanical switches, optical switches, and Hall effect switches.
- Endstop switches come in two forms: "active high" and "active low". This refers to the logic level at the STP input of the endstop connector. With an active high switch, there is +3.3V on the endstop STP pin when it is triggered, and 0V when it is not triggered. With an active low switch, it's the other way round. There is an LED and pullup resistor between STP and +3.3V. A normally-closed mechanical switch connected between STP and GND produces an active high input. A normally-open mechanical switch connected between STP and GND produces an active low input. The S parameter in the M574 command tells the firmware whether the endstop input is active low (S0) or active high (S1).
- The firmware also needs to know whether each endstop switch is at the low or min end of the axis, or at the high or max end of the axis. For example, X2 means that the X axis has an endstop at the high or max end. Y1 means the Y axis has and endstop at the low or min and. Z0 means the axis has no endstop switch.
So your line M574 X2 Y0 Z0 S0 means that X has an endstop which at the high or max end of the axis (X2) and it is an active-low switch (S0). Y and Z have no endstop switches at all. As you are using normally-open switches, S0 is correct and S1 would be wrong. If you use S1 then the firmware will think that the switch is triggered when it isn't, and vice versa.
While I consider the issue of How to reverse the Axis closed. I will offer 4 sets of PDF later for examination. They will range from Default config, First functional, Bug expression, and fully calibrated.
All of this above I hope is taken in and apart from all requests for interface changes.
-
@rflulling said in Laundry List of small Requests:
Then the bit must be set manually to S0 as the end stops are NOT active. Just mechanical termination.
Hi,
What do you mean by that?
Frederick
-
Microswitch
This applies to a bare microswitch, not to a microswitch on a board with a LED. Connect the switch between GND and STP (the outer 2 pins of the 3-pin connector). Note: this is not the same as on RAMPS.
We recommend you use the normally-closed contacts of the microswitches, which are generally the outside two connections on the microswitch, and set the signal polarity to active high (S1) in the M574 command. If for any reason you use normally-open microswitch contacts, you will need to set the signal polarity to active low (S0) in the M574 command.
@fcwilt said in Laundry List of small Requests:
@rflulling said in Laundry List of small Requests:
Then the bit must be set manually to S0 as the end stops are NOT active. Just mechanical termination.
Hi,
What do you mean by that?
Frederick
Also this: https://configurator.reprapfirmware.org
Generates the following code. Which incorrectly tells the hardware to expect a circuit.
Unfortunately, there are technically no errors, in the configurator or the code. But the S flag, bit 1 being on sets up the firmware for hardware that doesn't exist. See above on the Microswitch. Below works.
-
Sorry but I don't understand.
You have specified a NC switch on X and that is what the generated code specifies.
Frederick
-
It's ok, I am getting very distinct feeling of you can lead a horse to water, but you cannot make him drink, since coming here. I explain things over and over and more often than not the replies have nothing to do with the concern and more with the confusion of those reading.
Sorry but I don't understand.
For the configuration, the Active high switch must be tagged or the X2 will not be generated. If using the configuration. Simply setting the end stop high only flips the axis in the Home functions. So the solution is to remove the S1 and change it to an S0 as it should be for my configuration. -I did not write any of this code, the firmware, or the configurator. I cannot change how it behaved, only customize the results so that they do what I need.
I am not indulging any one any further on this side topic as it has gone off the rails from the original post regarding the Web Interface.
-
I have built five printers using Duet products and they all work and I never needed any help getting the end stops setup.
You stated "Then the bit must be set manually to S0 as the end stops are NOT active. Just mechanical termination"
Active High/Low in the config tool applies to simple switches. A NC switch is active high. A NO switch is active low.
If you want Active Low you can select it in the config tool.
Frederick
-
I doubt this will be any help but I don't understand either.
I think the issue is that @rflulling is getting confused by axis min (low end) and axis max (high end) with switch type active low and active high. The terms are being used interchangeably by statements like this " Simply setting the end stop high only flips the axis in the Home functions. " ........which makes no sense at all.
@rflulling To recap. X1 will tell the firmware that the switch is physically positioned at the low end of the axis - i.e at or close to Xmin. X2 will tell the firmware that the switch is physically fitted to the high end of the axis - i.e at or close to X max. The S parameter is used to tell the firmware what type of switch it is as DC42 explained above. If the switch type is normally closed and connected as it should be, then use S1. If the switch type is normally open, the use S0.
The type of switch cannot affect the direction of homing but we are all confused because that is what you seem to be implying happens.
Or to put it another way, the configurator and the files in generates work for everyone else so it's hard for us to believe that there is a bug, which is what you are implying.
EDIt. It seems that I was typing this at the same time as @fcwilt so I didn't see his post.
-
@deckingman said in Laundry List of small Requests:
I doubt this will be any help but I don't understand either.
Well that's a relief. I read his posts more than once and simply could not fathom exactly what he was thinking.
I think that this statement he made "Then the bit must be set manually to S0 as the end stops are NOT active. Just mechanical termination" is at the root of the problem.
I would hazard a guess that he is thinking that end stop devices that actually generate a logic level are "active" whereas simple micro switches are not. But, again, that is just a guess.
Frederick
-
@rflulling said in Laundry List of small Requests:
For the configuration, the Active high switch must be tagged or the X2 will not be generated. If using the configuration. Simply setting the end stop high only flips the axis in the Home functions. So the solution is to remove the S1 and change it to an S0 as it should be for my configuration. -I did not write any of this code, the firmware, or the configurator. I cannot change how it behaved, only customize the results so that they do what I need.
I'm sorry, I can't reproduce that. I just set this endstop config:
The configurator generated this in config.g:
; Endstops M574 X2 Y1 Z1 S0 ; Set active low and disabled endstops
Which is correct.
-
OK so just to clarify on the
M574
code because I think there is confusion about the terminology.The
M574
command has two parts. The firstXn Yn Zn
describes the physical location of the end-stops: whether is it at the min or max travel of the axis (or whether it is not installed).The second part,
Sn
, describes the logic level of the end-stop input pin when triggered and is described by the terminology 'active [low/high]' The terminology can be a bit confusing but here is a breakdown for the function of standard microswitch endstops:For a Normally Closed (NC) switch, the circuit is connected through the switch until it is pressed, so it will work as follows:
- When switch is not pressed, STP pin is shorted to GND through the switch, resulting in a STP pin logic state of LOW.
- When switch is pressed during homing, the STP to GND connection is broken, so STP is pulled hi through the pullup resistor. Thus a NC switch will result in an 'active high' (
S1
)signal on the STP pin.
For a Normally Open (NO) switch, the circuit will not be connected until it is pressed:
- When switch is not pressed, STP pin will be pulled HIGH through the pullup resistor.
- When switch is pressed during homing, STP pin will be shorted to GND through the switch, resulting in a STP pin logic level LOW. this is 'active low' (
S0
)
So 'active high' and 'active low' do not refer to which end of the axis the switch is installed on, but rather the logic level of the STP pin when triggered.
So an example config lines might look something like this:
M574 X2 S0
'active low' NO switch connected to X endstop input. X switch is physically installed at the max travel point of the X axis.
M574 Y1 S1
'active high' NC switch conneted to Y endstop input. Y switch is physically installed at the min travel point of the Y axis.
M574 Z0 S0
no 'Z' home switch is installed.We may just be getting the logic level high/low confused with the axis position high/low.
-
@nhof said in Laundry List of small Requests:
..................................We may just be getting the logic level high/low confused with the axis position high/low.
That makes 4 of us who have come to that conclusion.
Ref @rflulling 's quote " I am getting very distinct feeling of you can lead a horse to water, but you cannot make him drink", - I'd be happy to drink if the water was clear, but I'm being led to a muddy puddle
-
@nhof said in Laundry List of small Requests:
We may just be getting the logic level high/low confused with the axis position high/low.
All you posted seems correct but the config tool seems pretty clear to me with the "Endstop Type" and "Endstop Location" headings.
Frederick
-
Thank you for every one trying to understand what I am saying, and over and over coming up with very different solutions to issues I did not request, generating a tangent. I will consider all of your solutions and potentially include them with the guide I am putting together ( will double check to see if they are applicable solutions) Never the less the issue with the inverted axis I was working on is resolved and by no solution provided here. The bug, I am still going to call a bug, can be replicated by any one who stops proving their own solutions to, and inputs the code as I pointed out. Is it really so hard to test? I will even post my entire SD card as very nice and organized PDF that you can copy past into your own Config.g and see how it behaves, assuming you have a physical configuration similar enough that you do not need to make any changes to the test sample. Though honestly I think any one need only input this to see the issue M208 X110 Y0 Z0 S1.
That being said I think at least one reply by DC42 did partially identify why the behavior was as described Topic 3) Thank you.
@dc42 I will also attempt to operate the machine with "M574 X2 Y1 Z1 S0" to test. It runs fine with M574 X2 Y0 Z0 S0, and is currently doing so with S3D over USB2 @ 200% speed with PETG @ 255C and 0.05mm layer height, over USB (using files generated for a Wanhao custom version of Marlin on a Melzi board) on an OEM Duet2Maestro.
I will also look to see if the configuration you screen shot output the same code for me, and follow up. -
@rflulling sorry for getting off topic. I think we all just zero'd in on the end stop description and got hung up on it.
Assume you got the inversion working by inverting motor direction and end-stop location along with relevant homing scripts?
I see your point on the unusual M208 behaviour when given unexpected values. There is recent topic from another user who had the XY axis moving when Z moves were commanded because he had the M208 Ymin value set greater than Ymax (or something like that). A check on the M208 command to ensure that the values given are appropriate might be good.
I'm curious to try the M208 along with the M574 commands tomorrow when I have access to my machines to see what happens.
-
Did a bit of testing this morning on my machines.
I did not see any abnormal motion if the M208 commands are the same value. e.g.
M208 X0:0
. Motion is normal in this case.
I did not see any abnormal motion with M208 command depending on positive or negative values e.g.M208 X-100:-90
,M208 X-500:500
,M208 X-50:-50
. These worked as expected.
I did see abnormal motion with M208 when min value > max value. e.g.M208 X100:0
,M208 X0:-1
,M208 100:-100
etc. Moves after homing in this case will result in hard to predict motion.Motion was not that different with different values for M574 (for me). This could depend on homing scripts but I didn't bother testing any of this.
I also did not see any non-commanded moves on alternate axes (like XY moves when Z move was commanded), but I am using external drivers on drive 5, 6, and 7 for my axes so that may have an impact.
Poking around in the code, it looks like it may be an issue with the end coordinates of a move being re-calculated if the end points of a move fall outside the axis limits, as this will always be the case if the M208 command has been given inverted axis limit values and may result in the end points of moves being offset by the entire axis length in the opposite direction from the expected one.
I still think the best thing to do would be to add input validation on the M208 command. I think it is reasonable to require that the minimum limit is equal or less than the maximum limit.
Here is the file GCodes2.cpp with a little input validation. I don't have the build set up for RRF so I have not compiled or tested this code and it might need refactoring to clean it up, but the idea is there:
case 208: // Set/print maximum axis lengths. If there is an S parameter with value 1 then we set the min value, else we set the max value. { bool setMin = (gb.Seen('S') ? (gb.GetIValue() == 1) : false); bool seen = false; for (size_t axis = 0; axis < numTotalAxes; axis++) { if (gb.Seen(axisLetters[axis])) { float values[2]; size_t numValues = 2; gb.GetFloatArray(values, numValues, false); if (numValues == 2) { if (values[0] > values[1]) { reply.catf("Invalid %c axis limits, min limit cannot be greater than max limit", axisLetters[axis]); result = GCodeResult::error; } else { platform.SetAxisMinimum(axis, values[0], gb.MachineState().runningM501); platform.SetAxisMaximum(axis, values[1], gb.MachineState().runningM501); } } else if (setMin) { if (values[0] > platform.AxisMaximum(axis) { reply.catf("Invalid %c axis limits, min limit cannot be greater than max limit", axisLetters[axis]); result = GCodeResult::error; } else { platform.SetAxisMinimum(axis, values[0], gb.MachineState().runningM501); } } else { if (values[0] < platform.AxisMinimum(axis) { reply.catf("Invalid %c axis limits, min limit cannot be greater than max limit", axisLetters[axis]); result = GCodeResult::error; } else { platform.SetAxisMaximum(axis, values[0], gb.MachineState().runningM501); } } seen = true; } } if (!seen) { reply.copy("Axis limit"); char sep = 's'; for (size_t axis = 0; axis < numTotalAxes; axis++) { reply.catf("%c %c%.1f:%.1f", sep, axisLetters[axis], (double)platform.AxisMinimum(axis), (double)platform.AxisMaximum(axis)); sep = ','; } } } break;
-
@nhof said in Laundry List of small Requests:
I still think the best thing to do would be to add input validation on the M208 command. I think it is reasonable to require that the minimum limit is equal or less than the maximum limit.
Hi,
While this sort of sanity check is doable is this a common enough problem to justify the effort?
Are there other values that should be checked?
Frederick
-
Good question! While it is a fringe case, I think it's worth implementing a check because of the reports of axis motion on other axes than the commanded ones. (XY motion when Z move commanded, etc.)
It is ultimately the responsibility of the user to validate their config inputs, however it's not bad to prevent inputs that would break the system or cause undefined behavior.
I think unless there is both a use case and a standard for inverting axis limits and how the inversion would interact with the rest of the system, we may just want to eliminate the potential problems at the source.
I think more validation is always better to make the system more resilient against faults, with the caveat that it should not take control away from the user. A good example would be how the newer firmware versions require homing before axis movement to prevent damage from over-travel, however the user still has the ability to turn this check off with the M564 command.
Ultimately it's up to David to make the decisions of what to include/change anyway, this is just my opinion.
-
@nhof said in Laundry List of small Requests:
I did see abnormal motion with M208 when min value > max value. e.g. M208 X100:0, M208 X0:-1, M208 100:-100 etc. Moves after homing in this case will result in hard to predict motion.
Thank you, for the effort. I feel like every time I responded to reply one or tried to clarify, the rabbit hole only got longer and further off track from the original issue, and from the original post. It felt like every time I explained the explanation was some how attributed to something else, making me want to forget the post all together.
I honestly just wanted to report some bad behavior as well as make a few requests that seemed reasonable additions. Thank you, @nhof , you took the time to see it for yourself and validate that yes it is there and yes it makes the other axis do unpredictable things. -If requested I would be happy to gather more data in the the possible ways it breaks the code. I had observed more than one kind of bad behavior depending on the settings. But at the core was always that same, any time I input Multiple digits on an Axis of the M208 Command. I did not test to see if this was trickle down, meaning it only effected axis listed after. I did not check to see if I only made Z a high value would X or Y be effected if they were declared first.
I will tell you that the strangest thing i saw was telling X to go home and instead it would produce a behavior something like this. G90 G1 X15 Z25. If I pressed it again it would look like this, G90 G1 X-15 Z25. The result was an odd zigzag as if X was constantly reset. This would go on until Z eventually reached the top, if I kept hitting home.
Another odd one was X would go to the end of the line, without slamming into it, then at X115 gently return at a slower speed to X0 and stop.
The worst were of course, when no mater what was pressed, all axis behaved out order, or as if linked, and no one moved in the right direction despite setting being correct.
M208 X115 S1
, orM208 X-115 S1
, orM208 X10 S1
was called out in all instances, where bad behavior was observed.
-Thus the 1 digit on the S flag, or command M208, any time an axis is given a value greater than 9.
M208 X115 S0
, orM208 X-115 S0
, orM208 X10 S0
, orM208 X0 S0
seem to behave as expected and caused no issues that I know of for certain.