diff --git a/doc/log/commit_log_v1.1.txt b/doc/log/commit_log_v1.1.txt index 2acc620..15d8de7 100644 --- a/doc/log/commit_log_v1.1.txt +++ b/doc/log/commit_log_v1.1.txt @@ -1,3 +1,18 @@ +---------------- +Date: 2016-10-23 +Author: Sonny Jeon +Subject: Spindle speed close to minimum fix. + +- When spindle speed is close to the minimum rpm, the PWM value would +be zero or lower than allowed. The computation error was caused by +setting the minimum PWM value to zero, when it should have been 1. + +- Added a compiler check for minimum PWM to be greater than zero. + +- Moved some of the spindle PWM macros to a more appropriate place in +the cpu_map.h. + + ---------------- Date: 2016-10-22 Author: Will Winder diff --git a/grbl/config.h b/grbl/config.h index 8449c8a..e80e9a9 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -281,11 +281,11 @@ // and agressive streaming. There is also a busy and an idle refresh count, which sets up Grbl to send // refreshes more often when its not doing anything important. With a good GUI, this data doesn't need // to be refreshed very often, on the order of a several seconds. -// NOTE: The refresh count cannot be set to zero and must be one or greater. +// NOTE: WCO refresh must be 2 or greater. OVR refresh must be 1 or greater. #define REPORT_OVR_REFRESH_BUSY_COUNT 20 // (1-255) #define REPORT_OVR_REFRESH_IDLE_COUNT 10 // (1-255) Must be less than or equal to the busy count -#define REPORT_WCO_REFRESH_BUSY_COUNT 30 // (1-255) -#define REPORT_WCO_REFRESH_IDLE_COUNT 10 // (1-255) Must be less than or equal to the busy count +#define REPORT_WCO_REFRESH_BUSY_COUNT 30 // (2-255) +#define REPORT_WCO_REFRESH_IDLE_COUNT 10 // (2-255) Must be less than or equal to the busy count // ----- COMPATIBILITY OPTIONS: ------ // The following options enabled the old-style v0.9 Grbl interface. @@ -357,11 +357,13 @@ // Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled. // The PWM pin will still read 0V when the spindle is disabled. Most users will not need this option, but // it may be useful in certain scenarios. This minimum PWM settings coincides with the spindle rpm minimum -// setting, like rpm max to max PWM. So the variable spindle pin will not output the voltage range between -// 0V for disabled and the voltage set by the minimum PWM for minimum rpm. +// setting, like rpm max to max PWM. This is handy if you need a larger voltage difference between 0V disabled +// and the voltage set by the minimum PWM for minimum rpm. This difference is 0.02V per PWM value. So, when +// minimum PWM is at 1, only 0.02 volts separate enabled and disabled. At PWM 5, this would be 0.1V. Keep +// in mind that you will begin to lose PWM resolution with increased minimum PWM values, since you have less +// and less range over the total 256 PWM levels to signal different spindle speeds. // NOTE: Compute duty cycle at the minimum PWM by this equation: (% duty cycle)=(SPINDLE_MINIMUM_PWM/256)*100 -// Value must be greater than zero. -// #define SPINDLE_MINIMUM_PWM 5 // Default disabled. Uncomment to enable. Integer (1-255) +// #define SPINDLE_MINIMUM_PWM 5 // Default disabled. Uncomment to enable. Must be greater than zero. Integer (1-255). // By default on a 328p(Uno), Grbl combines the variable spindle PWM and the enable into one pin to help // preserve I/O pins. For certain setups, these may need to be separate pins. This configure option uses @@ -511,6 +513,8 @@ // Enable the '$I=(string)' build info write command. If disabled, any existing build info data must // be placed into EEPROM via external means with a valid checksum value. This macro option is useful // to prevent this data from being over-written by a user, when used to store OEM product data. +// NOTE: If disabled and to ensure Grbl can never alter the build info line, you'll also need to enable +// the SETTING_RESTORE_ALL macro above and remove SETTINGS_RESTORE_BUILD_INFO from the mask. // NOTE: See the included grblWrite_BuildInfo.ino example file to write this string seperately. #define ENABLE_BUILD_INFO_WRITE_COMMAND // '$I=' Default enabled. Comment to disable. @@ -558,34 +562,7 @@ #define PARKING_PULLOUT_RATE 100.0 // Pull-out/plunge slow feed rate in mm/min. #define PARKING_PULLOUT_INCREMENT 5.0 // Spindle pull-out and plunge distance in mm. Incremental distance. // Must be positive value or equal to zero. - - -// --------------------------------------------------------------------------------------- -// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES: - -#ifndef HOMING_CYCLE_0 - #error "Required HOMING_CYCLE_0 not defined." -#endif - -#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE) - #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled" -#endif - -#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P) - #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor" -#endif - -#if defined(PARKING_ENABLE) - #if defined(HOMING_FORCE_SET_ORIGIN) - #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time." - #endif -#endif - -#if defined(SPINDLE_MINIMUM_PWM) - #if !(SPINDLE_MINIMUM_PWM > 0) - #error "SPINDLE_MINIMUM_PWM must be greater than zero." - #endif -#endif + /* --------------------------------------------------------------------------------------- OEM Single File Configuration Option diff --git a/grbl/coolant_control.c b/grbl/coolant_control.c index 6b37e80..418cdac 100644 --- a/grbl/coolant_control.c +++ b/grbl/coolant_control.c @@ -107,7 +107,7 @@ void coolant_set_state(uint8_t mode) #endif } - sys.report_ovr_counter = REPORT_OVR_REFRESH_BUSY_COUNT; // Set to report change immediately + sys.report_ovr_counter = 0; // Set to report change immediately } diff --git a/grbl/grbl.h b/grbl/grbl.h index 1a9abd9..b662c9d 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "1.1d" -#define GRBL_VERSION_BUILD "20161023" +#define GRBL_VERSION_BUILD "20161024" // Define standard libraries used by Grbl. #include @@ -61,4 +61,45 @@ #include "stepper.h" #include "jog.h" +// --------------------------------------------------------------------------------------- +// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES: + +#ifndef HOMING_CYCLE_0 + #error "Required HOMING_CYCLE_0 not defined." +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled" +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor" +#endif + +#if defined(PARKING_ENABLE) + #if defined(HOMING_FORCE_SET_ORIGIN) + #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time." + #endif +#endif + +#if defined(SPINDLE_MINIMUM_PWM) + #if !(SPINDLE_MINIMUM_PWM > 0) + #error "SPINDLE_MINIMUM_PWM must be greater than zero." + #endif +#endif + +#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT) + #error "WCO busy refresh is less than idle refresh." +#endif +#if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT) + #error "Override busy refresh is less than idle refresh." +#endif +#if (REPORT_WCO_REFRESH_IDLE_COUNT < 2) + #error "WCO refresh must be greater than one." +#endif +#if (REPORT_OVR_REFRESH_IDLE_COUNT < 1) + #error "Override refresh must be greater than zero." +#endif +// --------------------------------------------------------------------------------------- + #endif diff --git a/grbl/main.c b/grbl/main.c index 72c3af3..be0b4ac 100644 --- a/grbl/main.c +++ b/grbl/main.c @@ -34,10 +34,17 @@ int main(void) stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt - memset(&sys, 0, sizeof(system_t)); // Clear all system variables - sys.abort = true; // Set abort to complete initialization + memset(sys_position,0,sizeof(sys_position)); // Clear machine position. sei(); // Enable interrupts + // Initialize system state. + #ifdef FORCE_INITIALIZATION_ALARM + // Force Grbl into an ALARM state upon a power-cycle or hard reset. + sys.state = STATE_ALARM; + #else + sys.state = STATE_IDLE; + #endif + // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing @@ -49,17 +56,23 @@ int main(void) if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif - // Force Grbl into an ALARM state upon a power-cycle or hard reset. - #ifdef FORCE_INITIALIZATION_ALARM - sys.state = STATE_ALARM; - #endif - // Grbl initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. for(;;) { - // TODO: Separate configure task that require interrupts to be disabled, especially upon - // a system abort and ensuring any active interrupts are cleanly reset. + // Reset system variables. + uint8_t prior_state = sys.state; + memset(&sys, 0, sizeof(system_t)); // Clear system struct variable. + sys.state = prior_state; + sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100% + sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100% + sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100% + memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position. + sys_probe_state = 0; + sys_rt_exec_state = 0; + sys_rt_exec_alarm = 0; + sys_rt_exec_motion_override = 0; + sys_rt_exec_accessory_override = 0; // Reset Grbl primary systems. serial_reset_read_buffer(); // Clear serial read buffer @@ -75,22 +88,6 @@ int main(void) plan_sync_position(); gc_sync_position(); - // Reset system variables. - sys.abort = sys.suspend = sys.soft_limit = false; - sys.step_control = STEP_CONTROL_NORMAL_OP; - sys.f_override = DEFAULT_FEED_OVERRIDE; - sys.r_override = DEFAULT_RAPID_OVERRIDE; - sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; - sys.spindle_stop_ovr = 0; - sys.report_wco_counter = REPORT_WCO_REFRESH_BUSY_COUNT; // Set to include in first report. - sys.report_ovr_counter = REPORT_OVR_REFRESH_BUSY_COUNT; // Set to include in first report. - - sys_probe_state = 0; - sys_rt_exec_state = 0; - sys_rt_exec_alarm = 0; - sys_rt_exec_motion_override = 0; - sys_rt_exec_accessory_override = 0; - // Print welcome message. Indicates an initialization has occured at power-up or with a reset. report_init_message(); diff --git a/grbl/protocol.c b/grbl/protocol.c index 69f0168..01cbd93 100644 --- a/grbl/protocol.c +++ b/grbl/protocol.c @@ -424,7 +424,7 @@ void protocol_exec_rt_system() if ((new_f_override != sys.f_override) || (new_r_override != sys.r_override)) { sys.f_override = new_f_override; sys.r_override = new_r_override; - sys.report_ovr_counter = REPORT_OVR_REFRESH_BUSY_COUNT; // Set to report change immediately + sys.report_ovr_counter = 0; // Set to report change immediately plan_update_velocity_profile_parameters(); plan_cycle_reinitialize(); } @@ -447,7 +447,7 @@ void protocol_exec_rt_system() if (last_s_override != sys.spindle_speed_ovr) { bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); sys.spindle_speed_ovr = last_s_override; - sys.report_ovr_counter = REPORT_OVR_REFRESH_BUSY_COUNT; // Set to report change immediately + sys.report_ovr_counter = 0; // Set to report change immediately } if (rt_exec & EXEC_SPINDLE_OVR_STOP) { @@ -512,11 +512,6 @@ static void protocol_exec_rt_suspend() float retract_waypoint = PARKING_PULLOUT_INCREMENT; plan_line_data_t plan_data; plan_line_data_t *pl_data = &plan_data; - memset(pl_data,0,sizeof(plan_line_data_t)); - pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); - #ifdef USE_LINE_NUMBERS - pl_data->line_number = PARKING_MOTION_LINE_NUMBER; - #endif #endif plan_block_t *block = plan_get_current_block(); @@ -555,9 +550,16 @@ static void protocol_exec_rt_suspend() #ifndef PARKING_ENABLE spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize - coolant_set_state(COOLANT_DISABLE);; // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize #else + + // Initialize planner state data + memset(pl_data,0,sizeof(plan_line_data_t)); + pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + #ifdef USE_LINE_NUMBERS + pl_data->line_number = PARKING_MOTION_LINE_NUMBER; + #endif // Get current position and store restore location and spindle retract waypoint. system_convert_array_steps_to_mpos(parking_target,sys_position); @@ -597,7 +599,7 @@ static void protocol_exec_rt_suspend() // Parking motion not possible. Just disable the spindle and coolant. // NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately. spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize - coolant_set_state(COOLANT_DISABLE);; // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize } @@ -672,7 +674,11 @@ static void protocol_exec_rt_suspend() // Regardless if the retract parking motion was a valid/safe motion or not, the // restore parking motion should logically be valid, either by returning to the // original position through valid machine space or by not moving at all. + // NOTE: If retract is restarted, spindle and coolant states will be cleared in + // the beginning of the retract routine. pl_data->feed_rate = PARKING_PULLOUT_RATE; + pl_data->condition = restore_condition; + pl_data->spindle_speed = restore_spindle_speed; mc_parking_motion(restore_target, pl_data); } } diff --git a/grbl/report.c b/grbl/report.c index 0b2e6c7..23fd148 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -803,7 +803,7 @@ void report_realtime_status() float wco[N_AXIS]; if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE) || - (sys.report_wco_counter >= REPORT_WCO_REFRESH_BUSY_COUNT) ) { + (sys.report_wco_counter == 0) ) { for (idx=0; idx< N_AXIS; idx++) { // Apply work coordinate offsets and tool length offset to current position. wco[idx] = gc_state.coord_system[idx]+gc_state.coord_offset[idx]; @@ -883,23 +883,23 @@ void report_realtime_status() #endif #ifdef REPORT_FIELD_WORK_COORD_OFFSET - if (sys.report_wco_counter++ >= REPORT_WCO_REFRESH_BUSY_COUNT) { + if (sys.report_wco_counter > 0) { sys.report_wco_counter--; } + else { if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { - sys.report_wco_counter = 1; // Reset counter for slow refresh - } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-REPORT_WCO_REFRESH_IDLE_COUNT+1); } - if (sys.report_ovr_counter >= REPORT_OVR_REFRESH_BUSY_COUNT) { - sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Set override on next report. - } + sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT-1); } + if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report. printPgmString(PSTR("|WCO:")); report_util_axis_values(wco); } #endif #ifdef REPORT_FIELD_OVERRIDES - if (sys.report_ovr_counter++ >= REPORT_OVR_REFRESH_BUSY_COUNT) { + if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; } + else { if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { - sys.report_ovr_counter = 1; // Reset counter for slow refresh - } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-REPORT_OVR_REFRESH_IDLE_COUNT+1); } + sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT-1); } printPgmString(PSTR("|Ov:")); print_uint8_base10(sys.f_override); serial_write(','); diff --git a/grbl/spindle_control.c b/grbl/spindle_control.c index cfddcc9..b799830 100644 --- a/grbl/spindle_control.c +++ b/grbl/spindle_control.c @@ -202,7 +202,7 @@ void spindle_stop() } - sys.report_ovr_counter = REPORT_OVR_REFRESH_BUSY_COUNT; // Set to report change immediately + sys.report_ovr_counter = 0; // Set to report change immediately } diff --git a/grbl/system.c b/grbl/system.c index 0a8172c..14f56fd 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -279,7 +279,7 @@ void system_flag_wco_change() #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE protocol_buffer_synchronize(); #endif - sys.report_wco_counter = REPORT_WCO_REFRESH_BUSY_COUNT; + sys.report_wco_counter = 0; } diff --git a/grbl/system.h b/grbl/system.h index 44bcc6b..a4ca818 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -94,7 +94,7 @@ #define SUSPEND_JOG_CANCEL bit(7) // Indicates a jog cancel in process and to reset buffers when complete. // Define step segment generator state flags. -#define STEP_CONTROL_NORMAL_OP 0 +#define STEP_CONTROL_NORMAL_OP 0 // Must be zero. #define STEP_CONTROL_END_MOTION bit(0) #define STEP_CONTROL_EXECUTE_HOLD bit(1) #define STEP_CONTROL_EXECUTE_SYS_MOTION bit(2) @@ -124,8 +124,8 @@ // Define global system variables typedef struct { - uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t state; // Tracks the current system state of Grbl. + uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door. uint8_t soft_limit; // Tracks soft limit errors for the state machine. (boolean) uint8_t step_control; // Governs the step segment generator depending on system state. @@ -147,7 +147,7 @@ extern system_t sys; int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. -volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. +volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.