mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-09-01 18:32:37 +02:00
Added better error reporting for incorrect configs. Added ConfigAlarm state, which you can't get out off so easily - but you are still able to upload, use files, etc.
This commit is contained in:
@@ -71,12 +71,14 @@ void grbl_init() {
|
|||||||
|
|
||||||
machine_init(); // user supplied function for special initialization
|
machine_init(); // user supplied function for special initialization
|
||||||
// Initialize system state.
|
// Initialize system state.
|
||||||
|
if (sys.state != State::ConfigAlarm) {
|
||||||
#ifdef FORCE_INITIALIZATION_ALARM
|
#ifdef FORCE_INITIALIZATION_ALARM
|
||||||
// Force Grbl into an ALARM state upon a power-cycle or hard reset.
|
// Force Grbl into an ALARM state upon a power-cycle or hard reset.
|
||||||
sys.state = State::Alarm;
|
sys.state = State::Alarm;
|
||||||
#else
|
#else
|
||||||
sys.state = State::Idle;
|
sys.state = State::Idle;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
// Check for power-up and set system alarm if homing is enabled to force homing cycle
|
// Check for power-up and set system alarm if homing is enabled to force homing cycle
|
||||||
// by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
|
// by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
|
||||||
// startup scripts, but allows access to settings and internal commands. Only a homing
|
// startup scripts, but allows access to settings and internal commands. Only a homing
|
||||||
@@ -84,7 +86,7 @@ void grbl_init() {
|
|||||||
// NOTE: The startup script will run after successful completion of the homing cycle, but
|
// NOTE: The startup script will run after successful completion of the homing cycle, but
|
||||||
// not after disabling the alarm locks. Prevents motion startup blocks from crashing into
|
// not after disabling the alarm locks. Prevents motion startup blocks from crashing into
|
||||||
// things uncontrollably. Very bad.
|
// things uncontrollably. Very bad.
|
||||||
if (config->_homingInitLock && homingAxes()) {
|
if (config->_homingInitLock && homingAxes() && sys.state != State::ConfigAlarm) {
|
||||||
// If there is an axis with homing configured, enter Alarm state on startup
|
// If there is an axis with homing configured, enter Alarm state on startup
|
||||||
sys.state = State::Alarm;
|
sys.state = State::Alarm;
|
||||||
}
|
}
|
||||||
@@ -108,6 +110,7 @@ void grbl_init() {
|
|||||||
} catch (const AssertionFailed& ex) {
|
} catch (const AssertionFailed& ex) {
|
||||||
// This means something is terribly broken:
|
// This means something is terribly broken:
|
||||||
info_serial("Critical error in run_once: %s", ex.what());
|
info_serial("Critical error in run_once: %s", ex.what());
|
||||||
|
sys.state = State::ConfigAlarm;
|
||||||
sleep(10000);
|
sleep(10000);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ void IRAM_ATTR isr_limit_switches(void* /*unused */) {
|
|||||||
// moves in the planner and serial buffers are all cleared and newly sent blocks will be
|
// moves in the planner and serial buffers are all cleared and newly sent blocks will be
|
||||||
// locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
|
// locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
|
||||||
// limit setting if their limits are constantly triggering after a reset and move their axes.
|
// limit setting if their limits are constantly triggering after a reset and move their axes.
|
||||||
if (sys.state != State::Alarm && sys.state != State::Homing) {
|
if (sys.state != State::Alarm && sys.state != State::ConfigAlarm && sys.state != State::Homing) {
|
||||||
if (sys_rt_exec_alarm == ExecAlarm::None) {
|
if (sys_rt_exec_alarm == ExecAlarm::None) {
|
||||||
#ifdef ENABLE_SOFTWARE_DEBOUNCE
|
#ifdef ENABLE_SOFTWARE_DEBOUNCE
|
||||||
// we will start a task that will recheck the switches after a small delay
|
// we will start a task that will recheck the switches after a small delay
|
||||||
|
@@ -570,18 +570,22 @@ bool MachineConfig::load(const char* filename) {
|
|||||||
// That way, we can always check if the yaml is there, and if it's not, load the yaml.new.
|
// That way, we can always check if the yaml is there, and if it's not, load the yaml.new.
|
||||||
|
|
||||||
} catch (const Configuration::ParseException& ex) {
|
} catch (const Configuration::ParseException& ex) {
|
||||||
|
sys.state = State::ConfigAlarm;
|
||||||
auto startNear = ex.Near();
|
auto startNear = ex.Near();
|
||||||
auto endNear = (startNear + 10) > (buffer + filesize) ? (buffer + filesize) : (startNear + 10);
|
auto endNear = (startNear + 10) > (buffer + filesize) ? (buffer + filesize) : (startNear + 10);
|
||||||
|
|
||||||
StringRange near(startNear, endNear);
|
StringRange near(startNear, endNear);
|
||||||
log_error("Configuration parse error: " << ex.What() << " @ " << ex.LineNumber() << ":" << ex.ColumnNumber() << " near " << near);
|
log_error("Configuration parse error: " << ex.What() << " @ " << ex.LineNumber() << ":" << ex.ColumnNumber() << " near " << near);
|
||||||
} catch (const AssertionFailed& ex) {
|
} catch (const AssertionFailed& ex) {
|
||||||
|
sys.state = State::ConfigAlarm;
|
||||||
// Get rid of buffer and return
|
// Get rid of buffer and return
|
||||||
log_error("Configuration loading failed: " << ex.what());
|
log_error("Configuration loading failed: " << ex.what());
|
||||||
} catch (std::exception& ex) {
|
} catch (std::exception& ex) {
|
||||||
|
sys.state = State::ConfigAlarm;
|
||||||
// Log exception:
|
// Log exception:
|
||||||
log_error("Configuration validation error: " << ex.what());
|
log_error("Configuration validation error: " << ex.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
sys.state = State::ConfigAlarm;
|
||||||
// Get rid of buffer and return
|
// Get rid of buffer and return
|
||||||
log_error("Unknown error while processing config file");
|
log_error("Unknown error while processing config file");
|
||||||
}
|
}
|
||||||
|
@@ -321,7 +321,7 @@ public:
|
|||||||
class MachineConfig : public Configuration::Configurable {
|
class MachineConfig : public Configuration::Configurable {
|
||||||
public:
|
public:
|
||||||
MachineConfig() = default;
|
MachineConfig() = default;
|
||||||
|
|
||||||
Axes* _axes = nullptr;
|
Axes* _axes = nullptr;
|
||||||
SPIBus* _spi = nullptr;
|
SPIBus* _spi = nullptr;
|
||||||
I2SOBus* _i2so = nullptr;
|
I2SOBus* _i2so = nullptr;
|
||||||
|
@@ -20,8 +20,6 @@
|
|||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
// #define false 0
|
// #define false 0
|
||||||
// #define true 1
|
// #define true 1
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Pins::PinDetail* Pin::undefinedPin = new Pins::VoidPinDetail();
|
Pins::PinDetail* Pin::undefinedPin = new Pins::VoidPinDetail();
|
||||||
Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail();
|
Pins::PinDetail* Pin::errorPin = new Pins::ErrorPinDetail("unknown");
|
||||||
|
|
||||||
bool Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) {
|
bool Pin::parse(StringRange tmp, Pins::PinDetail*& pinImplementation) {
|
||||||
String str = tmp.str();
|
String str = tmp.str();
|
||||||
@@ -151,7 +151,7 @@ Pin Pin::create(const StringRange& str) {
|
|||||||
pin_error("Setting up pin [%s] failed. Details: %s\r\n", str.str().c_str(), ex.what());
|
pin_error("Setting up pin [%s] failed. Details: %s\r\n", str.str().c_str(), ex.what());
|
||||||
(void)ex; // Get rid of compiler warning
|
(void)ex; // Get rid of compiler warning
|
||||||
|
|
||||||
return Pin(pinImplementation);
|
return Pin(new Pins::ErrorPinDetail(str.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,15 +19,30 @@
|
|||||||
#include "ErrorPinDetail.h"
|
#include "ErrorPinDetail.h"
|
||||||
#include "../Assert.h"
|
#include "../Assert.h"
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#include "../Report.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Pins {
|
namespace Pins {
|
||||||
ErrorPinDetail::ErrorPinDetail() : PinDetail(0) {}
|
ErrorPinDetail::ErrorPinDetail(const String& descr) : PinDetail(0), _description(descr) {}
|
||||||
|
|
||||||
PinCapabilities ErrorPinDetail::capabilities() const { return PinCapabilities::Error; }
|
PinCapabilities ErrorPinDetail::capabilities() const { return PinCapabilities::Error; }
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
void ErrorPinDetail::write(int high) { info_all("Cannot write to pin %s. The config is incorrect.", _description.c_str()); }
|
||||||
|
int ErrorPinDetail::read() { info_all("Cannot read from pin %s. The config is incorrect.", _description.c_str()); }
|
||||||
|
void ErrorPinDetail::setAttr(PinAttributes value) {
|
||||||
|
info_all("Cannot set mode on pin %s. The config is incorrect.", _description.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
void ErrorPinDetail::write(int high) { Assert(false, "Cannot write to an error pin."); }
|
void ErrorPinDetail::write(int high) { Assert(false, "Cannot write to an error pin."); }
|
||||||
int ErrorPinDetail::read() { Assert(false, "Cannot read from an error pin."); }
|
int ErrorPinDetail::read() { Assert(false, "Cannot read from an error pin."); }
|
||||||
void ErrorPinDetail::setAttr(PinAttributes value) { /* Fine, this won't get you anywhere. */
|
void ErrorPinDetail::setAttr(PinAttributes value) { /* Fine, this won't get you anywhere. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
PinAttributes ErrorPinDetail::getAttr() const { return PinAttributes::None; }
|
PinAttributes ErrorPinDetail::getAttr() const { return PinAttributes::None; }
|
||||||
|
|
||||||
String ErrorPinDetail::toString() { return "ERROR_PIN"; }
|
String ErrorPinDetail::toString() { return "ERROR_PIN"; }
|
||||||
|
@@ -23,8 +23,10 @@
|
|||||||
|
|
||||||
namespace Pins {
|
namespace Pins {
|
||||||
class ErrorPinDetail : public PinDetail {
|
class ErrorPinDetail : public PinDetail {
|
||||||
|
String _description;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ErrorPinDetail();
|
ErrorPinDetail(const String& descr);
|
||||||
|
|
||||||
PinCapabilities capabilities() const override;
|
PinCapabilities capabilities() const override;
|
||||||
|
|
||||||
|
@@ -87,7 +87,7 @@ Error execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_l
|
|||||||
return system_execute_line(line, client, auth_level);
|
return system_execute_line(line, client, auth_level);
|
||||||
}
|
}
|
||||||
// Everything else is gcode. Block if in alarm or jog mode.
|
// Everything else is gcode. Block if in alarm or jog mode.
|
||||||
if (sys.state == State::Alarm || sys.state == State::Jog) {
|
if (sys.state == State::Alarm || sys.state == State::ConfigAlarm || sys.state == State::Jog) {
|
||||||
return Error::SystemGcLock;
|
return Error::SystemGcLock;
|
||||||
}
|
}
|
||||||
return gc_execute_line(line, client);
|
return gc_execute_line(line, client);
|
||||||
@@ -137,7 +137,9 @@ void protocol_main_loop() {
|
|||||||
// Check for and report alarm state after a reset, error, or an initial power up.
|
// Check for and report alarm state after a reset, error, or an initial power up.
|
||||||
// NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed.
|
// NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed.
|
||||||
// Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges.
|
// Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges.
|
||||||
if (sys.state == State::Alarm || sys.state == State::Sleep) {
|
if (sys.state == State::ConfigAlarm) {
|
||||||
|
report_feedback_message(Message::AlarmLock);
|
||||||
|
} else if (sys.state == State::Alarm || sys.state == State::Sleep) {
|
||||||
report_feedback_message(Message::AlarmLock);
|
report_feedback_message(Message::AlarmLock);
|
||||||
sys.state = State::Alarm; // Ensure alarm state is set.
|
sys.state = State::Alarm; // Ensure alarm state is set.
|
||||||
} else {
|
} else {
|
||||||
@@ -325,6 +327,7 @@ static void protocol_do_motion_cancel() {
|
|||||||
// will handle and clear multiple planner block motions.
|
// will handle and clear multiple planner block motions.
|
||||||
switch (sys.state) {
|
switch (sys.state) {
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
return; // Do not set motionCancel
|
return; // Do not set motionCancel
|
||||||
|
|
||||||
@@ -356,6 +359,7 @@ static void protocol_do_feedhold() {
|
|||||||
rtFeedHold = false;
|
rtFeedHold = false;
|
||||||
rtCycleStart = false; // Cancel any pending start
|
rtCycleStart = false; // Cancel any pending start
|
||||||
switch (sys.state) {
|
switch (sys.state) {
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
case State::SafetyDoor:
|
case State::SafetyDoor:
|
||||||
@@ -390,6 +394,8 @@ static void protocol_do_safety_door() {
|
|||||||
rtCycleStart = false; // Cancel any pending start
|
rtCycleStart = false; // Cancel any pending start
|
||||||
report_feedback_message(Message::SafetyDoorAjar);
|
report_feedback_message(Message::SafetyDoorAjar);
|
||||||
switch (sys.state) {
|
switch (sys.state) {
|
||||||
|
case State::ConfigAlarm:
|
||||||
|
return;
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
case State::Sleep:
|
case State::Sleep:
|
||||||
@@ -443,6 +449,7 @@ static void protocol_do_safety_door() {
|
|||||||
static void protocol_do_sleep() {
|
static void protocol_do_sleep() {
|
||||||
rtSleep = false;
|
rtSleep = false;
|
||||||
switch (sys.state) {
|
switch (sys.state) {
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
sys.suspend.bit.retractComplete = true;
|
sys.suspend.bit.retractComplete = true;
|
||||||
sys.suspend.bit.holdComplete = true;
|
sys.suspend.bit.holdComplete = true;
|
||||||
@@ -518,6 +525,7 @@ static void protocol_do_cycle_start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
case State::Sleep:
|
case State::Sleep:
|
||||||
@@ -552,6 +560,7 @@ static void protocol_do_cycle_stop() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fall through
|
// Fall through
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
case State::Idle:
|
case State::Idle:
|
||||||
@@ -686,6 +695,7 @@ void protocol_exec_rt_system() {
|
|||||||
#endif
|
#endif
|
||||||
// Reload step segment buffer
|
// Reload step segment buffer
|
||||||
switch (sys.state) {
|
switch (sys.state) {
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
case State::CheckMode:
|
case State::CheckMode:
|
||||||
case State::Idle:
|
case State::Idle:
|
||||||
|
@@ -858,6 +858,7 @@ char* report_state_text() {
|
|||||||
case State::Homing:
|
case State::Homing:
|
||||||
strcpy(state, "Home");
|
strcpy(state, "Home");
|
||||||
break;
|
break;
|
||||||
|
case State::ConfigAlarm:
|
||||||
case State::Alarm:
|
case State::Alarm:
|
||||||
strcpy(state, "Alarm");
|
strcpy(state, "Alarm");
|
||||||
break;
|
break;
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Error.h"
|
#include "Error.h"
|
||||||
|
#include "NutsBolts.h"
|
||||||
|
#include "Exec.h"
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Report.h - Header for system level commands and real-time processes
|
Report.h - Header for system level commands and real-time processes
|
||||||
|
@@ -40,6 +40,7 @@ enum class State : uint8_t {
|
|||||||
Jog, // Jogging mode.
|
Jog, // Jogging mode.
|
||||||
SafetyDoor, // Safety door is ajar. Feed holds and de-energizes system.
|
SafetyDoor, // Safety door is ajar. Feed holds and de-energizes system.
|
||||||
Sleep, // Sleep state.
|
Sleep, // Sleep state.
|
||||||
|
ConfigAlarm, // You can't do anything but fix your config file.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step segment generator state flags.
|
// Step segment generator state flags.
|
||||||
|
@@ -678,7 +678,7 @@ namespace WebUI {
|
|||||||
|
|
||||||
static Error runSDFile(char* parameter, AuthenticationLevel auth_level) { // ESP220
|
static Error runSDFile(char* parameter, AuthenticationLevel auth_level) { // ESP220
|
||||||
Error err;
|
Error err;
|
||||||
if (sys.state == State::Alarm) {
|
if (sys.state == State::Alarm || sys.state == State::ConfigAlarm) {
|
||||||
webPrintln("Alarm");
|
webPrintln("Alarm");
|
||||||
return Error::IdleError;
|
return Error::IdleError;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user