Merge pull request #2591 from wavexx/la15_chained_wipes
Fix chained wipes in Linear Advance 1.5
This commit is contained in:
commit
7c1bf6a836
@ -7116,7 +7116,6 @@ Sigma_Exit:
|
||||
{
|
||||
float e = code_value();
|
||||
#ifndef LA_NOCOMPAT
|
||||
|
||||
e = la10c_jerk(e);
|
||||
#endif
|
||||
cs.max_jerk[E_AXIS] = e;
|
||||
|
@ -1061,16 +1061,16 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
/**
|
||||
* Use LIN_ADVANCE within this block if all these are true:
|
||||
*
|
||||
* block->steps_e : This is a print move, because we checked for X, Y, Z steps before.
|
||||
* extruder_advance_K : There is an advance factor set.
|
||||
* delta_mm[E_AXIS] > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
|
||||
* delta_mm[E_AXIS] >= 0 : Extruding or traveling, but _not_ retracting.
|
||||
* |delta_mm[Z_AXIS]| < 0.5 : Z is only moved for leveling (_not_ for priming)
|
||||
*/
|
||||
block->use_advance_lead = block->steps_e.wide
|
||||
&& extruder_advance_K
|
||||
&& delta_mm[E_AXIS] > 0
|
||||
block->use_advance_lead = extruder_advance_K > 0
|
||||
&& delta_mm[E_AXIS] >= 0
|
||||
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
||||
if (block->use_advance_lead) {
|
||||
// all extrusion moves with LA require a compression which is proportional to the
|
||||
// extrusion_length to distance ratio (e/D)
|
||||
e_D_ratio = (e - position_float[E_AXIS]) /
|
||||
sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
@ -1082,10 +1082,10 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
// 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
|
||||
if (e_D_ratio > 3.0)
|
||||
block->use_advance_lead = false;
|
||||
else {
|
||||
const uint32_t max_accel_steps_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio) * steps_per_mm;
|
||||
if (block->acceleration_st > max_accel_steps_per_s2) {
|
||||
block->acceleration_st = max_accel_steps_per_s2;
|
||||
else if (e_D_ratio > 0) {
|
||||
const float max_accel_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio);
|
||||
if (cs.acceleration > max_accel_per_s2) {
|
||||
block->acceleration_st = ceil(max_accel_per_s2 * steps_per_mm);
|
||||
#ifdef LA_DEBUG
|
||||
SERIAL_ECHOLNPGM("LA: Block acceleration limited due to max E-jerk");
|
||||
#endif
|
||||
@ -1133,9 +1133,14 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||
block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS];
|
||||
block->max_adv_steps = block->nominal_speed * block->adv_comp;
|
||||
|
||||
float advance_speed;
|
||||
if (e_D_ratio > 0)
|
||||
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
else
|
||||
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
|
||||
|
||||
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
||||
// still need to replicate the *exact* same step grouping policy (see below)
|
||||
float advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
||||
float advance_rate = (F_CPU / 8.0) / advance_speed;
|
||||
if (advance_speed > 20000) {
|
||||
|
@ -117,8 +117,8 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||
void advance_isr();
|
||||
|
||||
static const uint16_t ADV_NEVER = 0xFFFF;
|
||||
static const uint8_t ADV_INIT = 0b01;
|
||||
static const uint8_t ADV_DECELERATE = 0b10;
|
||||
static const uint8_t ADV_INIT = 0b01; // initialize LA
|
||||
static const uint8_t ADV_ACC_VARY = 0b10; // varying acceleration phase
|
||||
|
||||
static uint16_t nextMainISR;
|
||||
static uint16_t nextAdvanceISR;
|
||||
@ -128,13 +128,12 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||
static uint16_t eISR_Err;
|
||||
|
||||
static uint16_t current_adv_steps;
|
||||
static uint16_t final_adv_steps;
|
||||
static uint16_t max_adv_steps;
|
||||
static uint32_t LA_decelerate_after;
|
||||
static uint16_t target_adv_steps;
|
||||
|
||||
static int8_t e_steps;
|
||||
static uint8_t e_step_loops;
|
||||
static int8_t LA_phase;
|
||||
static int8_t e_steps; // scheduled e-steps during each isr loop
|
||||
static uint8_t e_step_loops; // e-steps to execute at most in each isr loop
|
||||
static uint8_t e_extruding; // current move is an extrusion move
|
||||
static int8_t LA_phase; // LA compensation phase
|
||||
|
||||
#define _NEXT_ISR(T) main_Rate = nextMainISR = T
|
||||
#else
|
||||
@ -349,15 +348,12 @@ FORCE_INLINE void stepper_next_block()
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
LA_decelerate_after = current_block->decelerate_after;
|
||||
final_adv_steps = current_block->final_adv_steps;
|
||||
max_adv_steps = current_block->max_adv_steps;
|
||||
e_step_loops = current_block->advance_step_loops;
|
||||
target_adv_steps = current_block->max_adv_steps;
|
||||
} else {
|
||||
e_steps = 0;
|
||||
e_step_loops = 1;
|
||||
current_adv_steps = 0;
|
||||
}
|
||||
e_steps = 0;
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
LA_phase = -1;
|
||||
#endif
|
||||
@ -371,11 +367,17 @@ FORCE_INLINE void stepper_next_block()
|
||||
counter_y.lo = counter_x.lo;
|
||||
counter_z.lo = counter_x.lo;
|
||||
counter_e.lo = counter_x.lo;
|
||||
#ifdef LIN_ADVANCE
|
||||
e_extruding = current_block->steps_e.lo != 0;
|
||||
#endif
|
||||
} else {
|
||||
counter_x.wide = -(current_block->step_event_count.wide >> 1);
|
||||
counter_y.wide = counter_x.wide;
|
||||
counter_z.wide = counter_x.wide;
|
||||
counter_e.wide = counter_x.wide;
|
||||
#ifdef LIN_ADVANCE
|
||||
e_extruding = current_block->steps_e.wide != 0;
|
||||
#endif
|
||||
}
|
||||
step_events_completed.wide = 0;
|
||||
// Set directions.
|
||||
@ -811,7 +813,7 @@ FORCE_INLINE void isr() {
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed.wide <= (unsigned long int)step_loops)
|
||||
la_state = ADV_INIT;
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -827,11 +829,13 @@ FORCE_INLINE void isr() {
|
||||
uint16_t timer = calc_timer(step_rate, step_loops);
|
||||
_NEXT_ISR(timer);
|
||||
deceleration_time += timer;
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
la_state = ADV_DECELERATE;
|
||||
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops)
|
||||
la_state |= ADV_INIT;
|
||||
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
||||
target_adv_steps = current_block->final_adv_steps;
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -841,6 +845,17 @@ FORCE_INLINE void isr() {
|
||||
// the initial interrupt blocking.
|
||||
OCR1A_nominal = calc_timer(uint16_t(current_block->nominal_rate), step_loops);
|
||||
step_loops_nominal = step_loops;
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if(current_block->use_advance_lead) {
|
||||
if (!nextAdvanceISR) {
|
||||
// Due to E-jerk, there can be discontinuities in pressure state where an
|
||||
// acceleration or deceleration can be skipped or joined with the previous block.
|
||||
// If LA was not previously active, re-check the pressure level
|
||||
la_state = ADV_INIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_NEXT_ISR(OCR1A_nominal);
|
||||
}
|
||||
@ -849,10 +864,23 @@ FORCE_INLINE void isr() {
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
// avoid multiple instances or function calls to advance_spread
|
||||
if (la_state & ADV_INIT) eISR_Err = current_block->advance_rate / 4;
|
||||
if (la_state & ADV_INIT) {
|
||||
if (current_adv_steps == target_adv_steps) {
|
||||
// nothing to be done in this phase
|
||||
la_state = 0;
|
||||
}
|
||||
else {
|
||||
eISR_Err = current_block->advance_rate / 4;
|
||||
if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
|
||||
// LA could reverse the direction of extrusion in this phase
|
||||
LA_phase = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (la_state & ADV_INIT || nextAdvanceISR != ADV_NEVER) {
|
||||
// update timers & phase for the next iteration
|
||||
advance_spread(main_Rate);
|
||||
if (la_state & ADV_DECELERATE) {
|
||||
if (LA_phase >= 0) {
|
||||
if (step_loops == e_step_loops)
|
||||
LA_phase = (eISR_Rate > main_Rate);
|
||||
else {
|
||||
@ -898,7 +926,7 @@ FORCE_INLINE void isr() {
|
||||
// Timer interrupt for E. e_steps is set in the main routine.
|
||||
|
||||
FORCE_INLINE void advance_isr() {
|
||||
if (step_events_completed.wide > LA_decelerate_after && current_adv_steps > final_adv_steps) {
|
||||
if (current_adv_steps > target_adv_steps) {
|
||||
// decompression
|
||||
e_steps -= e_step_loops;
|
||||
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
||||
@ -908,7 +936,7 @@ FORCE_INLINE void advance_isr() {
|
||||
current_adv_steps = 0;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
else if (step_events_completed.wide < LA_decelerate_after && current_adv_steps < max_adv_steps) {
|
||||
else if (current_adv_steps < target_adv_steps) {
|
||||
// compression
|
||||
e_steps += e_step_loops;
|
||||
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
||||
@ -1233,9 +1261,6 @@ void st_init()
|
||||
nextMainISR = 0;
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
main_Rate = ADV_NEVER;
|
||||
e_steps = 0;
|
||||
e_step_loops = 1;
|
||||
LA_phase = -1;
|
||||
current_adv_steps = 0;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user