Skip to content

Commit

Permalink
Improvement Loop 1
Browse files Browse the repository at this point in the history
- Enable the eISR to also handle others than only extruder 0
- Zero current_adv_steps when the extruder has changed
- current_block is set to Nullas soon as the last step_loops is done,
but the time until the next block is called is still belonging to the
old block. This prevents LIN_ADVANCE from executing the last advance
steps.
- Detect retracts which got joined with a short segment by a unusual e/D
ratio instead of checking for the leading axis.
  • Loading branch information
Sebastianv650 committed Feb 12, 2018
1 parent 06f5016 commit 7c5b6a8
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 86 deletions.
25 changes: 13 additions & 12 deletions Marlin/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1227,16 +1227,10 @@ void Planner::check_axes_activity() {
*
* extruder_advance_k : There is an advance factor set.
*
* esteps != block->step_event_count : This is a work around for the following problem:
* A problem occurs if the move before a retract is too small.
* In that case, the retract and move will be executed together.
* This leads to too many advance steps due to a huge e_acceleration.
* The math is good, but we must avoid retract moves with advance!
* de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
*/
block->use_advance_lead = esteps // && (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS])
block->use_advance_lead = esteps
&& extruder_advance_K
&& (uint32_t)esteps != block->step_event_count
&& de > 0;

if (block->use_advance_lead) {
Expand All @@ -1245,11 +1239,18 @@ void Planner::check_axes_activity() {
#else
block->e_D_ratio = (target_float[E_AXIS] - position_float[E_AXIS]) / SQRT(sq(target_float[X_AXIS] - position_float[X_AXIS]) + sq(target_float[Y_AXIS] - position_float[Y_AXIS])+ sq(target_float[Z_AXIS] - position_float[Z_AXIS]));
#endif

const uint32_t max_accel_steps_per_s2 = max_jerk[E_AXIS] / (extruder_advance_K * block->e_D_ratio) * steps_per_mm; //SQRT(extruder_advance_K * 10 * max_jerk[E_AXIS]) / (extruder_advance_K * block->e_D_ratio) * steps_per_mm;
if (accel > max_accel_steps_per_s2)
SERIAL_ECHOLN("Limited accel!");
NOMORE(accel, max_accel_steps_per_s2);

// Check for unusual high e_D ratio to detect if a retract move was combined with the last print move due to min. steps per segment
// This assumes no one will use a retract length of 0mm < retr_length < ~0.2mm and no one will print 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
if (block->e_D_ratio > 3.0) {
block->use_advance_lead = false;
}
else {
const uint32_t max_accel_steps_per_s2 = max_jerk[E_AXIS] / (extruder_advance_K * block->e_D_ratio) * steps_per_mm; //SQRT(extruder_advance_K * 10 * max_jerk[E_AXIS]) / (extruder_advance_K * block->e_D_ratio) * steps_per_mm;
if (accel > max_accel_steps_per_s2)
SERIAL_ECHOLN("Limited accel!");
NOMORE(accel, max_accel_steps_per_s2);
}
}
#endif

Expand Down
184 changes: 111 additions & 73 deletions Marlin/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,21 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even

#if ENABLED(LIN_ADVANCE)

uint32_t Stepper::LA_decelerate_after;

constexpr uint16_t ADV_NEVER = 65535;

uint16_t Stepper::nextMainISR = 0,
Stepper::nextAdvanceISR = ADV_NEVER,
Stepper::eISR_Rate = ADV_NEVER,
Stepper::current_adv_steps = 0;
Stepper::current_adv_steps = 0,
Stepper::final_adv_steps,
Stepper::max_adv_steps;

int8_t Stepper::e_steps = 0,
Stepper::LA_active_extruder; // Copy from current executed block. Needed because current_block is set to NULL "too early".

int8_t Stepper::e_steps[E_STEPPERS];
bool Stepper::use_advance_lead;

#endif // LIN_ADVANCE

Expand Down Expand Up @@ -483,7 +490,7 @@ void Stepper::isr() {
#if DISABLED(MIXING_EXTRUDER)
// Don't step E here for mixing extruder
count_position[E_AXIS] += count_direction[E_AXIS];
motor_direction(E_AXIS) ? --e_steps[TOOL_E_INDEX] : ++e_steps[TOOL_E_INDEX];
motor_direction(E_AXIS) ? --e_steps : ++e_steps;
#endif
}

Expand Down Expand Up @@ -682,13 +689,13 @@ void Stepper::isr() {
#if ENABLED(LIN_ADVANCE)

if (current_block->use_advance_lead) {
if (step_events_completed == step_loops || (e_steps[TOOL_E_INDEX] && eISR_Rate != current_block->advance_speed)) {
if (step_events_completed == step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
nextAdvanceISR = 0; // Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
eISR_Rate = current_block->advance_speed;
}
} else {
eISR_Rate = ADV_NEVER;
if (e_steps[TOOL_E_INDEX]) nextAdvanceISR = 0;
if (e_steps) nextAdvanceISR = 0;
}

#endif // LIN_ADVANCE
Expand All @@ -715,13 +722,13 @@ void Stepper::isr() {
#if ENABLED(LIN_ADVANCE)

if (current_block->use_advance_lead) {
if (step_events_completed <= (uint32_t)current_block->decelerate_after + step_loops || (e_steps[TOOL_E_INDEX] && eISR_Rate != current_block->advance_speed)) {
if (step_events_completed <= (uint32_t)current_block->decelerate_after + step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
nextAdvanceISR = 0; // Wake up eISR on first deceleration loop
eISR_Rate = current_block->advance_speed;
}
} else {
eISR_Rate = ADV_NEVER;
if (e_steps[TOOL_E_INDEX]) nextAdvanceISR = 0;
if (e_steps) nextAdvanceISR = 0;
}

#endif // LIN_ADVANCE
Expand All @@ -731,7 +738,7 @@ void Stepper::isr() {
#if ENABLED(LIN_ADVANCE)

// If we have esteps to execute, fire the next advance_isr "now"
if (e_steps[TOOL_E_INDEX] && eISR_Rate != current_block->advance_speed) nextAdvanceISR = 0;
if (e_steps && eISR_Rate != current_block->advance_speed) nextAdvanceISR = 0;

#endif

Expand Down Expand Up @@ -774,79 +781,98 @@ void Stepper::isr() {
#if ENABLED(MK2_MULTIPLEXER)
// Even-numbered steppers are reversed
#define SET_E_STEP_DIR(INDEX) \
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0))
if (e_steps) E## INDEX ##_DIR_WRITE(e_steps < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0))
#else
#define SET_E_STEP_DIR(INDEX) \
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
if (e_steps) E## INDEX ##_DIR_WRITE(e_steps < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
#endif

#define START_E_PULSE(INDEX) \
if (e_steps[INDEX]) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN)
if (e_steps) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN)

#define STOP_E_PULSE(INDEX) \
if (e_steps[INDEX]) { \
e_steps[INDEX] < 0 ? ++e_steps[INDEX] : --e_steps[INDEX]; \
if (e_steps) { \
e_steps < 0 ? ++e_steps : --e_steps; \
E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); \
}

if (current_block) {
if (current_block->use_advance_lead) {
if (step_events_completed > (uint32_t)current_block->decelerate_after && current_adv_steps > current_block->final_adv_steps) {
e_steps[0]--;
current_adv_steps--;
nextAdvanceISR = eISR_Rate;
}
else if (step_events_completed < (uint32_t)current_block->decelerate_after && current_adv_steps < current_block->max_adv_steps) {
e_steps[0]++;
current_adv_steps++;
nextAdvanceISR = eISR_Rate;
}
else {
nextAdvanceISR = ADV_NEVER;
eISR_Rate = ADV_NEVER;
}
if (current_block->use_advance_lead) {
if (step_events_completed > LA_decelerate_after && current_adv_steps > final_adv_steps) {
e_steps--;
current_adv_steps--;
nextAdvanceISR = eISR_Rate;
}
else
else if (step_events_completed < LA_decelerate_after && current_adv_steps < max_adv_steps) { //step_events_completed <= (uint32_t)current_block->accelerate_until) {
e_steps++;
current_adv_steps++;
nextAdvanceISR = eISR_Rate;
}
else {
nextAdvanceISR = ADV_NEVER;
eISR_Rate = ADV_NEVER;
}
}
else {
nextAdvanceISR = eISR_Rate;
}
else
nextAdvanceISR = ADV_NEVER;

SET_E_STEP_DIR(0);
#if E_STEPPERS > 1
SET_E_STEP_DIR(1);
#if E_STEPPERS > 2
SET_E_STEP_DIR(2);
#if E_STEPPERS > 3
SET_E_STEP_DIR(3);
#if E_STEPPERS > 4
SET_E_STEP_DIR(4);
#endif
#endif
#endif
#endif
switch(LA_active_extruder) {
case 0:
SET_E_STEP_DIR(0);
break;
#if EXTRUDERS > 1
case 1:
SET_E_STEP_DIR(1);
break;
#if EXTRUDERS > 2
case 2:
SET_E_STEP_DIR(2);
break;
#if EXTRUDERS > 3
case 3:
SET_E_STEP_DIR(3);
break;
#if EXTRUDERS > 4
case 4:
SET_E_STEP_DIR(4);
break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}

// Step all E steppers that have steps
while (e_steps[0]) {
while (e_steps) {

#if EXTRA_CYCLES_E > 20
uint32_t pulse_start = TCNT0;
#endif

START_E_PULSE(0);
#if E_STEPPERS > 1
START_E_PULSE(1);
#if E_STEPPERS > 2
START_E_PULSE(2);
#if E_STEPPERS > 3
START_E_PULSE(3);
#if E_STEPPERS > 4
START_E_PULSE(4);
#endif
#endif
#endif
#endif
switch(LA_active_extruder) {
case 0:
START_E_PULSE(0);
break;
#if EXTRUDERS > 1
case 1:
START_E_PULSE(1);
break;
#if EXTRUDERS > 2
case 2:
START_E_PULSE(2);
break;
#if EXTRUDERS > 3
case 3:
START_E_PULSE(3);
break;
#if EXTRUDERS > 4
case 4:
START_E_PULSE(4);
break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}

// For minimum pulse time wait before stopping pulses
#if EXTRA_CYCLES_E > 20
Expand All @@ -856,19 +882,31 @@ void Stepper::isr() {
DELAY_NOPS(EXTRA_CYCLES_E);
#endif

STOP_E_PULSE(0);
#if E_STEPPERS > 1
STOP_E_PULSE(1);
#if E_STEPPERS > 2
STOP_E_PULSE(2);
#if E_STEPPERS > 3
STOP_E_PULSE(3);
#if E_STEPPERS > 4
STOP_E_PULSE(4);
#endif
#endif
#endif
#endif
switch(LA_active_extruder) {
case 0:
STOP_E_PULSE(0);
break;
#if EXTRUDERS > 1
case 1:
STOP_E_PULSE(1);
break;
#if EXTRUDERS > 2
case 2:
STOP_E_PULSE(2);
break;
#if EXTRUDERS > 3
case 3:
STOP_E_PULSE(3);
break;
#if EXTRUDERS > 4
case 4:
STOP_E_PULSE(4);
break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}

// For minimum pulse time wait before looping
#if EXTRA_CYCLES_E > 20
Expand Down
22 changes: 21 additions & 1 deletion Marlin/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,13 @@ class Stepper {

#if ENABLED(LIN_ADVANCE)

static uint32_t LA_decelerate_after; // Copy from current executed block. Needed because current_block is set to NULL "too early".
static uint16_t nextMainISR, nextAdvanceISR, eISR_Rate, current_adv_steps;
static uint16_t final_adv_steps, max_adv_steps; // Copy from current executed block. Needed because current_block is set to NULL "too early".
#define _NEXT_ISR(T) nextMainISR = T
static int8_t e_steps[E_STEPPERS];
static int8_t e_steps;
static int8_t LA_active_extruder; // Copy from current executed block. Needed because current_block is set to NULL "too early".
static bool use_advance_lead;

#else // !LIN_ADVANCE

Expand Down Expand Up @@ -343,6 +347,22 @@ class Stepper {
FORCE_INLINE static void trapezoid_generator_reset() {

static int8_t last_extruder = -1;

#if ENABLED(LIN_ADVANCE)
if (current_block->active_extruder != last_extruder) {
current_adv_steps = 0; // If the now active extruder wasn't in use during the last move, it's pressure is most likely gone.
LA_active_extruder = current_block->active_extruder;
}

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;
use_advance_lead = true;
}
else
use_advance_lead = false;
#endif

if (current_block->direction_bits != last_direction_bits || current_block->active_extruder != last_extruder) {
last_direction_bits = current_block->direction_bits;
Expand Down

0 comments on commit 7c5b6a8

Please sign in to comment.