Merge pull request #4226 from thinkyhead/rc_emergency_command_parser

MarlinSerial emergency-command parser (with M108)
This commit is contained in:
Scott Lahteine 2016-07-07 16:53:55 -07:00 committed by GitHub
commit 98d0167a57
29 changed files with 294 additions and 56 deletions

View file

@ -284,6 +284,12 @@
#define HardwareSerial_h // trick to disable the standard HWserial
#endif
#if ENABLED(EMERGENCY_PARSER)
#define EMERGENCY_PARSER_CAPABILITIES " EMERGENCY_CODES:M108,M112,M410"
#else
#define EMERGENCY_PARSER_CAPABILITIES ""
#endif
#include "Arduino.h"
/**

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -230,9 +230,7 @@ void ok_to_send();
void reset_bed_level();
void kill(const char*);
#if DISABLED(DELTA) && DISABLED(SCARA)
void set_current_position_from_planner();
#endif
void quickstop_stepper();
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
void handle_filament_runout();
@ -288,6 +286,7 @@ extern float sw_endstop_min[3]; // axis[n].sw_endstop_min
extern float sw_endstop_max[3]; // axis[n].sw_endstop_max
extern bool axis_known_position[3]; // axis[n].is_known
extern bool axis_homed[3]; // axis[n].is_homed
extern volatile bool wait_for_heatup;
// GCode support for external objects
bool code_seen(char);

View file

@ -30,6 +30,7 @@
#include "Marlin.h"
#include "MarlinSerial.h"
#include "stepper.h"
#ifndef USBCON
// this next line disables the entire HardwareSerial.cpp,
@ -54,6 +55,10 @@ FORCE_INLINE void store_char(unsigned char c) {
rx_buffer.head = i;
}
CRITICAL_SECTION_END;
#if ENABLED(EMERGENCY_PARSER)
emergency_parser(c);
#endif
}
@ -310,3 +315,104 @@ MarlinSerial customizedSerial;
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;
#endif
#if ENABLED(EMERGENCY_PARSER)
// Currently looking for: M108, M112, M410
// If you alter the parser please don't forget to update the capabilities in Conditionals.h
void emergency_parser(unsigned char c) {
enum e_parser_state {
state_RESET,
state_N,
state_M,
state_M1,
state_M10,
state_M108,
state_M11,
state_M112,
state_M4,
state_M41,
state_M410,
state_IGNORE // to '\n'
};
static e_parser_state state = state_RESET;
switch (state) {
case state_RESET:
switch (c) {
case ' ': break;
case 'N': state = state_N; break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_N:
switch (c) {
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9': case '-': case ' ': break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_M:
switch (c) {
case ' ': break;
case '1': state = state_M1; break;
case '4': state = state_M4; break;
default: state = state_IGNORE;
}
break;
case state_M1:
switch (c) {
case '0': state = state_M10; break;
case '1': state = state_M11; break;
default: state = state_IGNORE;
}
break;
case state_M10:
state = (c == '8') ? state_M108 : state_IGNORE;
break;
case state_M11:
state = (c == '2') ? state_M112 : state_IGNORE;
break;
case state_M4:
state = (c == '1') ? state_M41 : state_IGNORE;
break;
case state_M41:
state = (c == '0') ? state_M410 : state_IGNORE;
break;
case state_IGNORE:
if (c == '\n') state = state_RESET;
break;
default:
if (c == '\n') {
switch (state) {
case state_M108:
wait_for_heatup = false;
break;
case state_M112:
kill(PSTR(MSG_KILLED));
break;
case state_M410:
quickstop_stepper();
break;
}
state = state_RESET;
}
}
}
#endif

View file

@ -101,6 +101,11 @@ struct ring_buffer {
extern ring_buffer rx_buffer;
#endif
#if ENABLED(EMERGENCY_PARSER)
#include "language.h"
void emergency_parser(unsigned char c);
#endif
class MarlinSerial { //: public Stream
public:
@ -141,6 +146,10 @@ class MarlinSerial { //: public Stream
rx_buffer.head = i;
}
CRITICAL_SECTION_END;
#if ENABLED(EMERGENCY_PARSER)
emergency_parser(c);
#endif
}
}

View file

@ -160,7 +160,7 @@
* M105 - Read current temp
* M106 - Fan on
* M107 - Fan off
* M108 - Cancel heatup and wait for the hotend and bed, this G-code is asynchronously handled in the get_serial_commands() parser
* M108 - Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
* M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
* Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
* IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
@ -332,7 +332,7 @@ uint8_t active_extruder = 0;
// Relative Mode. Enable with G91, disable with G90.
static bool relative_mode = false;
bool wait_for_heatup = true;
volatile bool wait_for_heatup = true;
const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:";
@ -1105,9 +1105,12 @@ inline void get_serial_commands() {
}
}
#if DISABLED(EMERGENCY_PARSER)
// If command was e-stop process now
if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
if (strcmp(command, "M108") == 0) wait_for_heatup = false;
if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
if (strcmp(command, "M410") == 0) { quickstop_stepper(); }
#endif
#if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0
last_command_time = ms;
@ -4535,10 +4538,29 @@ inline void gcode_M105() {
#endif // FAN_COUNT > 0
/**
* M108: Cancel heatup and wait for the hotend and bed, this G-code is asynchronously handled in the get_serial_commands() parser
#if DISABLED(EMERGENCY_PARSER)
/**
* M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
*/
inline void gcode_M108() { wait_for_heatup = false; }
inline void gcode_M108() { wait_for_heatup = false; }
/**
* M112: Emergency Stop
*/
inline void gcode_M112() { kill(PSTR(MSG_KILLED)); }
/**
* M410: Quickstop - Abort all planned moves
*
* This will stop the carriages mid-move, so most likely they
* will be out of sync with the stepper position after this.
*/
inline void gcode_M410() { quickstop_stepper(); }
#endif
/**
* M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating.
@ -4810,11 +4832,6 @@ inline void gcode_M111() {
SERIAL_EOL;
}
/**
* M112: Emergency Stop
*/
inline void gcode_M112() { kill(PSTR(MSG_KILLED)); }
#if ENABLED(HOST_KEEPALIVE_FEATURE)
/**
@ -5970,8 +5987,9 @@ inline void gcode_M400() { stepper.synchronize(); }
#endif // FILAMENT_WIDTH_SENSOR
#if DISABLED(DELTA) && DISABLED(SCARA)
void set_current_position_from_planner() {
void quickstop_stepper() {
stepper.quick_stop();
#if DISABLED(DELTA) && DISABLED(SCARA)
stepper.synchronize();
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
vector_3 pos = planner.adjusted_position(); // values directly from steppers...
@ -5984,23 +6002,9 @@ inline void gcode_M400() { stepper.synchronize(); }
current_position[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS);
#endif
sync_plan_position(); // ...re-apply to planner position
}
#endif
/**
* M410: Quickstop - Abort all planned moves
*
* This will stop the carriages mid-move, so most likely they
* will be out of sync with the stepper position after this.
*/
inline void gcode_M410() {
stepper.quick_stop();
#if DISABLED(DELTA) && DISABLED(SCARA)
set_current_position_from_planner();
#endif
}
#if ENABLED(MESH_BED_LEVELING)
/**
@ -6955,10 +6959,22 @@ void process_next_command() {
gcode_M111();
break;
#if DISABLED(EMERGENCY_PARSER)
case 108: // M108: Cancel Waiting
gcode_M108();
break;
case 112: // M112: Emergency Stop
gcode_M112();
break;
case 410: // M410 quickstop - Abort all the planned moves.
gcode_M410();
break;
#endif
#if ENABLED(HOST_KEEPALIVE_FEATURE)
case 113: // M113: Set Host Keepalive interval
@ -6976,10 +6992,6 @@ void process_next_command() {
KEEPALIVE_STATE(NOT_BUSY);
return; // "ok" already printed
case 108:
gcode_M108();
break;
case 109: // M109: Wait for temperature
gcode_M109();
break;
@ -7263,10 +7275,6 @@ void process_next_command() {
break;
#endif // ENABLED(FILAMENT_WIDTH_SENSOR)
case 410: // M410 quickstop - Abort all the planned moves.
gcode_M410();
break;
#if ENABLED(MESH_BED_LEVELING)
case 420: // M420 Enable/Disable Mesh Bed Leveling
gcode_M420();

View file

@ -579,6 +579,13 @@
#endif
/**
* emergency-command parser
*/
#if ENABLED(EMERGENCY_PARSER) && ENABLED(USBCON)
#error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
#endif
/**
* Warnings for old configurations
*/
#if WATCH_TEMP_PERIOD > 500

