Browse Source

Change how "Stopped" is handled internally, do not inhibit motion

Do not inhibit motion when Stopped is set.

We actually do need to move to move away the extruder from the bed, and
setting Stopped breaks it without adding any sort of security (M*
commands, such as M600 could still perform moves and still pass
through, while M104 would still set heaters).

During a hard error the internal queue is cleared (and sd file closed,
if any), so no new "unforeseen" command can be read.

Handle "Stopped" instead as a flag to inhibit serial processing and
automatically switch to "paused for user" state. While in this state
simply drop any input without incrementing the processed gcode line
number, behaving as-if the last command was still being processed.

This allows "Stopped" to correctly handle a printer-initiated paused
state and recover as expected by requesting a resend when resuming.
Yuri D'Elia 2 năm trước cách đây
mục cha
commit
fc10ca3146
4 tập tin đã thay đổi với 42 bổ sung35 xóa
  1. 16 18
      Firmware/Marlin_main.cpp
  2. 25 15
      Firmware/cmdqueue.cpp
  3. 0 1
      Firmware/cmdqueue.h
  4. 1 1
      Firmware/messages.cpp

+ 16 - 18
Firmware/Marlin_main.cpp

@@ -1843,7 +1843,14 @@ void host_keepalive() {
 // Before loop(), the setup() function is called by the main() routine.
 void loop()
 {
-	KEEPALIVE_STATE(NOT_BUSY);
+    if(Stopped) {
+        // Currently Stopped (possibly due to an error) and not accepting new serial commands.
+        // Signal to the host that we're currently busy waiting for supervision.
+        KEEPALIVE_STATE(PAUSED_FOR_USER);
+    } else {
+        // Printer is available for processing, reset state
+        KEEPALIVE_STATE(NOT_BUSY);
+    }
 
 	if (isPrintPaused && saved_printing_type == PRINTING_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing.
 		usb_timer.start();
@@ -4648,7 +4655,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
     */
     case 0: // G0 -> G1
     case 1: // G1
-      if(Stopped == false) {
+        {
             get_coordinates(); // For X Y Z E F
 
             // When recovering from a previous print move, restore the originally
@@ -4707,7 +4714,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
 	
     */
     case 2: 
-      if(Stopped == false) {
+      {
         get_arc_coordinates();
         prepare_arc_move(true);
       }
@@ -4715,7 +4722,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
  
     // -------------------------------
     case 3: 
-      if(Stopped == false) {
+      {
         get_arc_coordinates();
         prepare_arc_move(false);
       }
@@ -8777,16 +8784,6 @@ Sigma_Exit:
 	}
 	break;
 
-    /*!
-    ### M999 - Restart after being stopped <a href="https://reprap.org/wiki/G-code#M999:_Restart_after_being_stopped_by_error">M999: Restart after being stopped by error</a>
-    @todo Usually doesn't work. Should be fixed or removed. Most of the time, if `Stopped` it set, the print fails and is unrecoverable.
-    */
-    case 999:
-      Stopped = false;
-      lcd_reset_alert_level();
-      gcode_LastN = Stopped_gcode_LastN;
-      FlushSerialRequestResend();
-    break;
 	/*!
 	#### End of M-Commands
     */
@@ -8930,7 +8927,7 @@ Sigma_Exit:
                       active_extruder = tmp_extruder;
                       plan_set_position_curposXYZE();
                       // Move to the old position if 'F' was in the parameters
-                      if (make_move && Stopped == false) {
+                      if (make_move) {
                           prepare_move();
                       }
                   }
@@ -9992,12 +9989,13 @@ void ThermalStop(bool pause)
             // We got a hard thermal error and/or there is no print going on. Just stop.
             lcd_print_stop();
         }
-        Stopped_gcode_LastN = gcode_LastN; // Save last g_code for "restart"
 
-        // Eventually report the stopped status (though this is usually overridden by a
-        // higher-priority alert status message)
+        // Report the status on the serial, switch to a busy state
         SERIAL_ERROR_START;
         SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
+
+        // Eventually report the stopped status on the lcd (though this is usually overridden by a
+        // higher-priority alert status message)
         LCD_MESSAGERPGM(_T(MSG_STOPPED));
 
         Sound_MakeCustom(1000,0,true);

+ 25 - 15
Firmware/cmdqueue.cpp

@@ -28,7 +28,6 @@ ShortTimer serialTimeoutTimer;
 
 long gcode_N = 0;
 long gcode_LastN = 0;
-long Stopped_gcode_LastN = 0;
 
 uint32_t sdpos_atomic = 0;
 
@@ -464,8 +463,6 @@ void get_command()
 
 			  // Don't parse N again with code_seen('N')
 			  cmdbuffer[bufindw + CMDHDRSIZE] = '$';
-			  //if no errors, continue parsing
-			  gcode_LastN = gcode_N;
 		}
         // if we don't receive 'N' but still see '*'
         if ((cmdbuffer[bufindw + CMDHDRSIZE] != 'N') && (cmdbuffer[bufindw + CMDHDRSIZE] != '$') && (strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*') != NULL))
@@ -478,35 +475,48 @@ void get_command()
             serial_count = 0;
             return;
         }
+        // Handle KILL early, even when Stopped
+        if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
+          kill(MSG_M112_KILL, 2);
+        // Handle the USB timer
         if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'G')) != NULL) {
             if (!IS_SD_PRINTING) {
                 usb_timer.start();
             }
-            if (Stopped == true) {
-                if (code_value_uint8() <= 3) {
-                    SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
-                    LCD_MESSAGERPGM(_T(MSG_STOPPED));
-                }
-            }
-        } // end of 'G' command
+        }
+        if (Stopped == true) {
+            // Stopped can be set either during error states (thermal error: cannot continue), or
+            // when a printer-initiated action is processed. In such case the printer will send to
+            // the host an action, but cannot know if the action has been processed while new
+            // commands are being sent. In this situation we just drop the command while issuing
+            // periodic "busy" messages in the main loop. Since we're not incrementing the received
+            // line number, a request for resend will happen (if necessary), ensuring we don't skip
+            // commands whenever Stopped is cleared and processing resumes.
+            serial_count = 0;
+            return;
+        }
+
+        // Command is complete: store the current line into buffer, move to the next line.
 
-        //If command was e-stop process now
-        if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
-          kill(MSG_M112_KILL, 2);
-        
-        // Store the current line into buffer, move to the next line.
 		// Store type of entry
         cmdbuffer[bufindw] = gcode_N ? CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR : CMDBUFFER_CURRENT_TYPE_USB;
+
 #ifdef CMDBUFFER_DEBUG
         SERIAL_ECHO_START;
         SERIAL_ECHOPGM("Storing a command line to buffer: ");
         SERIAL_ECHO(cmdbuffer+bufindw+CMDHDRSIZE);
         SERIAL_ECHOLNPGM("");
 #endif /* CMDBUFFER_DEBUG */
+
+        // Store command itself
         bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
         if (bufindw == sizeof(cmdbuffer))
             bufindw = 0;
         ++ buflen;
+
+        // Update the processed gcode line
+        gcode_LastN = gcode_N;
+
 #ifdef CMDBUFFER_DEBUG
         SERIAL_ECHOPGM("Number of commands in the buffer: ");
         SERIAL_ECHO(buflen);

+ 0 - 1
Firmware/cmdqueue.h

@@ -54,7 +54,6 @@ extern char *strchr_pointer;
 
 extern long gcode_N;
 extern long gcode_LastN;
-extern long Stopped_gcode_LastN;
 
 extern bool cmdqueue_pop_front();
 extern void cmdqueue_reset();

+ 1 - 1
Firmware/messages.cpp

@@ -189,7 +189,7 @@ const char MSG_OK[] PROGMEM_N1 = "ok"; ////
 const char MSG_SD_OPEN_FILE_FAIL[] PROGMEM_N1 = "open failed, File: "; ////
 const char MSG_ENDSTOP_OPEN[] PROGMEM_N1 = "open"; ////
 const char MSG_POWERUP[] PROGMEM_N1 = "PowerUp"; ////
-const char MSG_ERR_STOPPED[] PROGMEM_N1 = "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"; ////
+const char MSG_ERR_STOPPED[] PROGMEM_N1 = "Printer stopped due to errors. Supervision required."; ////
 const char MSG_ENDSTOP_HIT[] PROGMEM_N1 = "TRIGGERED"; ////
 const char MSG_OCTOPRINT_PAUSE[] PROGMEM_N1 = "// action:pause"; ////
 const char MSG_OCTOPRINT_PAUSED[] PROGMEM_N1 = "// action:paused"; ////