Open blurfl opened 6 years ago
I've been starting to look into this and it seems a little less clear than I thought at first. The issue is that the stop and pause commands only change the machine's behavior temporarily.
If I'm reading it right stop will halt the machine immediately, clear the buffer and then return the machine to the ready position.
Pause does almost nothing, it just tells Ground Control to stop sending more lines and the ones in the buffer finish executing.
Am I missing something? I remember being able to enter a state where the machine would be in a locked state and wouldn't move again until a '~' character was sent. Does anyone remember how or when that state is entered?
UIElements/frontPage.py:259 in the 'Hold' command acts like that:
def pause(self):
if self.holdBtn.secretText == "HOLD":
self.data.uploadFlag = 0
print("Run Paused")
else:
self.data.uploadFlag = 1
self.data.quick_queue.put("~") #send cycle resume command to unpause the machine
print("Run Resumed")
I though the issue was that "stop will halt the machine immediately, clear the buffer and then return the machine to the ready position." isn't what happens.
You may be right that there is another issue with the stop button, the issue I was hoping this would solve is that the machine can get stuck in a 'locked' state where the user is unable to move anything. The closest I've come to finding what is going on is to run this file:
Which just has a tool change in it. During the tool change the machine is in a locked state and cannot be moved with the arrow buttons. The Test Motors/encoders function does not work, but I don't see a tests failed result as described, the test just simply doesn't run until the machine is unpaused
For a second there I thought we had at least three cases of this coming up with the second one being here:
https://forums.maslowcnc.com/t/calibration-motors-wont-move/4988
And the third one in an email which was making me concerned it probably wasn't a hardware thing in the original post like we suspected.
The good news is that I was able to determine that the email issue was caused by not having connected to the machine in Ground Control, and I'm optimistic that a similar solution to the second forums posting can be found so the original issue could still be hardware.
The M1 and M6 gcodes both call pause(). The function pause() function in System.cpp waits for PAUSE_FLAG_USER_PAUSE to go false and either '~' or '!' will do that (Gcode.cpp:50,55), but nothing else that I can see...
I've created #458 to check the sys.pause flag and add it to the message reported from the firmware, do you think this is the right way to achieve what we are trying to do? It doesn't interact with sys.stop, but as far as I can tell sys.stop is only ever true for a few milliseconds
sys.stop gets set to false every time through loop() as far as I can see. But as long as ALARM_POSITION_LIMIT_ERROR is true, sys.top will get set true again by Report.cpp. This logic in returnError() looks like it would do that:
if (!(sys.state & STATE_POS_ERR_IGNORE)) {
if ((abs(leftAxis.error()) >= sysSettings.positionErrorLimit) || (abs(rightAxis.error()) >= sysSettings.positionErrorLimit)) {
reportAlarmMessage(ALARM_POSITION_LIMIT_ERROR);
}
}
You are right, we should report the stop condition too 👍👍 Thanks for pointing that out
Here's the part of grbl's Report.cpp that inserts the machine state into the <…Mpos…Wpos...> message. The PSTRs seem to be the various states. Should we pick the closest one of those for our situation?
switch (sys.state) {
case STATE_IDLE: printPgmString(PSTR("Idle")); break;
case STATE_CYCLE: printPgmString(PSTR("Run")); break;
case STATE_HOLD:
if (!(sys.suspend & SUSPEND_JOG_CANCEL)) {
printPgmString(PSTR("Hold:"));
if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume
else { serial_write('1'); } // Actively holding
break;
} // Continues to print jog state during jog cancel.
case STATE_JOG: printPgmString(PSTR("Jog")); break;
case STATE_HOMING: printPgmString(PSTR("Home")); break;
case STATE_ALARM: printPgmString(PSTR("Alarm")); break;
case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break;
case STATE_SAFETY_DOOR:
printPgmString(PSTR("Door:"));
if (sys.suspend & SUSPEND_INITIATE_RESTORE) {
serial_write('3'); // Restoring
} else {
if (sys.suspend & SUSPEND_RETRACT_COMPLETE) {
if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) {
serial_write('1'); // Door ajar
} else {
serial_write('0');
} // Door closed and ready to resume
} else {
serial_write('2'); // Retracting
}
}
break;
case STATE_SLEEP: printPgmString(PSTR("Sleep")); break;
}
I just added a 'stop' state to the PR, but from looking at that code (thank you) it seems like we should be using 'Hold' as the state for both sys.pause and sys.stop == true. Does that seem right?
From looking at the documentation here I don't see an explicit list of state commands but they are referenced enough for context to explain what they do
'an explicit list of state commands' - I couldn't find one either. I'm happy enough with what you've got already. In our firmware, 'Hold' permits continuing from the present place in a file and 'Stop' is sort of a "clear-and-reset", quite different, and your approach identifies that. 👍🏻 I don't have experience with grbl to know what it's various states mean.
As discussed in this thread, the firmware can signal to GC that it is in the 'Stop' state so the GC can make that known in the GUI.