Send a Busy signal to hosts during long processes, wait for input, etc

If Marlin is blocking the serial input or command queue for any length
of time (for example more than 2 seconds), it needs to send a message
to serial out to inform the host that it is busy. Marlin should only
send these messages out when busy, and preferably not when trying to
print formatted output.
This commit is contained in:
Scott Lahteine 2016-03-07 03:48:14 -08:00
parent 7d25c107a8
commit 7ec7bb31c4
22 changed files with 234 additions and 3 deletions

View File

@ -314,6 +314,13 @@
#define Z_SAFE_HOMING #define Z_SAFE_HOMING
#endif #endif
/**
* Avoid double-negatives for enabling features
*/
#if DISABLED(DISABLE_HOST_KEEPALIVE)
#define HOST_KEEPALIVE_FEATURE
#endif
/** /**
* MAX_STEP_FREQUENCY differs for TOSHIBA * MAX_STEP_FREQUENCY differs for TOSHIBA
*/ */

View File

@ -646,6 +646,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -426,6 +426,26 @@ static uint8_t target_extruder;
int lpq_len = 20; int lpq_len = 20;
#endif #endif
#if ENABLED(HOST_KEEPALIVE_FEATURE)
// States for managing Marlin and host communication
// Marlin sends messages if blocked or busy
enum MarlinBusyState {
NOT_BUSY, // Not in a handler
IN_HANDLER, // Processing a GCode
IN_PROCESS, // Known to be blocking command input (as in G29)
PAUSED_FOR_USER, // Blocking pending any input
PAUSED_FOR_INPUT // Blocking pending text input (concept)
};
static MarlinBusyState busy_state = NOT_BUSY;
static millis_t next_busy_signal_ms = -1;
#define KEEPALIVE_STATE(n) do{ busy_state = n; }while(0)
#else
#define host_keepalive() ;
#define KEEPALIVE_STATE(n) ;
#endif // HOST_KEEPALIVE_FEATURE
//=========================================================================== //===========================================================================
//================================ Functions ================================ //================================ Functions ================================
//=========================================================================== //===========================================================================
@ -2130,6 +2150,35 @@ void unknown_command_error() {
SERIAL_ECHOPGM("\"\n"); SERIAL_ECHOPGM("\"\n");
} }
#if ENABLED(HOST_KEEPALIVE_FEATURE)
void host_keepalive() {
millis_t ms = millis();
if (busy_state != NOT_BUSY) {
if (ms < next_busy_signal_ms) return;
switch (busy_state) {
case NOT_BUSY:
break;
case IN_HANDLER:
case IN_PROCESS:
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_BUSY_PROCESSING);
break;
case PAUSED_FOR_USER:
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_USER);
break;
case PAUSED_FOR_INPUT:
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_INPUT);
break;
}
}
next_busy_signal_ms = ms + 2000UL;
}
#endif //HOST_KEEPALIVE_FEATURE
/** /**
* G0, G1: Coordinated movement of X Y Z E axes * G0, G1: Coordinated movement of X Y Z E axes
*/ */
@ -3219,6 +3268,8 @@ inline void gcode_G28() {
st_synchronize(); st_synchronize();
#endif #endif
KEEPALIVE_STATE(IN_HANDLER);
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (marlin_debug_flags & DEBUG_LEVELING) { if (marlin_debug_flags & DEBUG_LEVELING) {
SERIAL_ECHOLNPGM("<<< gcode_G29"); SERIAL_ECHOLNPGM("<<< gcode_G29");
@ -3325,12 +3376,16 @@ inline void gcode_G92() {
refresh_cmd_timeout(); refresh_cmd_timeout();
if (codenum > 0) { if (codenum > 0) {
codenum += previous_cmd_ms; // wait until this time for a click codenum += previous_cmd_ms; // wait until this time for a click
KEEPALIVE_STATE(PAUSED_FOR_USER);
while (millis() < codenum && !lcd_clicked()) idle(); while (millis() < codenum && !lcd_clicked()) idle();
KEEPALIVE_STATE(IN_HANDLER);
lcd_ignore_click(false); lcd_ignore_click(false);
} }
else { else {
if (!lcd_detected()) return; if (!lcd_detected()) return;
KEEPALIVE_STATE(PAUSED_FOR_USER);
while (!lcd_clicked()) idle(); while (!lcd_clicked()) idle();
KEEPALIVE_STATE(IN_HANDLER);
} }
if (IS_SD_PRINTING) if (IS_SD_PRINTING)
LCD_MESSAGEPGM(MSG_RESUMING); LCD_MESSAGEPGM(MSG_RESUMING);
@ -4963,6 +5018,8 @@ inline void gcode_M303() {
if (e >=0 && e < EXTRUDERS) if (e >=0 && e < EXTRUDERS)
target_extruder = e; target_extruder = e;
KEEPALIVE_STATE(NOT_BUSY);
PID_autotune(temp, e, c); PID_autotune(temp, e, c);
} }
@ -5334,6 +5391,13 @@ inline void gcode_M503() {
#if ENABLED(FILAMENTCHANGEENABLE) #if ENABLED(FILAMENTCHANGEENABLE)
inline void idle2() {
manage_heater();
manage_inactivity(true);
host_keepalive();
lcd_update();
}
/** /**
* M600: Pause for filament change * M600: Pause for filament change
* *
@ -5412,6 +5476,7 @@ inline void gcode_M503() {
delay(100); delay(100);
LCD_ALERTMESSAGEPGM(MSG_FILAMENTCHANGE); LCD_ALERTMESSAGEPGM(MSG_FILAMENTCHANGE);
millis_t next_tick = 0; millis_t next_tick = 0;
KEEPALIVE_STATE(WAIT_FOR_USER);
while (!lcd_clicked()) { while (!lcd_clicked()) {
#if DISABLED(AUTO_FILAMENT_CHANGE) #if DISABLED(AUTO_FILAMENT_CHANGE)
millis_t ms = millis(); millis_t ms = millis();
@ -5419,9 +5484,7 @@ inline void gcode_M503() {
lcd_quick_feedback(); lcd_quick_feedback();
next_tick = ms + 2500; // feedback every 2.5s while waiting next_tick = ms + 2500; // feedback every 2.5s while waiting
} }
manage_heater(); idle2();
manage_inactivity(true);
lcd_update();
#else #else
current_position[E_AXIS] += AUTO_FILAMENT_CHANGE_LENGTH; current_position[E_AXIS] += AUTO_FILAMENT_CHANGE_LENGTH;
destination[E_AXIS] = current_position[E_AXIS]; destination[E_AXIS] = current_position[E_AXIS];
@ -5429,6 +5492,7 @@ inline void gcode_M503() {
st_synchronize(); st_synchronize();
#endif #endif
} // while(!lcd_clicked) } // while(!lcd_clicked)
KEEPALIVE_STATE(IN_HANDLER);
lcd_quick_feedback(); // click sound feedback lcd_quick_feedback(); // click sound feedback
#if ENABLED(AUTO_FILAMENT_CHANGE) #if ENABLED(AUTO_FILAMENT_CHANGE)
@ -5765,6 +5829,8 @@ void process_next_command() {
seen_pointer = current_command; seen_pointer = current_command;
codenum = code_value_short(); codenum = code_value_short();
KEEPALIVE_STATE(IN_HANDLER);
// Handle a known G, M, or T // Handle a known G, M, or T
switch (command_code) { switch (command_code) {
case 'G': switch (codenum) { case 'G': switch (codenum) {
@ -6286,6 +6352,8 @@ void process_next_command() {
default: code_is_good = false; default: code_is_good = false;
} }
KEEPALIVE_STATE(NOT_BUSY);
ExitUnknownCommand: ExitUnknownCommand:
// Still unknown command? Throw an error // Still unknown command? Throw an error
@ -6975,6 +7043,7 @@ void disable_all_steppers() {
void idle() { void idle() {
manage_heater(); manage_heater();
manage_inactivity(); manage_inactivity();
host_keepalive();
lcd_update(); lcd_update();
} }

View File

@ -629,6 +629,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -626,6 +626,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -638,6 +638,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -641,6 +641,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -661,6 +661,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -646,6 +646,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -641,6 +641,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -654,6 +654,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -666,6 +666,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -638,6 +638,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -646,6 +646,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -768,6 +768,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -768,6 +768,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -772,6 +772,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -763,6 +763,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -682,6 +682,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -649,6 +649,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -640,6 +640,14 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define EEPROM_CHITCHAT // Please keep turned on if you can. #define EEPROM_CHITCHAT // Please keep turned on if you can.
#endif #endif
//
// Host Keepalive
//
// By default Marlin will send a busy status message to the host
// every 2 seconds when it can't accept commands.
//
//#define DISABLE_HOST_KEEPALIVE // Enable this option if your host doesn't like keepalive messages.
// //
// M100 Free Memory Watcher // M100 Free Memory Watcher
// //

View File

@ -124,6 +124,9 @@
#define MSG_COUNT_A " Count A: " #define MSG_COUNT_A " Count A: "
#define MSG_ERR_KILLED "Printer halted. kill() called!" #define MSG_ERR_KILLED "Printer halted. kill() called!"
#define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" #define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define MSG_BUSY_PROCESSING "busy: processing"
#define MSG_BUSY_PAUSED_FOR_USER "busy: paused for user"
#define MSG_BUSY_PAUSED_FOR_INPUT "busy: paused for input"
#define MSG_RESEND "Resend: " #define MSG_RESEND "Resend: "
#define MSG_UNKNOWN_COMMAND "Unknown command: \"" #define MSG_UNKNOWN_COMMAND "Unknown command: \""
#define MSG_ACTIVE_EXTRUDER "Active Extruder: " #define MSG_ACTIVE_EXTRUDER "Active Extruder: "