Skip to content

Commit

Permalink
Devt (#618)
Browse files Browse the repository at this point in the history
* Fixed various small bugs (#605)

* Fixed various small bugs

* Fixed potential cast bug

* Fixed double reporting of errors

Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>

* Stallguard tuning (#607)

* Devt (#571)

* Handles Tranimic drivers errors better

- If an unsupported driver is specified, it will give a message and not crash.

* Cleaned up unused files

Got rid of old unipolar files
Got rid of servo axis feature - it is a motor class now
Got rid of solenoid pen feature - never really used and it should be a motor class if it is.

* Fix ENABLE_AUTHENTICATION (#569)

* Fixed authentication code.

* Removed another const cast

Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>

* Fix step leakage with inverted steps (#570)

* Fix step leakage with inverted steps

* Update build date for merge

Co-authored-by: Bart Dring <bdring@buildlog.net>

Co-authored-by: Stefan de Bruijn <atlaste@users.noreply.github.com>
Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>
Co-authored-by: Mitch Bradley <wmb@firmworks.com>
Co-authored-by: Bart Dring <bdring@buildlog.net>

* Update platformio.ini

Per PR 583

* Created an enum for mode

* Removing some unused machine defs

* Added test machine definition

* Clean up for PR

* Remove test machine def.

Co-authored-by: Stefan de Bruijn <atlaste@users.noreply.github.com>
Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>
Co-authored-by: Mitch Bradley <wmb@firmworks.com>
Co-authored-by: Bart Dring <bdring@buildlog.net>

* Basic testing Complete

* Made state variable volatile.

* Homing cycle settings (#613)

* Initial Tests Complete

* Update Grbl.h

* Update variables

Co-authored-by: Mitch Bradley <wmb@firmworks.com>

* fixed dual switches when inverted (#614)

* fixed dual switches when inverted

* Removed debug message

* Cleaning up the machine defs

Removed unused #defines.

* Store coordinate offsets in NVS (#611)

* Store coordinate offsets in NVS

* Handle both old Eeprom formats

* Implementing fixes (#616)

- Stop creating additional tasks when limit_init() gets called again from homing and resets
- Explicitly delete an object that was causing a memory loss.

* Update Grbl.h

* Tweak memory fix and add $H check for $Homing/Cycles

Co-authored-by: Stefan de Bruijn <atlaste@users.noreply.github.com>
Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>
Co-authored-by: Mitch Bradley <wmb@firmworks.com>
Co-authored-by: Bart Dring <bdring@buildlog.net>
  • Loading branch information
5 people authored Sep 28, 2020
1 parent da1d6b8 commit d0acc9b
Show file tree
Hide file tree
Showing 30 changed files with 357 additions and 349 deletions.
28 changes: 1 addition & 27 deletions Grbl_Esp32/src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,7 @@ Some features should not be changed. See notes below.
// machine.h is #included below, after some definitions
// that the machine file might choose to undefine.

// Define the homing cycle patterns with bitmasks. The homing cycle first performs a search mode
// to quickly engage the limit switches, followed by a slower locate mode, and finished by a short
// pull-off motion to disengage the limit switches. The following HOMING_CYCLE_x defines are executed
// in order starting with suffix 0 and completes the homing routine for the specified-axes only. If
// an axis is omitted from the defines, it will not home, nor will the system update its position.
// Meaning that this allows for users with non-standard Cartesian machines, such as a lathe (x then z,
// with no y), to configure the homing cycle behavior to their needs.
// NOTE: The homing cycle is designed to allow sharing of limit pins, if the axes are not in the same
// cycle, but this requires some pin settings changes in the machine definition file. For example, the default homing
// cycle can share the Z limit pin with either X or Y limit pins, since they are on different cycles.
// By sharing a pin, this frees up a precious IO pin for other purposes. In theory, all axes limit pins
// may be reduced to one pin, if all axes are homed with separate cycles, or vice versa, all three axes
// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits
// will not be affected by pin sharing.

// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y.
// These homing cycle definitions precede the machine.h file so that the machine
// definition can undefine them if necessary.
#define HOMING_CYCLE_0 bit(Z_AXIS) // TYPICALLY REQUIRED: First move Z to clear workspace.
#define HOMING_CYCLE_1 bit(X_AXIS)
#define HOMING_CYCLE_2 bit(Y_AXIS)

// NOTE: The following is for for homing X and Y at the same time
// #define HOMING_CYCLE_0 bit(Z_AXIS) // first home z by itself
// #define HOMING_CYCLE_1 (bit(X_AXIS)|bit(Y_AXIS)) // Homes both X-Y in one cycle. NOT COMPATIBLE WITH COREXY!!!
// Note: HOMING_CYCLES are now settings

// Inverts pin logic of the control command pins based on a mask. This essentially means you can use
// normally-closed switches on the specified pins, rather than the default normally-open switches.
Expand Down Expand Up @@ -291,8 +267,6 @@ const double SAFETY_DOOR_SPINDLE_DELAY = 4.0; // Float (seconds)
const double SAFETY_DOOR_COOLANT_DELAY = 1.0; // Float (seconds)

// Enable CoreXY kinematics. Use ONLY with CoreXY machines.
// IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to
// #define HOMING_CYCLE_0 bit(X_AXIS) and #define HOMING_CYCLE_1 bit(Y_AXIS)
// NOTE: This configuration option alters the motion of the X and Y axes to principle of operation
// defined at (http://corexy.com/theory.html). Motors are assumed to positioned and wired exactly as
// described, if not, motions may move in strange directions. Grbl requires the CoreXY A and B motors
Expand Down
19 changes: 17 additions & 2 deletions Grbl_Esp32/src/Eeprom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,29 @@ void memcpy_to_eeprom_with_checksum(unsigned int destination, const char* source
unsigned char checksum = 0;
for (; size > 0; size--) {
unsigned char data = static_cast<unsigned char>(*source++);
checksum = (checksum << 1) | (checksum >> 7);
// Note: This checksum calculation is broken as described below.
checksum = (checksum << 1) || (checksum >> 7);
checksum += data;
EEPROM.write(destination++, data);
EEPROM.write(destination++, *(source++));
}
EEPROM.write(destination, checksum);
EEPROM.commit();
}

int memcpy_from_eeprom_with_old_checksum(char* destination, unsigned int source, unsigned int size) {
unsigned char data, checksum = 0;
for (; size > 0; size--) {
data = EEPROM.read(source++);
// Note: This checksum calculation is broken - the || should be just | -
// thus making the checksum very weak.
// We leave it as-is so we can read old data after a firmware upgrade.
// The new storage format uses the tagged NVS mechanism, avoiding this bug.
checksum = (checksum << 1) || (checksum >> 7);
checksum += data;
*(destination++) = data;
}
return (checksum == EEPROM.read(source));
}
int memcpy_from_eeprom_with_checksum(char* destination, unsigned int source, unsigned int size) {
unsigned char data, checksum = 0;
for (; size > 0; size--) {
Expand Down
1 change: 1 addition & 0 deletions Grbl_Esp32/src/Eeprom.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
//void eeprom_put_char(unsigned int addr, unsigned char new_value);
void memcpy_to_eeprom_with_checksum(unsigned int destination, const char* source, unsigned int size);
int memcpy_from_eeprom_with_checksum(char* destination, unsigned int source, unsigned int size);
int memcpy_from_eeprom_with_old_checksum(char* destination, unsigned int source, unsigned int size);
1 change: 1 addition & 0 deletions Grbl_Esp32/src/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ std::map<Error, const char*> ErrorCodes = {
{ Error::TravelExceeded, "Max travel exceeded during jog" },
{ Error::InvalidJogCommand, "Invalid jog command" },
{ Error::SettingDisabledLaser, "Laser mode requires PWM output" },
{ Error::HomingNoCycles, "No Homing/Cycle defined in settings" },
{ Error::GcodeUnsupportedCommand, "Unsupported GCode command" },
{ Error::GcodeModalGroupViolation, "Gcode modal group violation" },
{ Error::GcodeUndefinedFeedRate, "Gcode undefined feed rate" },
Expand Down
1 change: 1 addition & 0 deletions Grbl_Esp32/src/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum class Error : uint8_t {
TravelExceeded = 15,
InvalidJogCommand = 16,
SettingDisabledLaser = 17,
HomingNoCycles = 18,
GcodeUnsupportedCommand = 20,
GcodeModalGroupViolation = 21,
GcodeUndefinedFeedRate = 22,
Expand Down
114 changes: 53 additions & 61 deletions Grbl_Esp32/src/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,11 @@ parser_block_t gc_block;
#define FAIL(status) return (status);

void gc_init() {
// First thing we do here is iterate through the coord systems and read them all, so that
// we get all our coord system errors here, and not while we're busy:
float coord_system[MAX_N_AXIS];

// g54 - g59 is 6 coordinate systems, plus 2 for G28 and G30 reference positions
bool reported_error = false;
const int MAX_COORD_SYSTEMS = 8;
for (uint8_t i = 0; i < MAX_COORD_SYSTEMS; ++i) {
if (!(settings_read_coord_data(i, coord_system))) {
if (!reported_error) {
reported_error = true;
report_status_message(Error::SettingReadFail, CLIENT_SERIAL);
}
}
}

// Reset parser state:
memset(&gc_state, 0, sizeof(parser_state_t));
// Load default G54 coordinate system.
if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) {
report_status_message(Error::SettingReadFail, CLIENT_SERIAL);
}
gc_state.modal.coord_select = CoordIndex::G54;
coords[gc_state.modal.coord_select]->get(gc_state.coord_system);
}

// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard
Expand Down Expand Up @@ -149,7 +132,7 @@ Error gc_execute_line(char* line, uint8_t client) {
memcpy(&gc_block.modal, &gc_state.modal, sizeof(gc_modal_t)); // Copy current modes
AxisCommand axis_command = AxisCommand::None;
uint8_t axis_0, axis_1, axis_linear;
uint8_t coord_select = 0; // Tracks G10 P coordinate selection for execution
CoordIndex coord_select = CoordIndex::G54; // Tracks G10 P coordinate selection for execution
// Initialize bitflag tracking variables for axis indices compatible operations.
uint8_t axis_words = 0; // XYZ tracking
uint8_t ijk_words = 0; // IJK tracking
Expand All @@ -158,6 +141,8 @@ Error gc_execute_line(char* line, uint8_t client) {
uint32_t value_words = 0; // Tracks value words.
uint8_t gc_parser_flags = GCParserNone;
auto n_axis = number_axis->get();
float coord_data[MAX_N_AXIS]; // Used by WCO-related commands
uint8_t pValue; // Integer value of P word

// Determine if the line is a jogging motion or a normal g-code block.
if (line[0] == '$') { // NOTE: `$J=` already parsed when passed to this function.
Expand Down Expand Up @@ -409,15 +394,30 @@ Error gc_execute_line(char* line, uint8_t client) {
mg_word_bit = ModalGroup::MG8;
break;
case 54:
gc_block.modal.coord_select = CoordIndex::G54;
mg_word_bit = ModalGroup::MG12;
break;
case 55:
gc_block.modal.coord_select = CoordIndex::G55;
mg_word_bit = ModalGroup::MG12;
break;
case 56:
gc_block.modal.coord_select = CoordIndex::G56;
mg_word_bit = ModalGroup::MG12;
break;
case 57:
gc_block.modal.coord_select = CoordIndex::G57;
mg_word_bit = ModalGroup::MG12;
break;
case 58:
gc_block.modal.coord_select = CoordIndex::G58;
mg_word_bit = ModalGroup::MG12;
break;
case 59:
// NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.)
gc_block.modal.coord_select = int_value - 54; // Shift to array indexing.
gc_block.modal.coord_select = CoordIndex::G59;
mg_word_bit = ModalGroup::MG12;
break;
// NOTE: G59.x are not supported.
case 61:
if (mantissa != 0) {
FAIL(Error::GcodeUnsupportedCommand); // [G61.1 not supported]
Expand Down Expand Up @@ -879,13 +879,13 @@ Error gc_execute_line(char* line, uint8_t client) {
float block_coord_system[MAX_N_AXIS];
memcpy(block_coord_system, gc_state.coord_system, sizeof(gc_state.coord_system));
if (bit_istrue(command_words, bit(ModalGroup::MG12))) { // Check if called in block
if (gc_block.modal.coord_select > N_COORDINATE_SYSTEM) {
// This error probably cannot happen because preceding code sets
// gc_block.modal.coord_select only to specific supported values
if (gc_block.modal.coord_select >= CoordIndex::NWCSystems) {
FAIL(Error::GcodeUnsupportedCoordSys); // [Greater than N sys]
}
if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
if (!(settings_read_coord_data(gc_block.modal.coord_select, block_coord_system))) {
FAIL(Error::SettingReadFail);
}
coords[gc_block.modal.coord_select]->get(block_coord_system);
}
}
// [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED.
Expand All @@ -907,10 +907,6 @@ Error gc_execute_line(char* line, uint8_t client) {
if (bit_isfalse(value_words, (bit(GCodeWord::P) | bit(GCodeWord::L)))) {
FAIL(Error::GcodeValueWordMissing); // [P/L word missing]
}
coord_select = trunc(gc_block.values.p); // Convert p value to int.
if (coord_select > N_COORDINATE_SYSTEM) {
FAIL(Error::GcodeUnsupportedCoordSys); // [Greater than N sys]
}
if (gc_block.values.l != 20) {
if (gc_block.values.l == 2) {
if (bit_istrue(value_words, bit(GCodeWord::R))) {
Expand All @@ -920,32 +916,35 @@ Error gc_execute_line(char* line, uint8_t client) {
FAIL(Error::GcodeUnsupportedCommand); // [Unsupported L]
}
}
bit_false(value_words, (bit(GCodeWord::L) | bit(GCodeWord::P)));
// Determine coordinate system to change and try to load from EEPROM.
if (coord_select > 0) {
coord_select--; // Adjust P1-P6 index to EEPROM coordinate data indexing.
// Select the coordinate system based on the P word
pValue = trunc(gc_block.values.p); // Convert p value to integer
if (pValue > 0) {
// P1 means G54, P2 means G55, etc.
coord_select = static_cast<CoordIndex>(pValue - 1 + CoordIndex::G54);
} else {
coord_select = gc_block.modal.coord_select; // Index P0 as the active coordinate system
// P0 means use currently-selected system
coord_select = gc_block.modal.coord_select;
}
// NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
// FIXME: Instead of IJK, we'd better use: float vector[MAX_N_AXIS]; // [DG]
if (!settings_read_coord_data(coord_select, gc_block.values.ijk)) {
FAIL(Error::SettingReadFail); // [EEPROM read fail]
if (coord_select >= CoordIndex::NWCSystems) {
FAIL(Error::GcodeUnsupportedCoordSys); // [Greater than N sys]
}
bit_false(value_words, (bit(GCodeWord::L) | bit(GCodeWord::P)));
coords[coord_select]->get(coord_data);

// Pre-calculate the coordinate data changes.
for (idx = 0; idx < n_axis; idx++) { // Axes indices are consistent, so loop may be used.
// Update axes defined only in block. Always in machine coordinates. Can change non-active system.
if (bit_istrue(axis_words, bit(idx))) {
if (gc_block.values.l == 20) {
// L20: Update coordinate system axis at current position (with modifiers) with programmed value
// WPos = MPos - WCS - G92 - TLO -> WCS = MPos - G92 - TLO - WPos
gc_block.values.ijk[idx] = gc_state.position[idx] - gc_state.coord_offset[idx] - gc_block.values.xyz[idx];
coord_data[idx] = gc_state.position[idx] - gc_state.coord_offset[idx] - gc_block.values.xyz[idx];
if (idx == TOOL_LENGTH_OFFSET_AXIS) {
gc_block.values.ijk[idx] -= gc_state.tool_length_offset;
coord_data[idx] -= gc_state.tool_length_offset;
}
} else {
// L2: Update coordinate system axis to programmed value.
gc_block.values.ijk[idx] = gc_block.values.xyz[idx];
coord_data[idx] = gc_block.values.xyz[idx];
}
} // Else, keep current stored value.
}
Expand Down Expand Up @@ -1003,21 +1002,16 @@ Error gc_execute_line(char* line, uint8_t client) {
case NonModal::GoHome1: // G30
// [G28/30 Errors]: Cutter compensation is enabled.
// Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
// NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
if (gc_block.non_modal_command == NonModal::GoHome0) {
if (!settings_read_coord_data(SETTING_INDEX_G28, gc_block.values.ijk)) {
FAIL(Error::SettingReadFail);
}
coords[CoordIndex::G28]->get(coord_data);
} else { // == NonModal::GoHome1
if (!settings_read_coord_data(SETTING_INDEX_G30, gc_block.values.ijk)) {
FAIL(Error::SettingReadFail);
}
coords[CoordIndex::G30]->get(coord_data);
}
if (axis_words) {
// Move only the axes specified in secondary move.
for (idx = 0; idx < n_axis; idx++) {
if (!(axis_words & bit(idx))) {
gc_block.values.ijk[idx] = gc_state.position[idx];
coord_data[idx] = gc_state.position[idx];
}
}
} else {
Expand Down Expand Up @@ -1454,7 +1448,7 @@ Error gc_execute_line(char* line, uint8_t client) {
// [15. Coordinate system selection ]:
if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
gc_state.modal.coord_select = gc_block.modal.coord_select;
memcpy(gc_state.coord_system, block_coord_system, MAX_N_AXIS * sizeof(float));
memcpy(gc_state.coord_system, block_coord_system, sizeof(gc_state.coord_system));
system_flag_wco_change();
}
// [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED
Expand All @@ -1465,10 +1459,10 @@ Error gc_execute_line(char* line, uint8_t client) {
// [19. Go to predefined position, Set G10, or Set axis offsets ]:
switch (gc_block.non_modal_command) {
case NonModal::SetCoordinateData:
settings_write_coord_data(coord_select, gc_block.values.ijk);
coords[coord_select]->set(coord_data);
// Update system coordinate system if currently active.
if (gc_state.modal.coord_select == coord_select) {
memcpy(gc_state.coord_system, gc_block.values.ijk, MAX_N_AXIS * sizeof(float));
memcpy(gc_state.coord_system, coord_data, sizeof(gc_state.coord_system));
system_flag_wco_change();
}
break;
Expand All @@ -1480,14 +1474,14 @@ Error gc_execute_line(char* line, uint8_t client) {
if (axis_command != AxisCommand::None) {
mc_line(gc_block.values.xyz, pl_data); // kinematics kinematics not used for homing righ now
}
mc_line(gc_block.values.ijk, pl_data);
memcpy(gc_state.position, gc_block.values.ijk, MAX_N_AXIS * sizeof(float));
mc_line(coord_data, pl_data);
memcpy(gc_state.position, coord_data, sizeof(gc_state.position));
break;
case NonModal::SetHome0:
settings_write_coord_data(SETTING_INDEX_G28, gc_state.position);
coords[CoordIndex::G28]->set(coord_data);
break;
case NonModal::SetHome1:
settings_write_coord_data(SETTING_INDEX_G30, gc_state.position);
coords[CoordIndex::G30]->set(coord_data);
break;
case NonModal::SetCoordinateOffset:
memcpy(gc_state.coord_offset, gc_block.values.xyz, sizeof(gc_block.values.xyz));
Expand Down Expand Up @@ -1587,7 +1581,7 @@ Error gc_execute_line(char* line, uint8_t client) {
gc_state.modal.distance = Distance::Absolute;
gc_state.modal.feed_rate = FeedRate::UnitsPerMin;
// gc_state.modal.cutter_comp = CutterComp::Disable; // Not supported.
gc_state.modal.coord_select = 0; // G54
gc_state.modal.coord_select = CoordIndex::G54;
gc_state.modal.spindle = SpindleState::Disable;
gc_state.modal.coolant = {};
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
Expand All @@ -1605,9 +1599,7 @@ Error gc_execute_line(char* line, uint8_t client) {
#endif
// Execute coordinate change and spindle/coolant stop.
if (sys.state != State::CheckMode) {
if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) {
FAIL(Error::SettingReadFail);
}
coords[gc_state.modal.coord_select]->get(gc_state.coord_system);
system_flag_wco_change(); // Set to refresh immediately just in case something altered.
spindle->set_state(SpindleState::Disable, 0);
coolant_off();
Expand Down
Loading

0 comments on commit d0acc9b

Please sign in to comment.