Skip to content

Commit

Permalink
Limited tool change probe moves to be within machine limits. Ref. issue
Browse files Browse the repository at this point in the history
#542.

Added setting $358 to enable experimental functionality for fast rotary 'rewind' to stored G28 position.
Return move should complete in half a rotation or less.
For developers: added option to redirect debug via driver provided function when DEBUGOUT is set to -1 in config.h. Ref. issue #545.
  • Loading branch information
terjeio committed Jul 19, 2024
1 parent 5cff12e commit 8b9b785
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 50 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa

---

Latest build date is 20240704, see the [changelog](changelog.md) for details.
Latest build date is 20240719, see the [changelog](changelog.md) for details.

__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
Expand Down
22 changes: 22 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
## grblHAL changelog

<a name="20240715">Build 20240719

Core:

* Limited tool change probe moves to be within machine limits. Ref. [issue #542](https://github.com/grblHAL/core/issues/542).

* Added setting `$358` to enable experimental functionality for fast rotary 'rewind' to stored G28 position. Return move should complete in half a rotation or less.
To use program:
```
G91G28<axisletter>0
G90
```
where \<axisletter\> is the axisletter of the rotary axis to move.

* For developers: added option to redirect debug via driver provided function when `DEBUGOUT` is set to `-1` in _config.h_. Can be used to send debug output to debugger interfaces.

Plugins:

* WebUI: fix for crash when settings page is opened with macros plugin enabled. Ref. [issue #14](https://github.com/grblHAL/Plugin_WebUI/issues/14).

---

<a name="20240709"/>Build 20240709

Core:
Expand Down
12 changes: 12 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,18 @@ Timezone offset from UTC in hours, allowed range is -12.0 - 12.0.
#endif
///@}

/*! @name $538 - Setting_RotaryWrap
Enable fast return to G28 position for rotary axes by \ref axismask.
Use:
G91G28<axisletter>0
G90
*/
///@{
#if !defined DEFAULT_AXIS_ROTARY_WRAP_MASK || defined __DOXYGEN__
#define DEFAULT_AXIS_ROTARY_WRAP_MASK 0
#endif
///@}

// Axis settings (Group_XAxis - Group_VAxis)

/*! @name $10x - Setting_AxisStepsPerMM
Expand Down
54 changes: 51 additions & 3 deletions gcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,7 @@ status_code_t gc_execute_block (char *block)
case 56:
if(!settings.parking.flags.enable_override_control) // TODO: check if enabled?
FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command]
// no break;
// no break
case 48: case 49: case 50: case 51: case 53:
word_bit.modal_group.M9 = On;
gc_block.override_command = (override_mode_t)int_value;
Expand Down Expand Up @@ -1979,7 +1979,7 @@ status_code_t gc_execute_block (char *block)
if (gc_block.modal.units_imperial) do { // Axes indices are consistent, so loop may be used.
idx--;
#if N_AXIS > 3
if (bit_istrue(axis_words.mask, bit(idx)) && bit_isfalse(settings.steppers.is_rotational.mask, bit(idx))) {
if (bit_istrue(axis_words.mask, bit(idx)) && bit_isfalse(settings.steppers.is_rotary.mask, bit(idx))) {
#else
if (bit_istrue(axis_words.mask, bit(idx))) {
#endif
Expand Down Expand Up @@ -3408,12 +3408,60 @@ status_code_t gc_execute_block (char *block)
break;

case NonModal_GoHome_0:
#if N_AXIS > 3
{
axes_signals_t wrap = { (axis_words.mask & settings.steppers.is_rotary.mask) & settings.steppers.rotary_wrap.mask };
if(gc_state.modal.distance_incremental && wrap.mask) {
for(idx = Z_AXIS + 1; idx < N_AXIS; idx++) {
if(bit_istrue(wrap.mask, bit(idx)) && gc_block.values.xyz[idx] == gc_state.position[idx])
gc_block.rotary_wrap.mask |= bit(idx);
}
}
}
// no break
#endif

case NonModal_GoHome_1:
// Move to intermediate position before going home. Obeys current coordinate system and offsets
// and absolute and incremental modes.
plan_data.condition.rapid_motion = On; // Set rapid motion condition flag.
if (axis_command)
if(axis_command)
mc_line(gc_block.values.xyz, &plan_data);
#if N_AXIS > 3
if(gc_block.rotary_wrap.mask) {

coord_system_t wrap_target;

protocol_buffer_synchronize();
memcpy(wrap_target.xyz, gc_block.values.coord_data.xyz, sizeof(coord_system_t));

for(idx = Z_AXIS + 1; idx < N_AXIS; idx++) {
if(bit_istrue(gc_block.rotary_wrap.mask, bit(idx))) {
float position, delta;
if((wrap_target.xyz[idx] = fmodf(wrap_target.xyz[idx], 360.0f)) < 0.0f)
wrap_target.xyz[idx] = 360.0f + wrap_target.xyz[idx];
if((position = fmodf(gc_state.position[idx], 360.0f)) < 0.0)
position = 360.0f + position;
if((delta = position - wrap_target.xyz[idx]) < -180.0f)
position += 360.0f;
else if(delta > 180.0f)
position -= 360.0f;
sys.position[idx] = lroundf(position * settings.axis[idx].steps_per_mm);
}
}

sync_position();
mc_line(wrap_target.xyz, &plan_data);
protocol_buffer_synchronize();

for(idx = Z_AXIS + 1; idx < N_AXIS; idx++) {
if(bit_istrue(gc_block.rotary_wrap.mask, bit(idx)))
sys.position[idx] = lroundf(gc_block.values.coord_data.xyz[idx] * settings.axis[idx].steps_per_mm);
}

sync_position();
} else
#endif
mc_line(gc_block.values.coord_data.xyz, &plan_data);
memcpy(gc_state.position, gc_block.values.coord_data.xyz, sizeof(gc_state.position));
set_scaling(1.0f);
Expand Down
3 changes: 3 additions & 0 deletions gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@ typedef struct {
#if NGC_PARAMETERS_ENABLE
modal_state_action_t state_action; //!< M70-M73 modal state action
#endif
#if N_AXIS > 3
axes_signals_t rotary_wrap;
#endif
} parser_block_t;

// Initialize the parser
Expand Down
2 changes: 1 addition & 1 deletion grbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20240709
#define GRBL_BUILD 20240719

#define GRBL_URL "https://github.com/grblHAL"

Expand Down
2 changes: 1 addition & 1 deletion machine_limits.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ static bool homing_cycle (axes_signals_t cycle, axes_signals_t auto_square)
// NOTE: settings.axis[].max_travel is stored as a negative value.
if(bit_istrue(cycle.mask, bit(idx))) {
#if N_AXIS > 3
if(bit_istrue(settings.steppers.is_rotational.mask, bit(idx)))
if(bit_istrue(settings.steppers.is_rotary.mask, bit(idx)))
max_travel = max(max_travel, (-HOMING_AXIS_SEARCH_SCALAR) * (settings.axis[idx].max_travel < -0.0f ? settings.axis[idx].max_travel : -360.0f));
else
#endif
Expand Down
6 changes: 3 additions & 3 deletions planner.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,13 +469,13 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)

if(!block->condition.inverse_time &&
!block->condition.rapid_motion &&
(motion.mask & settings.steppers.is_rotational.mask) &&
(motion.mask & ~settings.steppers.is_rotational.mask)) {
(motion.mask & settings.steppers.is_rotary.mask) &&
(motion.mask & ~settings.steppers.is_rotary.mask)) {

float linear_magnitude = 0.0f;

idx = 0;
motion.mask &= ~settings.steppers.is_rotational.mask;
motion.mask &= ~settings.steppers.is_rotary.mask;

while(motion.mask) {
if(motion.mask & 0x01)
Expand Down
2 changes: 1 addition & 1 deletion report.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static char *get_axis_values_inches (float *axis_values)
if(idx == X_AXIS && gc_state.modal.diameter_mode)
strcat(buf, ftoa(axis_values[idx] * INCH_PER_MM * 2.0f, N_DECIMAL_COORDVALUE_INCH));
#if N_AXIS > 3
else if(idx > Z_AXIS && bit_istrue(settings.steppers.is_rotational.mask, bit(idx)))
else if(idx > Z_AXIS && bit_istrue(settings.steppers.is_rotary.mask, bit(idx)))
strcat(buf, ftoa(axis_values[idx], N_DECIMAL_COORDVALUE_MM));
#endif
else
Expand Down
95 changes: 65 additions & 30 deletions settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ PROGMEM const settings_t defaults = {
#endif
.steppers.deenergize.mask = DEFAULT_STEPPER_DEENERGIZE_MASK,
#if N_AXIS > 3
.steppers.is_rotational.mask = (DEFAULT_AXIS_ROTATIONAL_MASK & AXES_BITMASK) & 0b11111000,
.steppers.is_rotary.mask = (DEFAULT_AXIS_ROTATIONAL_MASK & AXES_BITMASK) & 0b11111000,
.steppers.rotary_wrap.mask = (DEFAULT_AXIS_ROTARY_WRAP_MASK & AXES_BITMASK) & 0b11111000,
#endif
#if DEFAULT_HOMING_ENABLE
.homing.flags.enabled = DEFAULT_HOMING_ENABLE,
Expand Down Expand Up @@ -406,7 +407,8 @@ static status_code_t set_linear_piece (setting_id_t id, char *svalue);
static char *get_linear_piece (setting_id_t id);
#endif
#if N_AXIS > 3
static status_code_t set_rotational_axes (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_rotary_axes (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_rotary_wrap_axes (setting_id_t id, uint_fast16_t int_value);
#endif
#if COMPATIBILITY_LEVEL > 2
static status_code_t set_enable_invert_mask (setting_id_t id, uint_fast16_t int_value);
Expand Down Expand Up @@ -434,6 +436,28 @@ static char control_signals[] = "Reset,Feed hold,Cycle start,Safety door,Block d
static char spindle_signals[] = "Spindle enable,Spindle direction,PWM";
static char coolant_signals[] = "Flood,Mist";
static char ganged_axes[] = "X-Axis,Y-Axis,Z-Axis";
#if !AXIS_REMAP_ABC2UVW
#if N_AXIS == 4
static const char rotary_axes[] = "A-Axis";
#elif N_AXIS == 5
static const char rotary_axes[] = "A-Axis,B-Axis";
#elif N_AXIS == 6
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis";
#elif N_AXIS == 7
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis";
#elif N_AXIS == 8
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis,V-Axis";
#endif
#else
#if N_AXIS == 4
static const char rotary_axes[] = "U-Axis";
#elif N_AXIS == 5
static const char rotary_axes[] = "U-Axis,V-Axis";
#elif N_AXIS == 6
static const char rotary_axes[] = "U-Axis,V-Axis,W-Axis";
#endif
#endif

static char fs_options[] = "Auto mount SD card,Hide LittleFS";
static char spindle_types[100] = "";
static char axis_dist[4] = "mm";
Expand Down Expand Up @@ -585,26 +609,8 @@ PROGMEM static const setting_detail_t setting_detail[] = {
#if COMPATIBILITY_LEVEL <= 1
{ Setting_DisableG92Persistence, Group_General, "Disable G92 persistence", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_g92_disable_persistence, get_int, NULL },
#endif
#if !AXIS_REMAP_ABC2UVW
#if N_AXIS == 4
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 5
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 6
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis,C-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 7
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis,C-Axis,U-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 8
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis,C-Axis,U-Axis,V-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#endif
#else
#if N_AXIS == 4
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "U-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 5
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "U-Axis,V-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#elif N_AXIS == 6
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "U-Axis,V-Axis,W-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
#endif
#if N_AXIS > 3
{ Settings_RotaryAxes, Group_Stepper, "Rotary axes", NULL, Format_Bitfield, rotary_axes, NULL, NULL, Setting_IsExtendedFn, set_rotary_axes, get_int, NULL },
#endif
#ifndef NO_SAFETY_DOOR_SUPPORT
{ Setting_DoorSpindleOnDelay, Group_SafetyDoor, "Spindle on delay", "s", Format_Decimal, "#0.0", "0.5", "20", Setting_IsExtended, &settings.safety_door.spindle_on_delay, NULL, is_setting_available },
Expand All @@ -623,6 +629,9 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_OffsetLock, Group_General, "Lock coordinate systems", NULL, Format_Bitfield, "G59.1,G59.2,G59.3", NULL, NULL, Setting_IsExtendedFn, set_offset_lock, get_int, NULL },
#endif
{ Setting_EncoderSpindle, Group_Spindle, "Encoder spindle", NULL, Format_RadioButtons, spindle_types, NULL, NULL, Setting_IsExtendedFn, set_encoder_spindle, get_int, is_setting_available },
#if N_AXIS > 3
{ Setting_RotaryWrap, Group_Stepper, "Fast rotary go to G28", NULL, Format_Bitfield, rotary_axes, NULL, NULL, Setting_IsExtendedFn, set_rotary_wrap_axes, get_int, NULL },
#endif
{ Setting_FSOptions, Group_General, "File systems options", NULL, Format_Bitfield, fs_options, NULL, NULL, Setting_IsExtended, &settings.fs_options.mask, NULL, is_setting_available },
{ Setting_HomePinsInvertMask, Group_Limits, "Invert home pins", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.home_invert.mask, NULL, is_setting_available },
{ Setting_HoldCoolantOnDelay, Group_Coolant, "Coolant on delay", "s", Format_Decimal, "#0.0", "0.5", "20", Setting_IsExtended, &settings.safety_door.coolant_on_delay, NULL, is_setting_available }
Expand Down Expand Up @@ -784,9 +793,12 @@ PROGMEM static const setting_descr_t setting_descr[] = {
#if COMPATIBILITY_LEVEL <= 1
{ Setting_DisableG92Persistence, "Disables save/restore of G92 offset to non-volatile storage (NVS)." },
#endif
#if N_AXIS > 3
{ Settings_RotaryAxes, "Designates axes as rotary, interpretation some other relevant axis settings is changed accordingly." },
#endif
#ifndef NO_SAFETY_DOOR_SUPPORT
{ Setting_DoorSpindleOnDelay, "Delay to allow spindle to spin up after safety door is opened or feed hold is canceled.." },
{ Setting_DoorCoolantOnDelay, "Delay to allow coolant to restart after safety door is opened or feed hold is canceled.." },
{ Setting_DoorSpindleOnDelay, "Delay to allow spindle to spin up after safety door is opened or feed hold is canceled." },
{ Setting_DoorCoolantOnDelay, "Delay to allow coolant to restart after safety door is opened or feed hold is canceled." },
#else
{ Setting_DoorSpindleOnDelay, "Delay to allow spindle to spin up when spindle at speed tolerance is > 0." },
#endif
Expand All @@ -803,6 +815,13 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ Setting_NGCDebugOut, "Example: (debug, metric mode: #<_metric>, coord system: #5220)" },
#endif
{ Setting_EncoderSpindle, "Specifies which spindle has the encoder attached." },
#if N_AXIS > 3
{ Setting_RotaryWrap, "Perform fast move to angle stored in G28 position.\\n"
"Use:\\n"
" G91G28<axisletter>0\\n"
" G90\\n"
},
#endif
{ Setting_FSOptions, "Auto mount SD card on startup." },
{ Setting_HomePinsInvertMask, "Inverts the axis home input signals." },
{ Setting_HoldCoolantOnDelay, "Delay to allow coolant to restart after feed hold is canceled." }
Expand Down Expand Up @@ -1128,7 +1147,7 @@ static inline void tmp_set_hard_limits (void)
sys.hard_limits.mask = settings.limits.flags.hard_enabled ? AXES_BITMASK : 0;
#if N_AXIS > 3
if(settings.limits.flags.hard_disabled_rotary)
sys.hard_limits.mask &= ~settings.steppers.is_rotational.mask;
sys.hard_limits.mask &= ~settings.steppers.is_rotary.mask;
#endif
}

Expand Down Expand Up @@ -1340,16 +1359,23 @@ static inline void set_axis_unit (const setting_detail_t *setting, const char *u

#if N_AXIS > 3

static status_code_t set_rotational_axes (setting_id_t id, uint_fast16_t int_value)
static status_code_t set_rotary_axes (setting_id_t id, uint_fast16_t int_value)
{
settings.steppers.is_rotational.mask = (int_value << 3) & AXES_BITMASK;
settings.steppers.is_rotary.mask = (int_value << 3) & AXES_BITMASK;

return Status_OK;
}

static status_code_t set_rotary_wrap_axes (setting_id_t id, uint_fast16_t int_value)
{
settings.steppers.rotary_wrap.mask = (int_value << 3) & AXES_BITMASK;

return Status_OK;
}

static inline bool axis_is_rotary (uint_fast8_t axis_idx)
{
return bit_istrue(settings.steppers.is_rotational.mask, bit(axis_idx));
return bit_istrue(settings.steppers.is_rotary.mask, bit(axis_idx));
}

static const char *set_axis_setting_unit (setting_id_t setting_id, uint_fast8_t axis_idx)
Expand Down Expand Up @@ -1730,8 +1756,12 @@ static uint32_t get_int (setting_id_t id)
break;

#if N_AXIS > 3
case Settings_Axis_Rotational:
value = (settings.steppers.is_rotational.mask & AXES_BITMASK) >> 3;
case Settings_RotaryAxes:
value = (settings.steppers.is_rotary.mask & AXES_BITMASK) >> 3;
break;

case Setting_RotaryWrap:
value = (settings.steppers.rotary_wrap.mask & AXES_BITMASK) >> 3;
break;
#endif

Expand Down Expand Up @@ -2184,6 +2214,7 @@ bool read_global_settings ()
bool ok = hal.nvs.type != NVS_None && SETTINGS_VERSION == hal.nvs.get_byte(0) && hal.nvs.memcpy_from_nvs((uint8_t *)&settings, NVS_ADDR_GLOBAL, sizeof(settings_t), true) == NVS_TransferResult_OK;

// Sanity check of settings, board map could have been changed...

#if LATHE_UVW_OPTION
settings.mode = Mode_Lathe;
#else
Expand All @@ -2209,6 +2240,10 @@ bool read_global_settings ()
settings.steppers.enable_invert.mask = AXES_BITMASK;
#endif

#if N_AXIS > 3
settings.steppers.rotary_wrap.mask &= settings.steppers.is_rotary.mask;
#endif

settings.control_invert.mask |= limits_override.mask;
settings.control_disable_pullup.mask &= ~limits_override.mask;

Expand Down
Loading

0 comments on commit 8b9b785

Please sign in to comment.