Improved constant laser power per rate mode. Re-factored for flash size. Minor bug fixes.
- NOTE: This commit has largely been untested. - Constant laser power per rate mode has been improved. Altered its implementation to be more responsive and accurate. - Based on LaserWeb dev feedback, only G1, G2, and G3 moves operate with constant laser power mode. Meaning that G0, G38.x, and $J jogging motions operate without it and will keep a constant power output. This was specifically requested as a way to focus the laser by keeping the laser on when not moving. Operationally, this shouldn’t alter how the laser mode operates. - Re-factored parts of the g-code parser and g-code state reports to save a few hundred bytes of flash. What was done makes the code a bit more unreadable (bad), but the flash space was in dire need. So, I’m willing to live with it for now. - Fixed a problem with $G g-code state reports. Showed `M0` program pause during a run state. Now fixed to show nothing during a run state. Also, `M30` program end was shown as `M2`. This was also corrected. - Improved spindle stop override responsiveness by removing the enforced spindle restoring delay. It’s not needed for a feature that is user controlled. - Fixed a bug with G2/3 arcs in inverse time mode. - Updated the interface.md document to make it more clear how WPos: or MPos: can be calculated from WCO:. Some GUI devs have failed to catch this in the documentation.
This commit is contained in:
@ -58,12 +58,16 @@
|
||||
// discarded when entirely consumed and completed by the segment buffer. Also, AMASS alters this
|
||||
// data for its own use.
|
||||
typedef struct {
|
||||
uint8_t direction_bits;
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
uint8_t spindle_pwm;
|
||||
#endif
|
||||
uint32_t steps[N_AXIS];
|
||||
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
|
||||
#endif
|
||||
} st_block_t;
|
||||
static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1];
|
||||
|
||||
@ -72,14 +76,17 @@ static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1];
|
||||
// planner buffer. Once "checked-out", the steps in the segments buffer cannot be modified by
|
||||
// the planner, where the remaining planner block steps still can.
|
||||
typedef struct {
|
||||
uint16_t n_step; // Number of step events to be executed for this segment
|
||||
uint8_t st_block_index; // Stepper block data index. Uses this information to execute this segment.
|
||||
uint16_t cycles_per_tick; // Step distance traveled per ISR tick, aka step rate.
|
||||
uint16_t n_step; // Number of step events to be executed for this segment
|
||||
uint16_t cycles_per_tick; // Step distance traveled per ISR tick, aka step rate.
|
||||
uint8_t st_block_index; // Stepper block data index. Uses this information to execute this segment.
|
||||
#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
|
||||
uint8_t amass_level; // Indicates AMASS level for the ISR to execute this segment
|
||||
#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;
|
||||
#endif
|
||||
} segment_t;
|
||||
static segment_t segment_buffer[SEGMENT_BUFFER_SIZE];
|
||||
|
||||
@ -153,7 +160,7 @@ typedef struct {
|
||||
float decelerate_after; // Deceleration ramp start measured from end of block (mm)
|
||||
|
||||
#ifdef LASER_CONSTANT_POWER_PER_RATE
|
||||
float inv_rate; // Used by PWM laser mode
|
||||
float inv_rate; // Used by PWM laser mode to speed up segment calculations.
|
||||
#endif
|
||||
} st_prep_t;
|
||||
static st_prep_t prep;
|
||||
@ -353,12 +360,20 @@ ISR(TIMER1_COMPA_vect)
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
// Set real-time spindle output as segment is loaded, just prior to the first step.
|
||||
spindle_set_speed(st.exec_block->spindle_pwm);
|
||||
#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
|
||||
#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
|
||||
system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end
|
||||
return; // Nothing to do but exit.
|
||||
}
|
||||
@ -650,8 +665,14 @@ void st_prep_buffer()
|
||||
}
|
||||
|
||||
#ifdef LASER_CONSTANT_POWER_PER_RATE
|
||||
// Pre-compute inverse programmed rate to speed up PWM updating per step segment.
|
||||
prep.inv_rate = 1.0/pl_block->programmed_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) {
|
||||
// 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; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -746,7 +767,7 @@ void st_prep_buffer()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block.
|
||||
#endif
|
||||
}
|
||||
@ -856,34 +877,36 @@ void st_prep_buffer()
|
||||
}
|
||||
} while (mm_remaining > prep.mm_complete); // **Complete** Exit loop. Profile complete.
|
||||
|
||||
/* -----------------------------------------------------------------------------------
|
||||
Compute spindle speed PWM output for step segment
|
||||
*/
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
|
||||
/* -----------------------------------------------------------------------------------
|
||||
Compute spindle speed PWM output for step segment
|
||||
*/
|
||||
#ifdef LASER_CONSTANT_POWER_PER_RATE
|
||||
if ((settings.flags & BITFLAG_LASER_MODE) || (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_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);
|
||||
}
|
||||
#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
|
||||
if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) {
|
||||
float rpm = pl_block->spindle_speed;
|
||||
#ifdef LASER_CONSTANT_POWER_PER_RATE
|
||||
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
|
||||
if (settings.flags & BITFLAG_LASER_MODE) {
|
||||
// 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.
|
||||
rpm *= (prep.current_speed * prep.inv_rate);
|
||||
}
|
||||
#endif
|
||||
st_prep_block->spindle_pwm = spindle_compute_pwm_value(rpm);
|
||||
} 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
|
||||
|
||||
/* -----------------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user