Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realtime Reporting and S000, P000, R000 #19330

Merged
merged 13 commits into from
Apr 16, 2021
Merged
9 changes: 9 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2115,6 +2115,15 @@
*/
//#define EMERGENCY_PARSER

/**
* Realtime Reporting
* Add support for commands S000 State, P000 Pause, and R000 Resume
*/
//#define REALTIME_REPORTING_COMMANDS
#if ENABLED(REALTIME_REPORTING_COMMANDS)
//#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC
#endif

// 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'.
Expand Down
134 changes: 76 additions & 58 deletions Marlin/src/feature/e_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,33 @@
// External references
extern bool wait_for_user, wait_for_heatup;

#if ENABLED(REALTIME_REPORTING_COMMANDS)
// From motion.h, which cannot be included here
void report_current_position_moving();
void quickpause_stepper();
void quickresume_stepper();
#endif

class EmergencyParser {

public:

// Currently looking for: M108, M112, M410, M876
enum State : char {
// Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000
enum State : uint8_t {
EP_RESET,
EP_N,
EP_M,
EP_M1,
EP_M10,
EP_M108,
EP_M11,
EP_M112,
EP_M4,
EP_M41,
EP_M410,
EP_M10, EP_M108,
EP_M11, EP_M112,
EP_M4, EP_M41, EP_M410,
#if ENABLED(HOST_PROMPT_SUPPORT)
EP_M8,
EP_M87,
EP_M876,
EP_M876S,
EP_M876SN,
EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
#endif
#if ENABLED(REALTIME_REPORTING_COMMANDS)
EP_S, EP_S0, EP_S00, EP_GRBL_STATUS,
EP_R, EP_R0, EP_R00, EP_GRBL_RESUME,
EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE,
#endif
EP_IGNORE // to '\n'
};
Expand All @@ -71,29 +75,52 @@ class EmergencyParser {
EmergencyParser() { enable(); }

FORCE_INLINE static void enable() { enabled = true; }

FORCE_INLINE static void disable() { enabled = false; }

FORCE_INLINE static void update(State &state, const uint8_t c) {
switch (state) {
case EP_RESET:
switch (c) {
case ' ': case '\n': case '\r': break;
case 'N': state = EP_N; break;
case 'M': state = EP_M; break;
default: state = EP_IGNORE;
case 'N': state = EP_N; break;
case 'M': state = EP_M; break;
#if ENABLED(REALTIME_REPORTING_COMMANDS)
case 'S': state = EP_S; break;
case 'P': state = EP_P; break;
case 'R': state = EP_R; break;
#endif
default: state = EP_IGNORE;
}
break;

case EP_N:
switch (c) {
case '0' ... '9':
case '-': case ' ': break;
case 'M': state = EP_M; break;
default: state = EP_IGNORE;
case '-': case ' ': break;
case 'M': state = EP_M; break;
#if ENABLED(REALTIME_REPORTING_COMMANDS)
case 'S': state = EP_S; break;
case 'P': state = EP_P; break;
case 'R': state = EP_R; break;
#endif
default: state = EP_IGNORE;
}
break;

#if ENABLED(REALTIME_REPORTING_COMMANDS)
case EP_S: state = (c == '0') ? EP_S0 : EP_IGNORE; break;
case EP_S0: state = (c == '0') ? EP_S00 : EP_IGNORE; break;
case EP_S00: state = (c == '0') ? EP_GRBL_STATUS : EP_IGNORE; break;

case EP_R: state = (c == '0') ? EP_R0 : EP_IGNORE; break;
case EP_R0: state = (c == '0') ? EP_R00 : EP_IGNORE; break;
case EP_R00: state = (c == '0') ? EP_GRBL_RESUME : EP_IGNORE; break;

case EP_P: state = (c == '0') ? EP_P0 : EP_IGNORE; break;
case EP_P0: state = (c == '0') ? EP_P00 : EP_IGNORE; break;
case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break;
#endif

case EP_M:
switch (c) {
case ' ': break;
Expand All @@ -114,48 +141,34 @@ class EmergencyParser {
}
break;

case EP_M10:
state = (c == '8') ? EP_M108 : EP_IGNORE;
break;

case EP_M11:
state = (c == '2') ? EP_M112 : EP_IGNORE;
break;

case EP_M4:
state = (c == '1') ? EP_M41 : EP_IGNORE;
break;

case EP_M41:
state = (c == '0') ? EP_M410 : EP_IGNORE;
break;
case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break;
case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break;
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;

#if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M8:
state = (c == '7') ? EP_M87 : EP_IGNORE;
break;

case EP_M87:
state = (c == '6') ? EP_M876 : EP_IGNORE;
break;
case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break;
case EP_M87: state = (c == '6') ? EP_M876 : EP_IGNORE; break;

case EP_M876:
switch (c) {
case ' ': break;
case 'S': state = EP_M876S; break;
default: state = EP_IGNORE; break;
}
break;
case EP_M876:
switch (c) {
case ' ': break;
case 'S': state = EP_M876S; break;
default: state = EP_IGNORE; break;
}
break;

case EP_M876S:
switch (c) {
case ' ': break;
case '0' ... '9':
state = EP_M876SN;
M876_reason = uint8_t(c - '0');
break;
}
break;

case EP_M876S:
switch (c) {
case ' ': break;
case '0' ... '9':
state = EP_M876SN;
M876_reason = (uint8_t)(c - '0');
break;
}
break;
#endif

case EP_IGNORE:
Expand All @@ -171,6 +184,11 @@ class EmergencyParser {
#if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M876SN: host_response_handler(M876_reason); break;
#endif
#if ENABLED(REALTIME_REPORTING_COMMANDS)
case EP_GRBL_STATUS: report_current_position_moving(); break;
case EP_GRBL_PAUSE: quickpause_stepper(); break;
case EP_GRBL_RESUME: quickresume_stepper(); break;
#endif
default: break;
}
state = EP_RESET;
Expand Down
5 changes: 4 additions & 1 deletion Marlin/src/gcode/bedlevel/abl/G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ class G29_State {
* There's no extra effect if you have a fixed Z probe.
*/
G29_TYPE GcodeSuite::G29() {

TERN_(PROBE_MANUALLY, static) G29_State abl;

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));

reset_stepper_timeout();

const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen('Q');
Expand Down Expand Up @@ -897,6 +898,8 @@ G29_TYPE GcodeSuite::G29() {

report_current_position();

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));

G29_RETURN(ISNAN(abl.measured_z));
}

Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/gcode/bedlevel/mbl/G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
*/
void GcodeSuite::G29() {

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));

static int mbl_probe_index = -1;

MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
Expand Down Expand Up @@ -187,6 +189,8 @@ void GcodeSuite::G29() {
}

report_current_position();

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
}

#endif // MESH_BED_LEVELING
13 changes: 12 additions & 1 deletion Marlin/src/gcode/bedlevel/ubl/G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@
#include "../../gcode.h"
#include "../../../feature/bedlevel/bedlevel.h"

void GcodeSuite::G29() { ubl.G29(); }
#if ENABLED(FULL_REPORT_TO_HOST_FEATURE)
#include "../../../module/motion.h"
#endif

void GcodeSuite::G29() {

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));

ubl.G29();

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
}

