From e8a0aeea269b9f10433f65060093b1327010d413 Mon Sep 17 00:00:00 2001 From: Terje Io Date: Tue, 31 Dec 2024 08:48:33 +0100 Subject: [PATCH] Fix for laser incorrectly enabled in laser mode when M3S 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. --- README.md | 4 +-- changelog.md | 25 +++++++++++++++++- config.h | 13 ++++++--- crossbar.h | 4 +-- gcode.c | 48 +++++++++++++++++++++++----------- gcode.h | 17 +++++++++++- grbl.h | 2 +- pin_bits_masks.h | 16 +++++++++--- planner.c | 7 +++-- planner.h | 4 +-- settings.c | 68 ++++++++++++------------------------------------ settings.h | 4 --- state_machine.c | 12 +++++++-- stepper.c | 18 ++++++------- 14 files changed, 143 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 94086c5..34f9507 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/changelog.md b/changelog.md index efc9c92..ee5f551 100644 --- a/changelog.md +++ b/changelog.md @@ -1,10 +1,33 @@ ## grblHAL changelog +Build 20241230 + +Core: + +* Fix for laser incorrectly enabled in laser mode when `M3S` 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. + +--- + 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: diff --git a/config.h b/config.h index 1e4a57c..0ff7883 100644 --- a/config.h +++ b/config.h @@ -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 diff --git a/crossbar.h b/crossbar.h index 7fd5f88..2bc1287 100644 --- a/crossbar.h +++ b/crossbar.h @@ -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. diff --git a/gcode.c b/gcode.c index 125abf2..8029762 100644 --- a/gcode.c +++ b/gcode.c @@ -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 diff --git a/gcode.h b/gcode.h index 4ec0b41..6f02bf7 100644 --- a/gcode.h +++ b/gcode.h @@ -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_ diff --git a/grbl.h b/grbl.h index eef18da..ebb5817 100644 --- a/grbl.h +++ b/grbl.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" diff --git a/pin_bits_masks.h b/pin_bits_masks.h index 5c16c43..d5ad4a5 100644 --- a/pin_bits_masks.h +++ b/pin_bits_masks.h @@ -127,6 +127,14 @@ #endif #endif +#ifndef SD_DETECT_BIT +#ifdef SD_DETECT_PIN +#define SD_DETECT_BIT (1<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 } diff --git a/planner.h b/planner.h index 4cb7213..6b872f7 100644 --- a/planner.h +++ b/planner.h @@ -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 diff --git a/settings.c b/settings.c index d336e5e..8de9ba9 100644 --- a/settings.c +++ b/settings.c @@ -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 { diff --git a/settings.h b/settings.h index 471d857..d9c6c31 100644 --- a/settings.h +++ b/settings.h @@ -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); diff --git a/state_machine.c b/state_machine.c index a60c654..50d2f4f 100644 --- a/state_machine.c +++ b/state_machine.c @@ -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) diff --git a/stepper.c b/stepper.c index 71011db..8acc1f8 100644 --- a/stepper.c +++ b/stepper.c @@ -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