New Continuous Filament Mixer (#12098)
This commit is contained in:
@ -1749,10 +1749,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Bail if this is a zero-length block
|
||||
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
|
||||
|
||||
// For a mixing extruder, get a magnified esteps for each
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
||||
block->mix_steps[i] = mixing_factor[i] * esteps;
|
||||
MIXER_POPULATE_BLOCK();
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT > 0
|
||||
@ -1765,7 +1763,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#endif
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
block->active_extruder = extruder;
|
||||
block->extruder = extruder;
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
@ -2066,15 +2064,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Calculate and limit speed in mm/sec for each axis
|
||||
float current_speed[NUM_AXIS], speed_factor = 1.0f; // factor <1 decreases speed
|
||||
LOOP_XYZE(i) {
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#if ENABLED(MIXING_EXTRUDER) && ENABLED(RETRACT_SYNC_MIXING)
|
||||
// In worst case, only one extruder running, no change is needed.
|
||||
// In best case, all extruders run the same amount, we can divide by MIXING_STEPPERS
|
||||
float delta_mm_i = 0;
|
||||
if (i == E_AXIS) {
|
||||
for (uint8_t s = 0; s < MIXING_STEPPERS; s++) {
|
||||
const float delta_mm_s = mixing_factor[s] * delta_mm[i];
|
||||
if (ABS(delta_mm_s) > ABS(delta_mm_i)) delta_mm_i = delta_mm_s;
|
||||
}
|
||||
}
|
||||
else delta_mm_i = delta_mm[i];
|
||||
if (i == E_AXIS && mixer.get_current_v_tool() == MIXER_AUTORETRACT_TOOL)
|
||||
delta_mm_i = delta_mm[i] / MIXING_STEPPERS;
|
||||
else
|
||||
delta_mm_i = delta_mm[i];
|
||||
#else
|
||||
const float delta_mm_i = delta_mm[i];
|
||||
#endif
|
||||
|
@ -47,6 +47,10 @@
|
||||
#include "../feature/fwretract.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#include "../feature/mixing.h"
|
||||
#endif
|
||||
|
||||
enum BlockFlagBit : char {
|
||||
// Recalculate trapezoids on entry junction. For optimization.
|
||||
BLOCK_BIT_RECALCULATE,
|
||||
@ -104,11 +108,11 @@ typedef struct {
|
||||
uint32_t step_event_count; // The number of step events required to complete this block
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
uint8_t active_extruder; // The extruder to move (if E move)
|
||||
uint8_t extruder; // The extruder to move (if E move)
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
uint32_t mix_steps[MIXING_STEPPERS]; // Scaled steps[E_AXIS] for the mixing steppers
|
||||
MIXER_BLOCK_DEFINITION; // Normalized color for the mixing steppers
|
||||
#endif
|
||||
|
||||
// Settings for the trapezoid generator
|
||||
|
@ -103,6 +103,10 @@
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#include "../feature/mixing.h"
|
||||
#endif
|
||||
|
||||
Stepper stepper; // Singleton
|
||||
|
||||
// public:
|
||||
@ -158,12 +162,10 @@ uint32_t Stepper::advance_dividend[XYZE] = { 0 },
|
||||
Stepper::decelerate_after, // The point from where we need to start decelerating
|
||||
Stepper::step_event_count; // The total event count for the current block
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
int32_t Stepper::delta_error_m[MIXING_STEPPERS];
|
||||
uint32_t Stepper::advance_dividend_m[MIXING_STEPPERS],
|
||||
Stepper::advance_divisor_m;
|
||||
#elif EXTRUDERS > 1
|
||||
uint8_t Stepper::active_extruder; // Active extruder
|
||||
#if EXTRUDERS > 1 || ENABLED(MIXING_EXTRUDER)
|
||||
uint8_t Stepper::stepper_extruder;
|
||||
#else
|
||||
constexpr uint8_t Stepper::stepper_extruder;
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
@ -301,7 +303,7 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
|
||||
#endif
|
||||
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(active_extruder, v)
|
||||
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(stepper_extruder, v)
|
||||
#endif
|
||||
|
||||
void Stepper::wake_up() {
|
||||
@ -340,21 +342,23 @@ void Stepper::set_directions() {
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
// Because this is valid for the whole block we don't know
|
||||
// what e-steppers will step. Likely all. Set all.
|
||||
if (motor_direction(E_AXIS)) {
|
||||
MIXING_STEPPERS_LOOP(j) REV_E_DIR(j);
|
||||
MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
|
||||
count_direction[E_AXIS] = -1;
|
||||
}
|
||||
else {
|
||||
MIXING_STEPPERS_LOOP(j) NORM_E_DIR(j);
|
||||
MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
|
||||
count_direction[E_AXIS] = 1;
|
||||
}
|
||||
#else
|
||||
if (motor_direction(E_AXIS)) {
|
||||
REV_E_DIR(active_extruder);
|
||||
REV_E_DIR(stepper_extruder);
|
||||
count_direction[E_AXIS] = -1;
|
||||
}
|
||||
else {
|
||||
NORM_E_DIR(active_extruder);
|
||||
NORM_E_DIR(stepper_extruder);
|
||||
count_direction[E_AXIS] = 1;
|
||||
}
|
||||
#endif
|
||||
@ -1387,39 +1391,27 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
PULSE_START(Z);
|
||||
#endif
|
||||
|
||||
// Pulse E/Mixing extruders
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
// Tick the E axis, correct error term and update position
|
||||
// Pulse Extruders
|
||||
// Tick the E axis, correct error term and update position
|
||||
#if ENABLED(LIN_ADVANCE) || ENABLED(MIXING_EXTRUDER)
|
||||
delta_error[E_AXIS] += advance_dividend[E_AXIS];
|
||||
if (delta_error[E_AXIS] >= 0) {
|
||||
count_position[E_AXIS] += count_direction[E_AXIS];
|
||||
delta_error[E_AXIS] -= advance_divisor;
|
||||
|
||||
// Don't step E here - But remember the number of steps to perform
|
||||
motor_direction(E_AXIS) ? --LA_steps : ++LA_steps;
|
||||
}
|
||||
#else // !LIN_ADVANCE - use linear interpolation for E also
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
|
||||
// Tick the E axis
|
||||
delta_error[E_AXIS] += advance_dividend[E_AXIS];
|
||||
if (delta_error[E_AXIS] >= 0) {
|
||||
count_position[E_AXIS] += count_direction[E_AXIS];
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
delta_error[E_AXIS] -= advance_divisor;
|
||||
}
|
||||
|
||||
// Tick the counters used for this mix in proper proportion
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
// Step mixing steppers (proportionally)
|
||||
delta_error_m[j] += advance_dividend_m[j];
|
||||
// Step when the counter goes over zero
|
||||
if (delta_error_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
|
||||
}
|
||||
|
||||
#else // !MIXING_EXTRUDER
|
||||
// Don't step E here - But remember the number of steps to perform
|
||||
motor_direction(E_AXIS) ? --LA_steps : ++LA_steps;
|
||||
#else // !LIN_ADVANCE && MIXING_EXTRUDER
|
||||
// Don't adjust delta_error[E_AXIS] here!
|
||||
// Being positive is the criteria for ending the pulse.
|
||||
E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
|
||||
#endif
|
||||
}
|
||||
#else // !LIN_ADVANCE && !MIXING_EXTRUDER
|
||||
#if HAS_E_STEP
|
||||
PULSE_START(E);
|
||||
#endif
|
||||
#endif // !LIN_ADVANCE
|
||||
#endif
|
||||
|
||||
#if MINIMUM_STEPPER_PULSE
|
||||
// Just wait for the requested pulse duration
|
||||
@ -1442,11 +1434,9 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
if (delta_error_m[j] >= 0) {
|
||||
delta_error_m[j] -= advance_divisor_m;
|
||||
E_STEP_WRITE(j, INVERT_E_STEP_PIN);
|
||||
}
|
||||
if (delta_error[E_AXIS] >= 0) {
|
||||
delta_error[E_AXIS] -= advance_divisor;
|
||||
E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
|
||||
}
|
||||
#else // !MIXING_EXTRUDER
|
||||
PULSE_STOP(E);
|
||||
@ -1717,27 +1707,18 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
decelerate_after = current_block->decelerate_after << oversampling;
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
const uint32_t e_steps = (
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
current_block->steps[E_AXIS]
|
||||
#else
|
||||
step_event_count
|
||||
#endif
|
||||
);
|
||||
MIXING_STEPPERS_LOOP(i) {
|
||||
delta_error_m[i] = -int32_t(e_steps);
|
||||
advance_dividend_m[i] = current_block->mix_steps[i] << 1;
|
||||
}
|
||||
advance_divisor_m = e_steps << 1;
|
||||
#elif EXTRUDERS > 1
|
||||
active_extruder = current_block->active_extruder;
|
||||
MIXER_STEPPER_SETUP();
|
||||
#endif
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
stepper_extruder = current_block->extruder;
|
||||
#endif
|
||||
|
||||
// Initialize the trapezoid generator from the current block.
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if DISABLED(MIXING_EXTRUDER) && E_STEPPERS > 1
|
||||
// If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
|
||||
if (active_extruder != last_moved_extruder) LA_current_adv_steps = 0;
|
||||
if (stepper_extruder != last_moved_extruder) LA_current_adv_steps = 0;
|
||||
#endif
|
||||
|
||||
if ((LA_use_advance_lead = current_block->use_advance_lead)) {
|
||||
@ -1751,15 +1732,15 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
#endif
|
||||
|
||||
if (current_block->direction_bits != last_direction_bits
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
|| active_extruder != last_moved_extruder
|
||||
#endif
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
|| stepper_extruder != last_moved_extruder
|
||||
#endif
|
||||
) {
|
||||
last_direction_bits = current_block->direction_bits;
|
||||
#if DISABLED(MIXING_EXTRUDER) && EXTRUDERS > 1
|
||||
last_moved_extruder = active_extruder;
|
||||
#endif
|
||||
set_directions();
|
||||
#if EXTRUDERS > 1
|
||||
last_moved_extruder = stepper_extruder;
|
||||
#endif
|
||||
}
|
||||
|
||||
// At this point, we must ensure the movement about to execute isn't
|
||||
@ -1827,15 +1808,17 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
interval = LA_ADV_NEVER;
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
// We don't know which steppers will be stepped because LA loop follows,
|
||||
// with potentially multiple steps. Set all.
|
||||
if (LA_steps >= 0)
|
||||
MIXING_STEPPERS_LOOP(j) NORM_E_DIR(j);
|
||||
MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
|
||||
else
|
||||
MIXING_STEPPERS_LOOP(j) REV_E_DIR(j);
|
||||
MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
|
||||
#else
|
||||
if (LA_steps >= 0)
|
||||
NORM_E_DIR(active_extruder);
|
||||
NORM_E_DIR(stepper_extruder);
|
||||
else
|
||||
REV_E_DIR(active_extruder);
|
||||
REV_E_DIR(stepper_extruder);
|
||||
#endif
|
||||
|
||||
// Get the timer count and estimate the end of the pulse
|
||||
@ -1848,14 +1831,9 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
|
||||
// Set the STEP pulse ON
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
// Step mixing steppers (proportionally)
|
||||
delta_error_m[j] += advance_dividend_m[j];
|
||||
// Step when the counter goes over zero
|
||||
if (delta_error_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
|
||||
}
|
||||
E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
|
||||
#else
|
||||
E_STEP_WRITE(active_extruder, !INVERT_E_STEP_PIN);
|
||||
E_STEP_WRITE(stepper_extruder, !INVERT_E_STEP_PIN);
|
||||
#endif
|
||||
|
||||
// Enforce a minimum duration for STEP pulse ON
|
||||
@ -1871,14 +1849,9 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
|
||||
// Set the STEP pulse OFF
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
if (delta_error_m[j] >= 0) {
|
||||
delta_error_m[j] -= advance_divisor_m;
|
||||
E_STEP_WRITE(j, INVERT_E_STEP_PIN);
|
||||
}
|
||||
}
|
||||
E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
|
||||
#else
|
||||
E_STEP_WRITE(active_extruder, INVERT_E_STEP_PIN);
|
||||
E_STEP_WRITE(stepper_extruder, INVERT_E_STEP_PIN);
|
||||
#endif
|
||||
|
||||
// For minimum pulse time wait before looping
|
||||
@ -2106,8 +2079,6 @@ void Stepper::init() {
|
||||
|
||||
endstops.enable(true); // Start with endstops active. After homing they can be disabled
|
||||
sei();
|
||||
|
||||
set_directions(); // Init directions to last_direction_bits = 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +150,12 @@
|
||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
|
||||
// If linear advance is disabled, then the loop also handles them
|
||||
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
|
||||
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER) // ToDo: ???
|
||||
// HELP ME: What is what?
|
||||
// Directions are set up for MIXING_STEPPERS - like before.
|
||||
// Finding the right stepper may last up to MIXING_STEPPERS loops in get_next_stepper().
|
||||
// These loops are a bit faster than advancing a bresenham counter.
|
||||
// Always only one e-stepper is stepped.
|
||||
#define ISR_START_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_START_STEPPER_CYCLES))
|
||||
#define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||
#else
|
||||
@ -188,7 +193,12 @@
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
// Estimate the minimum LA loop time
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#if ENABLED(MIXING_EXTRUDER) // ToDo: ???
|
||||
// HELP ME: What is what?
|
||||
// Directions are set up for MIXING_STEPPERS - like before.
|
||||
// Finding the right stepper may last up to MIXING_STEPPERS loops in get_next_stepper().
|
||||
// These loops are a bit faster than advancing a bresenham counter.
|
||||
// Always only one e-stepper is stepped.
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||
#else
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
|
||||
@ -292,17 +302,10 @@ class Stepper {
|
||||
decelerate_after, // The point from where we need to start decelerating
|
||||
step_event_count; // The total event count for the current block
|
||||
|
||||
// Mixing extruder mix delta_errors for bresenham tracing
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
static int32_t delta_error_m[MIXING_STEPPERS];
|
||||
static uint32_t advance_dividend_m[MIXING_STEPPERS],
|
||||
advance_divisor_m;
|
||||
#define MIXING_STEPPERS_LOOP(VAR) \
|
||||
for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++)
|
||||
#elif EXTRUDERS > 1
|
||||
static uint8_t active_extruder;
|
||||
#if EXTRUDERS > 1 || ENABLED(MIXING_EXTRUDER)
|
||||
static uint8_t stepper_extruder;
|
||||
#else
|
||||
static constexpr uint8_t active_extruder = 0;
|
||||
static constexpr uint8_t stepper_extruder = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
|
@ -356,19 +356,6 @@ inline void invalid_extruder_error(const uint8_t e) {
|
||||
SERIAL_ECHOLNPGM(MSG_INVALID_EXTRUDER);
|
||||
}
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
|
||||
|
||||
inline void mixing_tool_change(const uint8_t tmp_extruder) {
|
||||
if (tmp_extruder >= MIXING_VIRTUAL_TOOLS)
|
||||
return invalid_extruder_error(tmp_extruder);
|
||||
|
||||
// T0-Tnnn: Switch virtual tool by changing the mix
|
||||
for (uint8_t j = 0; j < MIXING_STEPPERS; j++)
|
||||
mixing_factor[j] = mixing_virtual_tool_mix[tmp_extruder][j];
|
||||
}
|
||||
|
||||
#endif // MIXING_EXTRUDER && MIXING_VIRTUAL_TOOLS > 1
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
|
||||
inline void dualx_tool_change(const uint8_t tmp_extruder, bool &no_move) {
|
||||
@ -467,7 +454,9 @@ inline void invalid_extruder_error(const uint8_t e) {
|
||||
* previous tool out of the way and the new tool into place.
|
||||
*/
|
||||
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) {
|
||||
planner.synchronize();
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
planner.synchronize();
|
||||
#endif
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE) // Only T0 allowed if the Printer is in DXC_DUPLICATION_MODE or DXC_SCALED_DUPLICATION_MODE
|
||||
if (tmp_extruder != 0 && dxc_is_duplicating())
|
||||
@ -481,8 +470,12 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
|
||||
|
||||
mixing_tool_change(tmp_extruder);
|
||||
if (tmp_extruder >= MIXING_VIRTUAL_TOOLS)
|
||||
return invalid_extruder_error(tmp_extruder);
|
||||
// T0-Tnnn: Switch virtual tool by changing the index to the mix
|
||||
mixer.T(uint_fast8_t(tmp_extruder));
|
||||
UNUSED(fr_mm_s);
|
||||
UNUSED(no_move);
|
||||
|
||||
#else // !MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1
|
||||
|
||||
|
Reference in New Issue
Block a user