I have a Sherline mill with steppers and no encoders (ie. open loop) I am using a probe, and I patched emc2 so that, if the probe trips when in non probe move, emc2 estops, and saves my $120 probe from my fat fingers :)
BUT at each estop, I was loosing steps which I felt was not acceptable. I found that in stepgen, when !enable, the component abruptly stop sending pulses; so I patched stepgen so that an estop respect maxaccel constraints; that worked very well and solved my problem.
Some time ago, I told about that on #emc, but some people there suggested that when driving a 5 ton machine, an estop MUST stop the system ASAP, and anything else is simply not acceptable; which makes sense. So I kept using my patch, and did not published it.
Then, last weekend, I upgraded to 2.1.3 from the CVS; stepgen has changed, so I had to redo the patch in another way. But in the meantime, I digged into HAL (absolutely superb design !!!) and I thought of an acceptable solution:
- Create a HAL bit parameter named "smooth_estop" with a default value of 0 - Change the tests "if(!enable)" to "if(!enable %% !smooth_estop)... else stop smoothly"
- This does not change the behaviour of any .ini or .hal script - This does not change the timing when enabled, and just add a single test when estopped - This allows openloop steppers to ALWAYS keep a valid position; I did some tests, and on my sherline, going from full speed (480 mm/mn) to 0 takes about 0.08 mm, which I think is acceptable. - For activating the mod, there is a single line to add to the .hal file.
- More HAL pins attached to the stepgen module.
- Diluting the meaning of "estop". A ramped stop is not an estop.
- Diluting the meaning of "enable". When you disable something, you make its output zero, now. Not later, not after a ramp, NOW.
- Implementing a generic function (probe protection) in a stepper specific way. Some guy with servos might also want this kind of probe protection - this approach does nothing for him.
Here is another approach that you can do in entirely in HAL, without changing any code, and works equally well for servos and steppers:
Use one mux2 block per axis. The position command from EMC goes to in0 of the mux. The output of the mux goes to stepgen, and to the mux's own in1 input. The select pin of the mux is connected to the "oh-crap" signal from the probe. ("oh-crap" means "probe touched something, but I'm not probing") The "mux with one input connected to the output" is a simple track/hold or latch circuit.
During normal operation, the mux select input is zero, and it faithfully passes the position commands from EMC to the stepgen block (or the PID block if you are running servos). If the probe hits something, the select input becomes a one, and the mux begins reading its own output. That means the command to stepgen freezes in its tracks. When the position command stops changing, stepgen will stop the motor as quickly as possible, while obeying the accel constraints. The stepgen enable would continue to be used for true E-stop, where you absolutely must stop now and reliability is more important than lost steps.
Since the stepgen would stop when the "oh-crap" signal went true, EMC would trip on a following error. When that happens, EMC's position command begins tracking the feedback, so restarting is as simple as turning off the "oh-crap" signal, and jogging away from whatever you ran into.
As an aside:
On a servo system, freezing the position command might even stop the machine faster than disabling the PID and/or the servo amp, since the PID can command negative power, not just zero power. The tradeoff is speed for reliability. For an E-stop, you must cut off power - you can't depend on the PID, since it depends on feedback. Perhaps the reason the user hit estop is because an encoder just died and the motor is running away.... But for probe protection, where a quick stop is the key, freezing the position command will stop either a servo OR a step machine as quickly as possible.