mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-30 01:30:05 +02:00
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 <barton.dring@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "Error.h"
|
||||
|
||||
std::map<Error, const char*> ErrorCodes = {
|
||||
std::map<Error, const char*> ErrorNames = {
|
||||
{ Error::Ok, "No error" },
|
||||
{ Error::ExpectedCommandLetter, "Expected GCodecommand letter" },
|
||||
{ Error::BadNumberFormat, "Bad GCode number format" },
|
||||
|
@@ -85,4 +85,4 @@ enum class Error : uint8_t {
|
||||
Eol = 111,
|
||||
};
|
||||
|
||||
extern std::map<Error, const char*> ErrorCodes;
|
||||
extern std::map<Error, const char*> ErrorNames;
|
||||
|
15
Grbl_Esp32/src/Exec.cpp
Normal file
15
Grbl_Esp32/src/Exec.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "Exec.h"
|
||||
|
||||
std::map<ExecAlarm, const char*> 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"},
|
||||
};
|
57
Grbl_Esp32/src/Exec.h
Normal file
57
Grbl_Esp32/src/Exec.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
// 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<ExecAlarm, const char*> AlarmNames;
|
@@ -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<ExecAlarm>(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);
|
||||
|
@@ -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<int>(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<int>(status_code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
bool motorSettingChanged = false;
|
||||
|
||||
FlagSetting* verbose_errors;
|
||||
|
||||
FakeSetting<int>* 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<int>(N_AXIS);
|
||||
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
extern bool motorSettingChanged;
|
||||
|
||||
extern FlagSetting* verbose_errors;
|
||||
|
||||
extern FakeSetting<int>* number_axis;
|
||||
|
||||
extern AxisSettings* x_axis_settings;
|
||||
|
@@ -20,6 +20,9 @@
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// 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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user