mirror of
https://github.com/grblHAL/core.git
synced 2026-08-20 22:11:38 +08:00
Fix for laser incorrectly enabled in laser mode when M3S<n> commanded in G0 and G80 modal states. Ref. issue #644.
Added optional support for 3rd order acceleration (jerk) and G187 gcode. Ref. pull request #593.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## grblHAL ##
|
||||
|
||||
Latest build date is 20241222, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20241230, see the [changelog](changelog.md) for details.
|
||||
|
||||
> [!NOTE]
|
||||
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
|
||||
@@ -93,4 +93,4 @@ G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are
|
||||
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
|
||||
|
||||
---
|
||||
20241222
|
||||
20241230
|
||||
|
||||
+24
-1
@@ -1,10 +1,33 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20241226">Build 20241230
|
||||
|
||||
Core:
|
||||
|
||||
* Fix for laser incorrectly enabled in laser mode when `M3S<n>` commanded in `G0` and `G80` modal states. Ref. issue [#644](https://github.com/grblHAL/core/issues/644).
|
||||
|
||||
* Added support for 3rd order acceleration \(jerk\) and G187 gcode. Ref. pull request [#593](https://github.com/grblHAL/core/pull/593).
|
||||
|
||||
Drivers:
|
||||
|
||||
* STM32F4xx: updated ST framework to latest version, added support for ethernet via DP83848 PHY.
|
||||
|
||||
* STM32F4xx, STM32F7xx: Improved SD card mount/dismount handling and added support for card detect signal.
|
||||
Now flags RTC as set if date >= grblHAL build date.
|
||||
|
||||
* LPC176x: added function required for Modbus support. Renamed bootloader build option to avoid confusion.
|
||||
|
||||
Plugins:
|
||||
|
||||
* SD card: improved mount/dismount handling.
|
||||
|
||||
---
|
||||
|
||||
<a name="20241226">20241226
|
||||
|
||||
Drivers:
|
||||
|
||||
* STM32F4xx: fix for not enabling steppers after clearing E-stop alarm. Ref. issue [#203](https://github.com/grblHAL/STM32F4xx/issues/203).
|
||||
* STM32F4xx: SuperLongBoard - fix for not enabling steppers after clearing E-stop alarm. Ref. issue [#203](https://github.com/grblHAL/STM32F4xx/issues/203).
|
||||
|
||||
Plugins:
|
||||
|
||||
|
||||
@@ -190,9 +190,18 @@ or EMI triggering the related interrupt falsely or too many times.
|
||||
// ADVANCED CONFIGURATION OPTIONS:
|
||||
|
||||
// EXPERIMENTAL OPTIONS
|
||||
|
||||
#define ENABLE_PATH_BLENDING Off // Do NOT enable unless working on adding this feature!
|
||||
|
||||
#if !defined ENABLE_ACCELERATION_PROFILES || defined __DOXYGEN__
|
||||
#define ENABLE_ACCELERATION_PROFILES Off // Enable to allow G-Code changeable acceleration profiles.
|
||||
#define ENABLE_JERK_ACCELERATION Off // Enable to use 3rd order Acceleration calculations. May need more processing power, tiny chips beware.
|
||||
#endif
|
||||
|
||||
#if !defined ENABLE_JERK_ACCELERATION || defined __DOXYGEN__
|
||||
#define ENABLE_JERK_ACCELERATION Off // Enable to use 3rd order acceleration calculations. May need more processing power, a FPU will help.
|
||||
#endif
|
||||
|
||||
// -
|
||||
|
||||
// Enables code for debugging purposes. Not for general use and always in constant flux.
|
||||
//#define DEBUG // Uncomment to enable. Default disabled.
|
||||
@@ -2022,7 +2031,6 @@ G90
|
||||
/*! @name 22x - Setting_AxisJerk
|
||||
*/
|
||||
///@{
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
#if !defined DEFAULT_X_JERK|| defined __DOXYGEN__
|
||||
#define DEFAULT_X_JERK 100.0f // mm/sec^3
|
||||
#endif
|
||||
@@ -2047,7 +2055,6 @@ G90
|
||||
#if (defined V_AXIS && !defined DEFAULT_V_JERK) || defined __DOXYGEN__
|
||||
#define DEFAULT_V_JERK 100.0f // mm/sec^3
|
||||
#endif
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/*! @name 13x - Setting_AxisMaxTravel
|
||||
|
||||
+2
-2
@@ -445,7 +445,6 @@ typedef enum {
|
||||
PinGroup_AuxOutput,
|
||||
PinGroup_AuxInputAnalog,
|
||||
PinGroup_AuxOutputAnalog,
|
||||
PinGroup_SdCard,
|
||||
PinGroup_MotorChipSelect,
|
||||
PinGroup_MotorUART,
|
||||
PinGroup_I2C,
|
||||
@@ -471,7 +470,8 @@ typedef enum {
|
||||
PinGroup_QEI_Index = (1<<16),
|
||||
PinGroup_Motor_Warning = (1<<17),
|
||||
PinGroup_Motor_Fault = (1<<18),
|
||||
PinGroup_AuxInput = (1<<19)
|
||||
PinGroup_SdCard = (1<<19),
|
||||
PinGroup_AuxInput = (1<<20)
|
||||
} pin_group_t;
|
||||
|
||||
//! Pin interrupt modes, may be or'ed when reporting pin capability.
|
||||
|
||||
@@ -288,6 +288,24 @@ plane_t *gc_get_plane_data (plane_t *plane, plane_select_t select)
|
||||
return plane;
|
||||
}
|
||||
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
|
||||
//Acceleration Profiles for G187 P[x] in percent of maximum machine acceleration.
|
||||
float gc_get_accel_factor (uint8_t profile)
|
||||
{
|
||||
static const float lookup[] = {
|
||||
1.0f, // 100% - Roughing - Max Acceleration Default
|
||||
0.8f, // 80% - Semi Roughing
|
||||
0.6f, // 60% - Semi Finish
|
||||
0.4f, // 40% - Finish
|
||||
0.2f // 20% - Slow AF Mode
|
||||
};
|
||||
|
||||
return lookup[profile >= (sizeof(lookup) / sizeof(float)) ? 0 : profile];
|
||||
}
|
||||
|
||||
#endif // ENABLE_ACCELERATION_PROFILES
|
||||
|
||||
void gc_init (bool stop)
|
||||
{
|
||||
#if COMPATIBILITY_LEVEL > 1
|
||||
@@ -362,7 +380,7 @@ void gc_init (bool stop)
|
||||
ngc_modal_state_invalidate();
|
||||
#endif
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
gc_state.modal.acceleration_factor = 1.0f; // Initialize machine with 100% Profile
|
||||
gc_state.modal.acceleration_factor = gc_get_accel_factor(0); // Initialize machine with default
|
||||
#endif
|
||||
|
||||
// if(settings.flags.lathe_mode)
|
||||
@@ -2379,7 +2397,7 @@ status_code_t gc_execute_block (char *block)
|
||||
if(gc_block.words.p && (gc_block.values.p < 1.0f || gc_block.values.p > 5.0f))
|
||||
FAIL(Status_GcodeValueOutOfRange);
|
||||
|
||||
gc_state.modal.acceleration_factor = lookupfactor(gc_block.words.p ? (uint8_t)gc_block.values.p - 1 : 0);
|
||||
gc_state.modal.acceleration_factor = gc_get_accel_factor(gc_block.words.p ? (uint8_t)gc_block.values.p - 1 : 0);
|
||||
gc_block.words.p = Off;
|
||||
break;
|
||||
#endif
|
||||
@@ -3163,6 +3181,10 @@ status_code_t gc_execute_block (char *block)
|
||||
}
|
||||
sspindle->rpm = gc_block.values.s; // Update spindle speed state.
|
||||
}
|
||||
|
||||
// NOTE: Pass zero spindle speed for all restricted laser motions.
|
||||
plan_data.spindle.rpm = gc_parser_flags.laser_disable ? 0.0f : gc_block.values.s;
|
||||
|
||||
#if N_SYS_SPINDLE > 1
|
||||
}
|
||||
#endif
|
||||
@@ -3331,28 +3353,24 @@ status_code_t gc_execute_block (char *block)
|
||||
if((spindle_ok = sspindle->state.value != gc_block.spindle_modal.state.value)) {
|
||||
|
||||
if(grbl.on_spindle_programmed)
|
||||
grbl.on_spindle_programmed(sspindle->hal, gc_block.spindle_modal.state, sspindle->rpm, sspindle->rpm_mode);
|
||||
grbl.on_spindle_programmed(sspindle->hal, gc_block.spindle_modal.state, plan_data.spindle.rpm, sspindle->rpm_mode);
|
||||
|
||||
if((spindle_ok = spindle_sync(sspindle->hal, gc_block.spindle_modal.state, sspindle->rpm)))
|
||||
if((spindle_ok = spindle_sync(sspindle->hal, gc_block.spindle_modal.state, plan_data.spindle.rpm)))
|
||||
sspindle->state = sspindle->hal->param->state = gc_block.spindle_modal.state;
|
||||
|
||||
spindle_event = !spindle_ok;
|
||||
}
|
||||
|
||||
if(spindle_event && grbl.on_spindle_programmed)
|
||||
grbl.on_spindle_programmed(sspindle->hal, sspindle->state, sspindle->rpm, sspindle->rpm_mode);
|
||||
grbl.on_spindle_programmed(sspindle->hal, sspindle->state, plan_data.spindle.rpm, sspindle->rpm_mode);
|
||||
}
|
||||
|
||||
if(sspindle != NULL)
|
||||
gc_state.spindle = sspindle; // for now
|
||||
|
||||
// NOTE: Pass zero spindle speed for all restricted laser motions.
|
||||
if(!gc_parser_flags.laser_disable)
|
||||
memcpy(&plan_data.spindle, gc_state.spindle, sizeof(spindle_t)); // Record data for planner use.
|
||||
else {
|
||||
plan_data.spindle.hal = gc_state.spindle->hal;
|
||||
// plan_data.spindle.speed = 0.0f; // Initialized as zero already.
|
||||
}
|
||||
plan_data.spindle.hal = gc_state.spindle->hal;
|
||||
memcpy(&plan_data.spindle, gc_state.spindle, offsetof(spindle_t, rpm)); // Record data for planner use.
|
||||
|
||||
// TODO: Recheck spindle running in CCS mode (is_rpm_pos_adjusted == On)?
|
||||
|
||||
plan_data.spindle.state = gc_state.spindle->state; // Set condition flag for planner use.
|
||||
@@ -3846,9 +3864,9 @@ status_code_t gc_execute_block (char *block)
|
||||
gc_state.modal.coolant = (coolant_state_t){0};
|
||||
gc_state.modal.override_ctrl.feed_rate_disable = Off;
|
||||
gc_state.modal.override_ctrl.spindle_rpm_disable = Off;
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
gc_state.modal.acceleration_factor = 1.0f;
|
||||
#endif
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
gc_state.modal.acceleration_factor = gc_get_accel_factor(0);
|
||||
#endif
|
||||
|
||||
#if N_SYS_SPINDLE > 1
|
||||
|
||||
|
||||
@@ -502,11 +502,22 @@ typedef struct {
|
||||
const gc_value_type_t type;
|
||||
} gc_value_ptr_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t value;
|
||||
struct {
|
||||
uint8_t is_rpm_rate_adjusted :1,
|
||||
is_laser_ppi_mode :1,
|
||||
unassigned :6;
|
||||
|
||||
};
|
||||
} spindle_cond_t;
|
||||
|
||||
typedef struct {
|
||||
float rpm; //!< Spindle speed
|
||||
spindle_state_t state; //!< {M3,M4,M5}
|
||||
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
|
||||
spindle_css_data_t *css; //!< Data used for Constant Surface Speed Mode calculations
|
||||
spindle_cond_t condition; //!< TODO: move data from planner_cond_t here
|
||||
float rpm; //!< Spindle speed. Must be second last!
|
||||
spindle_ptrs_t *hal; //!< Spindle function pointers etc. Must be last!
|
||||
} spindle_t;
|
||||
|
||||
@@ -701,4 +712,8 @@ parameter_words_t gc_get_g65_arguments (void);
|
||||
bool gc_modal_state_restore (gc_modal_t *copy);
|
||||
#endif
|
||||
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
float gc_get_accel_factor (uint8_t profile);
|
||||
#endif
|
||||
|
||||
#endif // _GCODE_H_
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20241222
|
||||
#define GRBL_BUILD 20241230
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
+12
-4
@@ -127,6 +127,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_DETECT_BIT
|
||||
#ifdef SD_DETECT_PIN
|
||||
#define SD_DETECT_BIT (1<<SD_DETECT_PIN)
|
||||
#else
|
||||
#define SD_DETECT_BIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Optional control signals
|
||||
|
||||
#ifndef SAFETY_DOOR_BIT
|
||||
@@ -633,11 +641,11 @@ static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_clai
|
||||
|
||||
#ifndef DEVICES_IRQ_MASK
|
||||
#ifdef AUX_DEVICES
|
||||
#define DEVICES_IRQ_MASK (SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT)
|
||||
#define DEVICES_IRQ_MASK_SUM (SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT)
|
||||
#define DEVICES_IRQ_MASK (SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|SD_DETECT_BIT)
|
||||
#define DEVICES_IRQ_MASK_SUM (SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
|
||||
#else
|
||||
#define DEVICES_IRQ_MASK (MPG_MODE_BIT|I2C_STROBE_BIT|QEI_SELECT_BIT|SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT)
|
||||
#define DEVICES_IRQ_MASK_SUM (MPG_MODE_BIT+I2C_STROBE_BIT+QEI_SELECT_BIT+SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT)
|
||||
#define DEVICES_IRQ_MASK (MPG_MODE_BIT|I2C_STROBE_BIT|QEI_SELECT_BIT|SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|SD_DETECT_BIT)
|
||||
#define DEVICES_IRQ_MASK_SUM (MPG_MODE_BIT+I2C_STROBE_BIT+QEI_SELECT_BIT+SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -336,6 +336,7 @@ inline static float plan_compute_profile_parameters (plan_block_t *block, float
|
||||
block->max_entry_speed_sqr = nominal_speed > prev_nominal_speed ? (prev_nominal_speed * prev_nominal_speed) : (nominal_speed * nominal_speed);
|
||||
if (block->max_entry_speed_sqr > block->max_junction_speed_sqr)
|
||||
block->max_entry_speed_sqr = block->max_junction_speed_sqr;
|
||||
|
||||
return nominal_speed;
|
||||
}
|
||||
|
||||
@@ -348,6 +349,7 @@ static inline float limit_acceleration_by_axis_maximum (float *unit_vec)
|
||||
if (unit_vec[--idx] != 0.0f) // Avoid divide by zero.
|
||||
limit_value = min(limit_value, fabsf(settings.axis[idx].acceleration / unit_vec[idx]));
|
||||
} while(idx);
|
||||
|
||||
return limit_value;
|
||||
}
|
||||
|
||||
@@ -361,6 +363,7 @@ static inline float limit_jerk_by_axis_maximum (float *unit_vec)
|
||||
if (unit_vec[--idx] != 0.0f) // Avoid divide by zero.
|
||||
limit_value = min(limit_value, fabsf(settings.axis[idx].jerk / unit_vec[idx]));
|
||||
} while(idx);
|
||||
|
||||
return limit_value;
|
||||
}
|
||||
#endif
|
||||
@@ -738,7 +741,7 @@ void plan_data_init (plan_line_data_t *plan_data)
|
||||
#ifdef KINEMATICS_API
|
||||
plan_data->rate_multiplier = 1.0f;
|
||||
#endif
|
||||
#ifdef ENABLE_ACCELERATION_PROFILES
|
||||
plan_data->acceleration_factor = 1.0f;
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
plan_data->acceleration_factor = gc_get_accel_factor(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ typedef struct plan_block {
|
||||
#ifdef KINEMATICS_API
|
||||
float rate_multiplier; // Rate multiplier of this block.
|
||||
#endif
|
||||
#ifdef ENABLE_ACCELERATION_PROFILES
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
float acceleration_factor; // Stores the currently used acceleration factor.
|
||||
#endif
|
||||
// Stored spindle speed data used by spindle overrides and resuming methods.
|
||||
@@ -96,7 +96,7 @@ typedef struct {
|
||||
#ifdef KINEMATICS_API
|
||||
float rate_multiplier; // Feed rate multiplier.
|
||||
#endif
|
||||
#ifdef ENABLE_ACCELERATION_PROFILES
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
float acceleration_factor; // Stores the currently used acceleration factor.
|
||||
#endif
|
||||
#if ENABLE_PATH_BLENDING
|
||||
|
||||
+17
-51
@@ -210,9 +210,7 @@ PROGMEM const settings_t defaults = {
|
||||
.axis[X_AXIS].steps_per_mm = DEFAULT_X_STEPS_PER_MM,
|
||||
.axis[X_AXIS].max_rate = DEFAULT_X_MAX_RATE,
|
||||
.axis[X_AXIS].acceleration = (DEFAULT_X_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[X_AXIS].jerk = (DEFAULT_X_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[X_AXIS].max_travel = (-DEFAULT_X_MAX_TRAVEL),
|
||||
.axis[X_AXIS].dual_axis_offset = 0.0f,
|
||||
.axis[X_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
|
||||
@@ -225,9 +223,7 @@ PROGMEM const settings_t defaults = {
|
||||
.axis[Y_AXIS].max_rate = DEFAULT_Y_MAX_RATE,
|
||||
.axis[Y_AXIS].max_travel = (-DEFAULT_Y_MAX_TRAVEL),
|
||||
.axis[Y_AXIS].acceleration = (DEFAULT_Y_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[Y_AXIS].jerk = (DEFAULT_Y_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[Y_AXIS].dual_axis_offset = 0.0f,
|
||||
.axis[Y_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
|
||||
.axis[Y_AXIS].homing_seek_rate = DEFAULT_HOMING_SEEK_RATE,
|
||||
@@ -238,9 +234,7 @@ PROGMEM const settings_t defaults = {
|
||||
.axis[Z_AXIS].steps_per_mm = DEFAULT_Z_STEPS_PER_MM,
|
||||
.axis[Z_AXIS].max_rate = DEFAULT_Z_MAX_RATE,
|
||||
.axis[Z_AXIS].acceleration = (DEFAULT_Z_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[Z_AXIS].jerk = (DEFAULT_Z_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[Z_AXIS].max_travel = (-DEFAULT_Z_MAX_TRAVEL),
|
||||
.axis[Z_AXIS].dual_axis_offset = 0.0f,
|
||||
.axis[Z_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
|
||||
@@ -253,9 +247,7 @@ PROGMEM const settings_t defaults = {
|
||||
.axis[A_AXIS].steps_per_mm = DEFAULT_A_STEPS_PER_MM,
|
||||
.axis[A_AXIS].max_rate = DEFAULT_A_MAX_RATE,
|
||||
.axis[A_AXIS].acceleration =(DEFAULT_A_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[A_AXIS].jerk = (DEFAULT_A_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[A_AXIS].max_travel = (-DEFAULT_A_MAX_TRAVEL),
|
||||
.axis[A_AXIS].dual_axis_offset = 0.0f,
|
||||
.axis[A_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
|
||||
@@ -270,9 +262,7 @@ PROGMEM const settings_t defaults = {
|
||||
.axis[B_AXIS].steps_per_mm = DEFAULT_B_STEPS_PER_MM,
|
||||
.axis[B_AXIS].max_rate = DEFAULT_B_MAX_RATE,
|
||||
.axis[B_AXIS].acceleration = (DEFAULT_B_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[B_AXIS].jerk = (DEFAULT_B_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[B_AXIS].max_travel = (-DEFAULT_B_MAX_TRAVEL),
|
||||
.axis[B_AXIS].dual_axis_offset = 0.0f,
|
||||
.axis[B_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
|
||||
@@ -286,9 +276,7 @@ PROGMEM const settings_t defaults = {
|
||||
#ifdef C_AXIS
|
||||
.axis[C_AXIS].steps_per_mm = DEFAULT_C_STEPS_PER_MM,
|
||||
.axis[C_AXIS].acceleration = (DEFAULT_C_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[C_AXIS].jerk = (DEFAULT_C_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[C_AXIS].max_rate = DEFAULT_C_MAX_RATE,
|
||||
.axis[C_AXIS].max_travel = (-DEFAULT_C_MAX_TRAVEL),
|
||||
.axis[C_AXIS].dual_axis_offset = 0.0f,
|
||||
@@ -303,9 +291,7 @@ PROGMEM const settings_t defaults = {
|
||||
#ifdef U_AXIS
|
||||
.axis[U_AXIS].steps_per_mm = DEFAULT_U_STEPS_PER_MM,
|
||||
.axis[U_AXIS].acceleration = (DEFAULT_U_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[U_AXIS].jerk = (DEFAULT_U_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[U_AXIS].max_rate = DEFAULT_U_MAX_RATE,
|
||||
.axis[U_AXIS].max_travel = (-DEFAULT_U_MAX_TRAVEL),
|
||||
.axis[U_AXIS].dual_axis_offset = 0.0f,
|
||||
@@ -319,9 +305,7 @@ PROGMEM const settings_t defaults = {
|
||||
#ifdef V_AXIS
|
||||
.axis[V_AXIS].steps_per_mm = DEFAULT_V_STEPS_PER_MM,
|
||||
.axis[V_AXIS].acceleration = (DEFAULT_V_ACCELERATION * 60.0f * 60.0f),
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
.axis[V_AXIS].jerk = (DEFAULT_V_JERK * 60.0f * 60.0f * 60.0f),
|
||||
#endif
|
||||
.axis[V_AXIS].max_rate = DEFAULT_V_MAX_RATE,
|
||||
.axis[V_AXIS].max_travel = (-DEFAULT_V_MAX_TRAVEL),
|
||||
.axis[V_AXIS].dual_axis_offset = 0.0f,
|
||||
@@ -446,7 +430,7 @@ static char axis_dist[4] = "mm";
|
||||
static char axis_rate[8] = "mm/min";
|
||||
static char axis_accel[10] = "mm/sec^2";
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
static char axis_jerk[15] = "mm/sec^3";
|
||||
static char axis_jerk[10] = "mm/sec^3";
|
||||
#endif
|
||||
#if DELTA_ROBOT
|
||||
static char axis_steps[9] = "step/rev";
|
||||
@@ -499,29 +483,12 @@ bool settings_override_acceleration (uint8_t axis, float acceleration)
|
||||
} else {
|
||||
if(!override_backup.valid)
|
||||
save_override_backup();
|
||||
settings.axis[axis].acceleration = (override_backup.acceleration[axis] >= (acceleration * 60.0f * 60.0f)) ? (acceleration * 60.0f * 60.0f) : override_backup.acceleration[axis]; // Limited to max setting value
|
||||
settings.axis[axis].acceleration = acceleration * 60.0f * 60.0f; // Limit max to setting value?
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
//Acceleration Profiles for G187 P[x] in percent of maximum machine acceleration.
|
||||
float lookupfactor(uint8_t profile) {
|
||||
static const float lookup[5] = {
|
||||
1.0f, // 100% - Roughing - Max Acceleration Default
|
||||
0.8f, // 80% - Semi Roughing
|
||||
0.6f, // 60% - Semi Finish
|
||||
0.4f, // 40% - Finish
|
||||
0.2f, // 20% - Slow AF Mode
|
||||
};
|
||||
if (profile >= sizeof(lookup) / sizeof(lookup[0])) {
|
||||
profile = 0;
|
||||
}
|
||||
return lookup[profile];
|
||||
}
|
||||
#endif
|
||||
|
||||
// ---
|
||||
|
||||
static void homing_pulloff_init (float pulloff)
|
||||
@@ -1194,12 +1161,12 @@ static status_code_t set_axis_setting (setting_id_t setting, float value)
|
||||
break;
|
||||
|
||||
case Setting_AxisAcceleration:
|
||||
settings.axis[idx].acceleration = override_backup.acceleration[idx] = value * 60.0f * 60.0f; // Convert to mm/min^2 for grbl internal use.
|
||||
settings.axis[idx].acceleration = override_backup.acceleration[idx] = value * 60.0f * 60.0f; // Convert to mm/min^2 for internal use.
|
||||
break;
|
||||
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
case Setting_AxisJerk:
|
||||
settings.axis[idx].jerk = value * 60.0f * 60.0f * 60.0f; // Convert to mm/min^3 for grbl internal use.
|
||||
settings.axis[idx].jerk = value * 60.0f * 60.0f * 60.0f; // Convert to mm/min^3 for internal use.
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -1208,7 +1175,7 @@ static status_code_t set_axis_setting (setting_id_t setting, float value)
|
||||
bit_false(sys.homed.mask, bit(idx));
|
||||
system_add_rt_report(Report_Homed);
|
||||
}
|
||||
settings.axis[idx].max_travel = -value; // Store as negative for grbl internal use.
|
||||
settings.axis[idx].max_travel = -value; // Store as negative for internal use.
|
||||
if(settings.homing.flags.init_lock && (sys.homing.mask & sys.homed.mask) != sys.homing.mask) {
|
||||
system_raise_alarm(Alarm_HomingRequired);
|
||||
grbl.report.feedback_message(Message_HomingCycleRequired);
|
||||
@@ -1262,7 +1229,8 @@ static float get_float (setting_id_t setting)
|
||||
{
|
||||
float value = 0.0f;
|
||||
|
||||
if(setting >= Setting_AxisSettingsBase && setting <= Setting_AxisSettingsMax) {
|
||||
if((setting >= Setting_AxisSettingsBase && setting <= Setting_AxisSettingsMax) ||
|
||||
(setting >= Setting_AxisSettingsBase1 && setting <= Setting_AxisSettingsMax1)) {
|
||||
|
||||
uint_fast8_t idx;
|
||||
|
||||
@@ -1281,7 +1249,7 @@ static float get_float (setting_id_t setting)
|
||||
break;
|
||||
|
||||
case Setting_AxisMaxTravel:
|
||||
value = -settings.axis[idx].max_travel; // Store as negative for grbl internal use.
|
||||
value = -settings.axis[idx].max_travel; // Store as negative for internal use.
|
||||
break;
|
||||
|
||||
#if ENABLE_BACKLASH_COMPENSATION
|
||||
@@ -1302,25 +1270,15 @@ static float get_float (setting_id_t setting)
|
||||
value = settings.axis[idx].homing_seek_rate;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(setting >= Setting_AxisSettingsBase1 && setting <= Setting_AxisSettingsMax1) {
|
||||
|
||||
uint_fast8_t idx;
|
||||
|
||||
switch(settings_get_axis_base(setting, &idx)) {
|
||||
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
case Setting_AxisJerk:
|
||||
value = settings.axis[idx].jerk / (60.0f * 60.0f * 60.0f); // Convert from mm/min^3 to mm/sec^3.
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else switch(setting) {
|
||||
} else switch(setting) {
|
||||
|
||||
case Setting_HomingFeedRate:
|
||||
value = settings.axis[0].homing_feed_rate;
|
||||
@@ -3246,6 +3204,14 @@ void settings_init (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
uint_fast8_t idx = N_AXIS;
|
||||
do {
|
||||
if(settings.axis[--idx].jerk == 0.0f)
|
||||
settings.axis[idx].jerk = settings.axis[idx].acceleration * 60.0f * 10.0f;
|
||||
} while(idx);
|
||||
#endif
|
||||
|
||||
setting_details_t *details = setting_details.next;
|
||||
|
||||
if(details) do {
|
||||
|
||||
@@ -1081,10 +1081,6 @@ bool settings_read_coord_data(coord_system_id_t id, float (*coord_data)[N_AXIS])
|
||||
// Temporarily override acceleration, if 0 restore to configured setting value
|
||||
bool settings_override_acceleration (uint8_t axis, float acceleration);
|
||||
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
float lookupfactor (uint8_t profile);
|
||||
#endif
|
||||
|
||||
void settings_register (setting_details_t *details);
|
||||
setting_details_t *settings_get_details (void);
|
||||
bool settings_is_group_available (setting_group_t group);
|
||||
|
||||
+10
-2
@@ -76,14 +76,20 @@ static parking_data_t park = {0};
|
||||
|
||||
static void state_spindle_restore (spindle_t *spindle)
|
||||
{
|
||||
if(spindle->hal)
|
||||
if(spindle->hal) {
|
||||
if(grbl.on_spindle_programmed)
|
||||
grbl.on_spindle_programmed(spindle->hal, spindle->state, spindle->rpm, spindle->rpm_mode);
|
||||
spindle_restore(spindle->hal, spindle->state, spindle->rpm);
|
||||
}
|
||||
}
|
||||
|
||||
static void state_spindle_set_state (spindle_t *spindle)
|
||||
{
|
||||
if(spindle->hal)
|
||||
if(spindle->hal) {
|
||||
if(grbl.on_spindle_programmed)
|
||||
grbl.on_spindle_programmed(spindle->hal, spindle->state, spindle->rpm, spindle->rpm_mode);
|
||||
spindle_set_state(spindle->hal, spindle->state, spindle->rpm);
|
||||
}
|
||||
}
|
||||
|
||||
static void state_restore_conditions (restore_condition_t *condition)
|
||||
@@ -360,6 +366,8 @@ void state_suspend_manager (void)
|
||||
// Handles beginning of spindle stop
|
||||
if (sys.override.spindle_stop.initiate) {
|
||||
sys.override.spindle_stop.value = 0; // Clear stop override state
|
||||
if(grbl.on_spindle_programmed)
|
||||
grbl.on_spindle_programmed(restore_condition.spindle[restore_condition.spindle_num].hal, (spindle_state_t){0}, 0.0f, 0);
|
||||
spindle_set_state(restore_condition.spindle[restore_condition.spindle_num].hal, (spindle_state_t){0}, 0.0f); // De-energize
|
||||
sys.override.spindle_stop.enabled = On; // Set stop override state to enabled, if de-energized.
|
||||
if(grbl.on_override_changed)
|
||||
|
||||
@@ -223,7 +223,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
|
||||
}
|
||||
|
||||
|
||||
/* "The Stepper Driver Interrupt" - This timer interrupt is the workhorse of Grbl. Grbl employs
|
||||
/* "The Stepper Driver Interrupt" - This timer interrupt is the workhorse of grblHAL. grblHAL employs
|
||||
the venerable Bresenham line algorithm to manage and exactly synchronize multi-axis moves.
|
||||
Unlike the popular DDA algorithm, the Bresenham algorithm is not susceptible to numerical
|
||||
round-off errors and only requires fast integer counters, meaning low computational overhead
|
||||
@@ -232,7 +232,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
|
||||
pulse trains, or aliasing, which can lead to strange audible noises or shaking. This is
|
||||
particularly noticeable or may cause motion issues at low step frequencies (0-5kHz), but
|
||||
is usually not a physical problem at higher frequencies, although audible.
|
||||
To improve Bresenham multi-axis performance, Grbl uses what we call an Adaptive Multi-Axis
|
||||
To improve Bresenham multi-axis performance, grblHAL uses what we call an Adaptive Multi-Axis
|
||||
Step Smoothing (AMASS) algorithm, which does what the name implies. At lower step frequencies,
|
||||
AMASS artificially increases the Bresenham resolution without effecting the algorithm's
|
||||
innate exactness. AMASS adapts its resolution levels automatically depending on the step
|
||||
@@ -246,7 +246,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
|
||||
Level 2, we simply bit-shift again, so the non-dominant Bresenham axes can step within any
|
||||
of the four ISR ticks, the dominant axis steps every four ISR ticks, and quadruple the
|
||||
stepper ISR frequency. And so on. This, in effect, virtually eliminates multi-axis aliasing
|
||||
issues with the Bresenham algorithm and does not significantly alter Grbl's performance, but
|
||||
issues with the Bresenham algorithm and does not significantly alter grblHAL's performance, but
|
||||
in fact, more efficiently utilizes unused CPU cycles overall throughout all configurations.
|
||||
AMASS retains the Bresenham algorithm exactness by requiring that it always executes a full
|
||||
Bresenham step, regardless of AMASS Level. Meaning that for an AMASS Level 2, all four
|
||||
@@ -263,9 +263,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
|
||||
after each pulse. The bresenham line tracer algorithm controls all stepper outputs
|
||||
simultaneously with these two interrupts.
|
||||
|
||||
NOTE: This interrupt must be as efficient as possible and complete before the next ISR tick,
|
||||
which for Grbl must be less than 33.3usec (@30kHz ISR rate). Oscilloscope measured time in
|
||||
ISR is 5usec typical and 25usec maximum, well below requirement.
|
||||
NOTE: This interrupt must be as efficient as possible and complete before the next ISR tick.
|
||||
NOTE: This ISR expects at least one step to be executed per segment.
|
||||
*/
|
||||
|
||||
@@ -393,8 +391,10 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void)
|
||||
st_go_idle();
|
||||
|
||||
// Ensure pwm is set properly upon completion of rate-controlled motion.
|
||||
if (st.exec_block->dynamic_rpm && st.exec_block->spindle->cap.laser)
|
||||
if(st.exec_block->dynamic_rpm && st.exec_block->spindle->cap.laser) {
|
||||
prep.current_spindle_rpm = 0.0f;
|
||||
st.exec_block->spindle->update_pwm(st.exec_block->spindle, st.exec_block->spindle->pwm_off_value);
|
||||
}
|
||||
|
||||
st.exec_block = NULL;
|
||||
system_set_exec_state_flag(EXEC_CYCLE_COMPLETE); // Flag main program for cycle complete
|
||||
@@ -1033,7 +1033,7 @@ void st_prep_buffer (void)
|
||||
However, since floats have only 7.2 significant digits, long moves with extremely
|
||||
high step counts can exceed the precision of floats, which can lead to lost steps.
|
||||
Fortunately, this scenario is highly unlikely and unrealistic in CNC machines
|
||||
supported by Grbl (i.e. exceeding 10 meters axis travel at 200 step/mm).
|
||||
supported by grblHAL (i.e. exceeding 10 meters axis travel at 200 step/mm).
|
||||
*/
|
||||
float step_dist_remaining = prep.steps_per_mm * mm_remaining; // Convert mm_remaining to steps
|
||||
uint32_t n_steps_remaining = (uint32_t)ceilf(step_dist_remaining); // Round-up current steps remaining
|
||||
@@ -1056,7 +1056,7 @@ void st_prep_buffer (void)
|
||||
// compensate, we track the time to execute the previous segment's partial step and simply
|
||||
// apply it with the partial step distance to the current segment, so that it minutely
|
||||
// adjusts the whole segment rate to keep step output exact. These rate adjustments are
|
||||
// typically very small and do not adversely effect performance, but ensures that Grbl
|
||||
// typically very small and do not adversely effect performance, but ensures that grblHAL
|
||||
// outputs the exact acceleration and velocity profiles as computed by the planner.
|
||||
dt += prep.dt_remainder; // Apply previous segment partial step execute time
|
||||
float inv_rate = dt / ((float)prep.steps_remaining - step_dist_remaining); // Compute adjusted step rate inverse
|
||||
|
||||
Reference in New Issue
Block a user