diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 57d7b89b..35031ab2 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -1061,14 +1061,12 @@ 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 + && delta_mm[E_AXIS] >= 0 && abs(delta_mm[Z_AXIS]) < 0.5; if (block->use_advance_lead) { e_D_ratio = (e - position_float[E_AXIS]) / @@ -1082,7 +1080,7 @@ 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 { + else if (e_D_ratio > 0) { 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; @@ -1133,9 +1131,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) { diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index bc860b14..de068166 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -351,7 +351,6 @@ FORCE_INLINE void stepper_next_block() target_adv_steps = current_block->max_adv_steps; } else { e_step_loops = 1; - current_adv_steps = 0; } e_steps = 0; nextAdvanceISR = ADV_NEVER; @@ -840,6 +839,24 @@ 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(current_adv_steps < target_adv_steps) { + // after reaching cruising speed, halt compression. if we couldn't accumulate the + // required pressure in the acceleration phase due to lost ticks it's unlikely we + // could undo all of it during deceleration either + target_adv_steps = current_adv_steps; + } + else if (!nextAdvanceISR && current_adv_steps > target_adv_steps) { + // we're cruising in a block with excess backpressure and without a previous + // acceleration phase - this *cannot* happen during a regular block, but it's + // likely in result of chained a wipe move. release the pressure earlier by + // forcedly enabling LA while cruising! + la_state = ADV_INIT; + } + } +#endif } _NEXT_ISR(OCR1A_nominal); }