View file

@ -186,10 +186,7 @@ void Endstops::report_state() {
if (stepper.abort_on_endstop_hit) {
card.sdprinting = false;
card.closefile();
stepper.quick_stop();
#if DISABLED(DELTA) && DISABLED(SCARA)
set_current_position_from_planner();
#endif
quickstop_stepper();
thermalManager.disable_all_heaters(); // switch off all heaters.
}
#endif

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -526,6 +526,12 @@ const unsigned int dropsegments = 2; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 26
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 8
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -528,6 +528,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -522,6 +522,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -522,6 +522,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -521,6 +521,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -526,6 +526,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -522,6 +522,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -520,6 +520,12 @@ const unsigned int dropsegments = 5; //everything with less than this number of
#define MAX_CMD_SIZE 96
#define BUFSIZE 4
// Enable an emergency-command parser to intercept certain commands as they
// enter the serial receive buffer, so they cannot be blocked.
// Currently handles M108, M112, M410
// Does not work on boards using AT90USB (USBCON) processors!
//#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.

View file

@ -128,7 +128,7 @@
#define MSG_INVALID_EXTRUDER "Invalid extruder"
#define MSG_INVALID_SOLENOID "Invalid solenoid"
#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature"
#define MSG_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
#define MSG_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID EMERGENCY_PARSER_CAPABILITIES "\n"
#define MSG_COUNT_X " Count X: "
#define MSG_COUNT_A " Count A: "
#define MSG_ERR_KILLED "Printer halted. kill() called!"

View file

@ -238,8 +238,10 @@ unsigned char Temperature::soft_pwm[HOTENDS];
soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
#endif
wait_for_heatup = true;
// PID Tuning loop
for (;;) {
while (wait_for_heatup) {
millis_t ms = millis();
@ -421,6 +423,7 @@ unsigned char Temperature::soft_pwm[HOTENDS];
}
lcd_update();
}
if (!wait_for_heatup) disable_all_heaters();
}
#endif // HAS_PID_HEATING

View file

@ -556,14 +556,11 @@ static void lcd_status_screen() {
static void lcd_sdcard_stop() {
card.stopSDPrint();
clear_command_queue();
stepper.quick_stop();
quickstop_stepper();
print_job_timer.stop();
thermalManager.autotempShutdown();
wait_for_heatup = false;
lcd_setstatus(MSG_PRINT_ABORTED, true);
#if DISABLED(DELTA) && DISABLED(SCARA)
set_current_position_from_planner();
#endif // !DELTA && !SCARA
}
#endif //SDSUPPORT

View file

@ -95,8 +95,6 @@
extern int absPreheatHPBTemp;
extern int absPreheatFanSpeed;
extern bool wait_for_heatup;
#if ENABLED(FILAMENT_LCD_DISPLAY)
extern millis_t previous_lcd_status_ms;
#endif