#endif // AUTO_BED_LEVELING_UBL
4 changes: 4 additions & 0 deletions Marlin/src/gcode/calibrate/G28.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ void GcodeSuite::G28() {

TERN_(LASER_MOVE_G28_OFF, cutter.set_inline_enabled(false)); // turn off laser

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOMING));

#if ENABLED(DUAL_X_CARRIAGE)
bool IDEX_saved_duplication_state = extruder_duplication_enabled;
DualXMode IDEX_saved_mode = dual_x_carriage_mode;
Expand Down Expand Up @@ -479,6 +481,8 @@ void GcodeSuite::G28() {
if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS)))
SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));

#if HAS_L64XX
// Set L6470 absolute position registers to counts
// constexpr *might* move this to PROGMEM.
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/gcode/calibrate/G33.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ static float auto_tune_a() {
*/
void GcodeSuite::G33() {

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));

const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS);
if (!WITHIN(probe_points, 0, 10)) {
SERIAL_ECHOLNPGM("?(P)oints implausible (0-10).");
Expand Down Expand Up @@ -645,6 +647,8 @@ void GcodeSuite::G33() {
while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision);

ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
}

#endif // DELTA_AUTO_CALIBRATION
11 changes: 10 additions & 1 deletion Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
}
#endif

// Handle a known G, M, or T
// Handle a known command or reply "unknown command"

switch (parser.command_letter) {

case 'G': switch (parser.codenum) {

case 0: case 1: // G0: Fast Move, G1: Linear Move
Expand Down Expand Up @@ -995,6 +997,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 'D': D(parser.codenum); break; // Dn: Debug codes
#endif

#if ENABLED(REALTIME_REPORTING_COMMANDS)
case 'S': case 'P': case 'R': break; // Invalid S, P, R commands already filtered
#endif

default:
#if ENABLED(WIFI_CUSTOM_COMMAND)
if (wifi_custom_command(parser.command_ptr)) break;
Expand Down Expand Up @@ -1087,12 +1093,15 @@ void GcodeSuite::process_subcommands_now(char * gcode) {
case IN_HANDLER:
case IN_PROCESS:
SERIAL_ECHO_MSG(STR_BUSY_PROCESSING);
TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_position_moving());
break;
case PAUSED_FOR_USER:
SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER);
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD));
break;
case PAUSED_FOR_INPUT:
SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_INPUT);
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD));
break;
default:
break;
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/gcode/host/M114.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@
const xyze_float_t diff = from_steppers - leveled;
SERIAL_ECHOPGM("Diff: ");
report_xyze(diff);

TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
}

#endif // M114_DETAIL
Expand Down Expand Up @@ -211,4 +213,6 @@ void GcodeSuite::M114() {

TERN_(M114_LEGACY, planner.synchronize());
report_current_position_projected();

TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
}
4 changes: 4 additions & 0 deletions Marlin/src/gcode/motion/G0_G1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
| (parser.seen('Z') ? _BV(Z_AXIS) : 0) )
#endif
) {
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));

#ifdef G0_FEEDRATE
feedRate_t old_feedrate;
Expand Down Expand Up @@ -116,6 +117,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
planner.synchronize();
SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
}
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
#else
TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
#endif
}
}
4 changes: 4 additions & 0 deletions Marlin/src/gcode/motion/G2_G3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ void plan_arc(
void GcodeSuite::G2_G3(const bool clockwise) {
if (MOTION_CONDITIONS) {

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));

#if ENABLED(SF_ARC_FIX)
const bool relative_mode_backup = relative_mode;
relative_mode = true;
Expand Down Expand Up @@ -364,6 +366,8 @@ void GcodeSuite::G2_G3(const bool clockwise) {
}
else
SERIAL_ERROR_MSG(STR_ERR_ARC_ARGS);

TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
}
}

Expand Down
Loading