From 0e19f1e583439c454014f42937f70e6309c3c7a5 Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Thu, 29 Oct 2020 09:25:33 -1000 Subject: [PATCH] Added $A AKA Alarms/List command (#654) * Added $A AKA Alarms/List command Similar to $E AKA Errors/List $E used to be AKA ErrorCodes/List Also added $Errors/Verbose setting to display full error text instead of the error number. It defaults to true because it works with every sender I have tried so far - cncjs, UGS, and Chrome GCode Sender. If you have problems with some sender you can set it to false. * Added static_assert per atlaste's comment * Added a default and fixed Authentication issue Co-authored-by: bdring --- Grbl_Esp32/src/Defaults.h | 4 ++ Grbl_Esp32/src/Error.cpp | 2 +- Grbl_Esp32/src/Error.h | 2 +- Grbl_Esp32/src/Exec.cpp | 15 +++++++ Grbl_Esp32/src/Exec.h | 57 ++++++++++++++++++++++++++ Grbl_Esp32/src/ProcessSettings.cpp | 43 ++++++++++++++++--- Grbl_Esp32/src/Report.cpp | 9 +++- Grbl_Esp32/src/SettingsDefinitions.cpp | 4 ++ Grbl_Esp32/src/SettingsDefinitions.h | 2 + Grbl_Esp32/src/System.h | 53 ++---------------------- Grbl_Esp32/src/WebUI/WebSettings.cpp | 10 ++--- 11 files changed, 137 insertions(+), 64 deletions(-) create mode 100644 Grbl_Esp32/src/Exec.cpp create mode 100644 Grbl_Esp32/src/Exec.h diff --git a/Grbl_Esp32/src/Defaults.h b/Grbl_Esp32/src/Defaults.h index 42d7d9b9..6ca3728c 100644 --- a/Grbl_Esp32/src/Defaults.h +++ b/Grbl_Esp32/src/Defaults.h @@ -70,6 +70,10 @@ # define DEFAULT_STATUS_REPORT_MASK 1 // $10 #endif +#ifndef DEFAULT_VERBOSE_ERRORS +# define DEFAULT_VERBOSE_ERRORS 0 +#endif + #ifndef DEFAULT_JUNCTION_DEVIATION # define DEFAULT_JUNCTION_DEVIATION 0.01 // $11 mm #endif diff --git a/Grbl_Esp32/src/Error.cpp b/Grbl_Esp32/src/Error.cpp index e7fa5de6..149b0665 100644 --- a/Grbl_Esp32/src/Error.cpp +++ b/Grbl_Esp32/src/Error.cpp @@ -21,7 +21,7 @@ #include "Error.h" -std::map ErrorCodes = { +std::map ErrorNames = { { Error::Ok, "No error" }, { Error::ExpectedCommandLetter, "Expected GCodecommand letter" }, { Error::BadNumberFormat, "Bad GCode number format" }, diff --git a/Grbl_Esp32/src/Error.h b/Grbl_Esp32/src/Error.h index cfc2b379..09a54030 100644 --- a/Grbl_Esp32/src/Error.h +++ b/Grbl_Esp32/src/Error.h @@ -85,4 +85,4 @@ enum class Error : uint8_t { Eol = 111, }; -extern std::map ErrorCodes; +extern std::map ErrorNames; diff --git a/Grbl_Esp32/src/Exec.cpp b/Grbl_Esp32/src/Exec.cpp new file mode 100644 index 00000000..3cba113d --- /dev/null +++ b/Grbl_Esp32/src/Exec.cpp @@ -0,0 +1,15 @@ +#include "Exec.h" + +std::map AlarmNames = { + { ExecAlarm::None, "None"}, + { ExecAlarm::HardLimit, "Hard Limit"}, + { ExecAlarm::SoftLimit, "Soft Limit"}, + { ExecAlarm::AbortCycle, "Abort Cycle"}, + { ExecAlarm::ProbeFailInitial, "Probe Fail Initial"}, + { ExecAlarm::ProbeFailContact, "Probe Fail Contact"}, + { ExecAlarm::HomingFailReset, "Homing Fail Reset"}, + { ExecAlarm::HomingFailDoor, "Homing Fail Door"}, + { ExecAlarm::HomingFailPulloff, "Homing Fail Pulloff"}, + { ExecAlarm::HomingFailApproach, "Homing Fail Approach"}, + { ExecAlarm::SpindleControl, "Spindle Control"}, +}; diff --git a/Grbl_Esp32/src/Exec.h b/Grbl_Esp32/src/Exec.h new file mode 100644 index 00000000..23d7110d --- /dev/null +++ b/Grbl_Esp32/src/Exec.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +// System executor bit map. Used internally by realtime protocol as realtime command flags, +// which notifies the main program to execute the specified realtime command asynchronously. +// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default +// flags are always false, so the realtime protocol only needs to check for a non-zero value to +// know when there is a realtime command to execute. +struct ExecStateBits { + uint8_t statusReport : 1; + uint8_t cycleStart : 1; + uint8_t cycleStop : 1; // Unused, per cycle_stop variable + uint8_t feedHold : 1; + uint8_t reset : 1; + uint8_t safetyDoor : 1; + uint8_t motionCancel : 1; + uint8_t sleep : 1; +}; + +union ExecState { + uint8_t value; + ExecStateBits bit; +}; + +static_assert(sizeof(ExecStateBits) == sizeof(uint8_t), "ExecStateBits is not an uint8"); + +// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides. +// Spindle/coolant and feed/rapids are separated into two controlling flag variables. + +struct ExecAccessoryBits { + uint8_t spindleOvrStop : 1; + uint8_t coolantFloodOvrToggle : 1; + uint8_t coolantMistOvrToggle : 1; +}; + +union ExecAccessory { + uint8_t value; + ExecAccessoryBits bit; +}; + +// Alarm codes. +enum class ExecAlarm : uint8_t { + None = 0, + HardLimit = 1, + SoftLimit = 2, + AbortCycle = 3, + ProbeFailInitial = 4, + ProbeFailContact = 5, + HomingFailReset = 6, + HomingFailDoor = 7, + HomingFailPulloff = 8, + HomingFailApproach = 9, + SpindleControl = 10, +}; + +extern std::map AlarmNames; diff --git a/Grbl_Esp32/src/ProcessSettings.cpp b/Grbl_Esp32/src/ProcessSettings.cpp index 57744e65..7e13ab83 100644 --- a/Grbl_Esp32/src/ProcessSettings.cpp +++ b/Grbl_Esp32/src/ProcessSettings.cpp @@ -325,12 +325,42 @@ Error doJog(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESP return gc_execute_line(jogLine, out->client()); } -const char* errorString(Error errorNumber) { - auto it = ErrorCodes.find(errorNumber); - return it == ErrorCodes.end() ? NULL : it->second; +const char* alarmString(ExecAlarm alarmNumber) { + auto it = AlarmNames.find(alarmNumber); + return it == AlarmNames.end() ? NULL : it->second; } -Error listErrorCodes(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { +Error listAlarms(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { + if (value) { + char* endptr = NULL; + uint8_t alarmNumber = strtol(value, &endptr, 10); + if (*endptr) { + grbl_sendf(out->client(), "Malformed alarm number: %s\r\n", value); + return Error::InvalidValue; + } + const char* alarmName = alarmString(static_cast(alarmNumber)); + if (alarmName) { + grbl_sendf(out->client(), "%d: %s\r\n", alarmNumber, alarmName); + return Error::Ok; + } else { + grbl_sendf(out->client(), "Unknown alarm number: %d\r\n", alarmNumber); + return Error::InvalidValue; + } + } + + for (auto it = AlarmNames.begin(); it != AlarmNames.end(); it++) { + grbl_sendf(out->client(), "%d: %s\r\n", it->first, it->second); + } + return Error::Ok; +} + + +const char* errorString(Error errorNumber) { + auto it = ErrorNames.find(errorNumber); + return it == ErrorNames.end() ? NULL : it->second; +} + +Error listErrors(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { if (value) { char* endptr = NULL; uint8_t errorNumber = strtol(value, &endptr, 10); @@ -348,7 +378,7 @@ Error listErrorCodes(const char* value, WebUI::AuthenticationLevel auth_level, W } } - for (auto it = ErrorCodes.begin(); it != ErrorCodes.end(); it++) { + for (auto it = ErrorNames.begin(); it != ErrorNames.end(); it++) { grbl_sendf(out->client(), "%d: %s\r\n", it->first, it->second); } return Error::Ok; @@ -383,7 +413,8 @@ void make_grbl_commands() { new GrblCommand("S", "Settings/List", list_settings, notCycleOrHold); new GrblCommand("SC", "Settings/ListChanged", list_changed_settings, notCycleOrHold); new GrblCommand("CMD", "Commands/List", list_commands, notCycleOrHold); - new GrblCommand("E", "ErrorCodes/List", listErrorCodes, anyState); + new GrblCommand("A", "Alarms/List", listAlarms, anyState); + new GrblCommand("E", "Errors/List", listErrors, anyState); new GrblCommand("G", "GCode/Modes", report_gcode, anyState); new GrblCommand("C", "GCode/Check", toggle_check_mode, anyState); new GrblCommand("X", "Alarm/Disable", disable_alarm_lock, anyState); diff --git a/Grbl_Esp32/src/Report.cpp b/Grbl_Esp32/src/Report.cpp index a7dda585..20cff520 100644 --- a/Grbl_Esp32/src/Report.cpp +++ b/Grbl_Esp32/src/Report.cpp @@ -247,7 +247,14 @@ void report_status_message(Error status_code, uint8_t client) { return; } #endif - grbl_sendf(client, "error:%d\r\n", static_cast(status_code)); + // With verbose errors, the message text is displayed instead of the number. + // Grbl 0.9 used to display the text, while Grbl 1.1 switched to the number. + // Many senders support both formats. + if (verbose_errors->get()) { + grbl_sendf(client, "error: %s\r\n", errorString(status_code)); + } else { + grbl_sendf(client, "error:%d\r\n", static_cast(status_code)); + } } } diff --git a/Grbl_Esp32/src/SettingsDefinitions.cpp b/Grbl_Esp32/src/SettingsDefinitions.cpp index 53a561e8..5e2c2e2c 100644 --- a/Grbl_Esp32/src/SettingsDefinitions.cpp +++ b/Grbl_Esp32/src/SettingsDefinitions.cpp @@ -2,6 +2,8 @@ bool motorSettingChanged = false; +FlagSetting* verbose_errors; + FakeSetting* number_axis; StringSetting* startup_line_0; @@ -237,6 +239,8 @@ void make_settings() { make_coordinate(CoordIndex::G28, "G28"); make_coordinate(CoordIndex::G30, "G30"); + verbose_errors = new FlagSetting(EXTENDED, WG, NULL, "Errors/Verbose", DEFAULT_VERBOSE_ERRORS); + // number_axis = new IntSetting(EXTENDED, WG, NULL, "NumberAxis", N_AXIS, 0, 6, NULL, true); number_axis = new FakeSetting(N_AXIS); diff --git a/Grbl_Esp32/src/SettingsDefinitions.h b/Grbl_Esp32/src/SettingsDefinitions.h index 0fd68b33..b01038bf 100644 --- a/Grbl_Esp32/src/SettingsDefinitions.h +++ b/Grbl_Esp32/src/SettingsDefinitions.h @@ -2,6 +2,8 @@ extern bool motorSettingChanged; +extern FlagSetting* verbose_errors; + extern FakeSetting* number_axis; extern AxisSettings* x_axis_settings; diff --git a/Grbl_Esp32/src/System.h b/Grbl_Esp32/src/System.h index d416511a..6803f7e2 100644 --- a/Grbl_Esp32/src/System.h +++ b/Grbl_Esp32/src/System.h @@ -20,6 +20,9 @@ along with Grbl. If not, see . */ +// Execution states and alarm +#include "Exec.h" + // System states. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for // critical events. @@ -107,56 +110,6 @@ typedef struct { } system_t; extern system_t sys; -// System executor bit map. Used internally by realtime protocol as realtime command flags, -// which notifies the main program to execute the specified realtime command asynchronously. -// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default -// flags are always false, so the realtime protocol only needs to check for a non-zero value to -// know when there is a realtime command to execute. -struct ExecStateBits { - uint8_t statusReport : 1; - uint8_t cycleStart : 1; - uint8_t cycleStop : 1; // Unused, per cycle_stop variable - uint8_t feedHold : 1; - uint8_t reset : 1; - uint8_t safetyDoor : 1; - uint8_t motionCancel : 1; - uint8_t sleep : 1; -}; - -union ExecState { - uint8_t value; - ExecStateBits bit; -}; - -// Alarm executor codes. Valid values (1-255). Zero is reserved. -enum class ExecAlarm : uint8_t { - None = 0, - HardLimit = 1, - SoftLimit = 2, - AbortCycle = 3, - ProbeFailInitial = 4, - ProbeFailContact = 5, - HomingFailReset = 6, - HomingFailDoor = 7, - HomingFailPulloff = 8, - HomingFailApproach = 9, - SpindleControl = 10, -}; - -// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides. -// Spindle/coolant and feed/rapids are separated into two controlling flag variables. - -struct ExecAccessoryBits { - uint8_t spindleOvrStop : 1; - uint8_t coolantFloodOvrToggle : 1; - uint8_t coolantMistOvrToggle : 1; -}; - -union ExecAccessory { - uint8_t value; - ExecAccessoryBits bit; -}; - // Control pin states struct ControlPinBits { uint8_t safetyDoor : 1; diff --git a/Grbl_Esp32/src/WebUI/WebSettings.cpp b/Grbl_Esp32/src/WebUI/WebSettings.cpp index 09539a77..b9a34b8c 100644 --- a/Grbl_Esp32/src/WebUI/WebSettings.cpp +++ b/Grbl_Esp32/src/WebUI/WebSettings.cpp @@ -306,9 +306,9 @@ namespace WebUI { return Error::SdFailedOpenFile; } //until no line in file - Error err; - Error accumErr = Error::Ok; - uint8_t client = (espresponse) ? espresponse->client() : CLIENT_ALL; + Error err; + Error accumErr = Error::Ok; + uint8_t client = (espresponse) ? espresponse->client() : CLIENT_ALL; while (currentfile.available()) { String currentline = currentfile.readStringUntil('\n'); if (currentline.length() > 0) { @@ -398,7 +398,7 @@ namespace WebUI { user_password->setDefault(); return Error::Ok; } - if (user_password->setStringValue(parameter)) { + if (user_password->setStringValue(parameter) != Error::Ok) { webPrintln("Invalid Password"); return Error::InvalidValue; } @@ -730,7 +730,7 @@ namespace WebUI { webPrintln(""); return Error::Ok; } - SD_client = (espresponse) ? espresponse->client() : CLIENT_ALL; + SD_client = (espresponse) ? espresponse->client() : CLIENT_ALL; SD_auth_level = auth_level; // execute the first line now; Protocol.cpp handles later ones when SD_ready_next report_status_message(execute_line(fileLine, SD_client, SD_auth_level), SD_client);