v1.1e: New laser features. G-code parser refactoring. CoreXY homing fix.

- Increment to v1.1e due to new laser features.

- After several discussions with some prominent laser people, a few
tweaks to the new laser mode has been installed.

- LASER: M3 behaves in a constant power mode.

- LASER: M4 behaves in a dynamic power mode, where the laser power is
automatically adjusted based on how fast Grbl is moving relative to the
programmed feed rate. This is the same as the  CONSTANT_POWER_PER_RATE
config.h option in the last version. NOTE: When not in motion in M4,
Grbl automatically turns off the laser. Again, it only operates while
moving!

- LASER: Only G1, G2, and G3 motion modes will turn on the laser. So,
this means that G0, G80 motion modes will always keep the laser
disabled. No matter if M3/M4 are active!

- LASER: A spindle stop override is automatically invoked when a laser
is put in a feed hold. This behavior may be disabled by a config.h
option.

- Lots of little tweaks to the g-code parser to help streamline it a
bit. It should no effect how it operates. Generally just added a parser
flag to track and execute certain scenarios a little more clearly.

- Jog motions now allow line numbers to be passed to it and will be
displayed in the status reports.

- Fixed a CoreXY homing bug.

- Fixed an issue when $13 is changed, WCO isn’t sent immediately.

- Altered how spindle PWM is set in the stepper ISR. Updated on a step
segment basis now. May need to change this back if there are any
oddities from doing this.

- Updated some documentation. Clarified why M0 no longer showing up in
$G and why a `1.` floating point values are shown with no decimals,
like so `1`.
This commit is contained in:
Sonny Jeon
2016-12-03 18:02:45 -07:00
parent 998f23b9ce
commit b753c542c7
18 changed files with 219 additions and 145 deletions

View File

@ -62,11 +62,7 @@ typedef struct {
uint32_t step_event_count;
uint8_t direction_bits;
#ifdef VARIABLE_SPINDLE
#ifdef LASER_CONSTANT_POWER_PER_RATE
uint8_t is_pwm_rate_adjusted; // Tracks motions that require constant laser power/rate
#else
uint8_t spindle_pwm;
#endif
uint8_t is_pwm_rate_adjusted; // Tracks motions that require constant laser power/rate
#endif
} st_block_t;
static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1];
@ -84,8 +80,8 @@ typedef struct {
#else
uint8_t prescaler; // Without AMASS, a prescaler is required to adjust for slow timing.
#endif
#ifdef LASER_CONSTANT_POWER_PER_RATE
uint8_t rate_adjusted_pwm;
#ifdef VARIABLE_SPINDLE
uint8_t spindle_pwm;
#endif
} segment_t;
static segment_t segment_buffer[SEGMENT_BUFFER_SIZE];
@ -159,8 +155,9 @@ typedef struct {
float accelerate_until; // Acceleration ramp end measured from end of block (mm)
float decelerate_after; // Deceleration ramp start measured from end of block (mm)
#ifdef LASER_CONSTANT_POWER_PER_RATE
#ifdef VARIABLE_SPINDLE
float inv_rate; // Used by PWM laser mode to speed up segment calculations.
uint8_t current_spindle_pwm;
#endif
} st_prep_t;
static st_prep_t prep;
@ -360,20 +357,14 @@ ISR(TIMER1_COMPA_vect)
#ifdef VARIABLE_SPINDLE
// Set real-time spindle output as segment is loaded, just prior to the first step.
#ifdef LASER_CONSTANT_POWER_PER_RATE
spindle_set_speed(st.exec_segment->rate_adjusted_pwm);
#else
spindle_set_speed(st.exec_block->spindle_pwm);
#endif
spindle_set_speed(st.exec_segment->spindle_pwm);
#endif
} else {
// Segment buffer empty. Shutdown.
st_go_idle();
#ifdef LASER_CONSTANT_POWER_PER_RATE
// Ensure pwm is set properly upon completion of rate-controlled motion.
if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); }
#endif
// Ensure pwm is set properly upon completion of rate-controlled motion.
if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); }
system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end
return; // Nothing to do but exit.
}
@ -664,16 +655,16 @@ void st_prep_buffer()
prep.current_speed = sqrt(pl_block->entry_speed_sqr);
}
#ifdef LASER_CONSTANT_POWER_PER_RATE
// Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the
// spindle off.
st_prep_block->is_pwm_rate_adjusted = false;
if (settings.flags & BITFLAG_LASER_MODE) {
// Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the
// spindle off.
st_prep_block->is_pwm_rate_adjusted = false;
if (settings.flags & BITFLAG_LASER_MODE) {
if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) {
// Pre-compute inverse programmed rate to speed up PWM updating per step segment.
prep.inv_rate = 1.0/pl_block->programmed_rate;
if (!(pl_block->condition & PL_COND_MOTION_MASK)) { st_prep_block->is_pwm_rate_adjusted = true; }
st_prep_block->is_pwm_rate_adjusted = true;
}
#endif
}
}
/* ---------------------------------------------------------------------------------
@ -881,32 +872,23 @@ void st_prep_buffer()
/* -----------------------------------------------------------------------------------
Compute spindle speed PWM output for step segment
*/
#ifdef LASER_CONSTANT_POWER_PER_RATE
if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) {
if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
float rpm = pl_block->spindle_speed;
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); }
// If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE)
// but this would be instantaneous only and during a motion. May not matter at all.
prep_segment->rate_adjusted_pwm = spindle_compute_pwm_value(rpm);
} else {
sys.spindle_speed = 0.0;
prep_segment->rate_adjusted_pwm = SPINDLE_PWM_OFF_VALUE;
}
bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM);
if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) {
if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
float rpm = pl_block->spindle_speed;
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); }
// If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE)
// but this would be instantaneous only and during a motion. May not matter at all.
prep.current_spindle_pwm = spindle_compute_pwm_value(rpm);
} else {
sys.spindle_speed = 0.0;
prep.current_spindle_pwm = SPINDLE_PWM_OFF_VALUE;
}
#else
if (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM) {
if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
st_prep_block->spindle_pwm = spindle_compute_pwm_value(pl_block->spindle_speed);
} else {
sys.spindle_speed = 0.0;
st_prep_block->spindle_pwm = SPINDLE_PWM_OFF_VALUE;
}
bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM);
}
#endif
bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM);
}
prep_segment->spindle_pwm = prep.current_spindle_pwm; // Reload segment PWM value
#endif
/* -----------------------------------------------------------------------------------