Commit 2e716a35 authored by MagoKimbra's avatar MagoKimbra

Same fix

parent 947ed498
...@@ -405,12 +405,16 @@ ...@@ -405,12 +405,16 @@
*********************************************************************** ***********************************************************************
* * * *
* Extends G0/G1 with mixing factors ABCDHI for up to 6 steppers. * * Extends G0/G1 with mixing factors ABCDHI for up to 6 steppers. *
* Adds a new code, M223, to set the current mix factors. * * Adds a new code, M165, to set the current mix factors. *
* Optional support for Repetier Host M163, M164, and virtual tools. *
* Extends the stepping routines to move multiple steppers in * * Extends the stepping routines to move multiple steppers in *
* proportion to the mix. * * proportion to the mix. *
* * * *
***********************************************************************/ ***********************************************************************/
//#define COLOR_MIXING_EXTRUDER //#define COLOR_MIXING_EXTRUDER
// Use the Virtual Tool method with M163 and M164
#define MIXING_VIRTUAL_TOOLS 16
/***********************************************************************/ /***********************************************************************/
...@@ -1077,7 +1081,7 @@ ...@@ -1077,7 +1081,7 @@
#define SHOW_BOOTSCREEN #define SHOW_BOOTSCREEN
#define STRING_SPLASH_LINE1 "v" SHORT_BUILD_VERSION // will be shown during bootup in line 1 #define STRING_SPLASH_LINE1 "v" SHORT_BUILD_VERSION // will be shown during bootup in line 1
//#define STRING_SPLASH_LINE2 STRING_DISTRIBUTION_DATE // will be shown during bootup in line 2 #define STRING_SPLASH_LINE2 STRING_DISTRIBUTION_DATE // will be shown during bootup in line 2
#define SPLASH_SCREEN_DURATION 5000 // SPLASH SCREEN duration in millisecond #define SPLASH_SCREEN_DURATION 5000 // SPLASH SCREEN duration in millisecond
//#define LCD_SCREEN_ROT_90 //Rotate screen orientation for graphics display by 90 degree clockwise //#define LCD_SCREEN_ROT_90 //Rotate screen orientation for graphics display by 90 degree clockwise
......
...@@ -115,6 +115,9 @@ ...@@ -115,6 +115,9 @@
* M140 - Set bed target temp * M140 - Set bed target temp
* M145 - Set the heatup state H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS) * M145 - Set the heatup state H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
* M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work. * M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
* M163 - Set a single proportion for a mixing extruder. Requires COLOR_MIXING_EXTRUDER.
* M164 - Save the mix as a virtual extruder. Requires COLOR_MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS.
* M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. Requires COLOR_MIXING_EXTRUDER.
* M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating * M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
* Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
* M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>- * M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>-
...@@ -131,7 +134,6 @@ ...@@ -131,7 +134,6 @@
* M220 - Set speed factor override percentage: S<factor in percent> * M220 - Set speed factor override percentage: S<factor in percent>
* M221 - Set extrude factor override percentage: S<factor in percent> * M221 - Set extrude factor override percentage: S<factor in percent>
* M222 - Set density extrusion percentage for purge: S<factor in percent> * M222 - Set density extrusion percentage for purge: S<factor in percent>
* M223 - Set the mix factors for a mixing extruder: <ABCDHI>
* M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state> * M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state>
* M240 - Trigger a camera to take a photograph * M240 - Trigger a camera to take a photograph
* M250 - Set LCD contrast C<contrast value> (value 0..63) * M250 - Set LCD contrast C<contrast value> (value 0..63)
......
...@@ -246,7 +246,10 @@ double printer_usage_filament; ...@@ -246,7 +246,10 @@ double printer_usage_filament;
#endif #endif
#if ENABLED(COLOR_MIXING_EXTRUDER) #if ENABLED(COLOR_MIXING_EXTRUDER)
float mixing_factor[DRIVER_EXTRUDERS] = { 1.0 / DRIVER_EXTRUDERS }; float mixing_factor[DRIVER_EXTRUDERS];
#if MIXING_VIRTUAL_TOOLS > 1
float mixing_virtual_tool_mix[MIXING_VIRTUAL_TOOLS][DRIVER_EXTRUDERS];
#endif
#endif #endif
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
...@@ -669,6 +672,18 @@ void setup() { ...@@ -669,6 +672,18 @@ void setup() {
setup_statled(); setup_statled();
#endif #endif
#if ENABLED(MIXING_EXTRUDER_FEATURE) && MIXING_VIRTUAL_TOOLS > 1
// Initialize mixing to 100% color 1
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
mixing_factor[i] = (i == 0) ? 1 : 0;
}
for (int8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++) {
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
mixing_virtual_tool_mix[t][i] = mixing_factor[i];
}
}
#endif
#if ENABLED(RFID_MODULE) #if ENABLED(RFID_MODULE)
RFID_ON = RFID522.init(); RFID_ON = RFID522.init();
if (RFID_ON) if (RFID_ON)
...@@ -2532,25 +2547,33 @@ static void clean_up_after_endstop_move() { ...@@ -2532,25 +2547,33 @@ static void clean_up_after_endstop_move() {
#endif //DELTA #endif //DELTA
#if ENABLED(COLOR_MIXING_EXTRUDER) #if ENABLED(COLOR_MIXING_EXTRUDER)
// Get mixing parameters from the GCode void normalize_mix() {
// Factors that are left out are set to 0
// The total "must" be 1.0 (but it will be normalized)
void gcode_get_mix() {
const char* mixing_codes = "ABCDHI";
float mix_total = 0.0; float mix_total = 0.0;
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) { for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
float v = code_seen(mixing_codes[i]) ? code_value() : mixing_factor[i]; float v = mixing_factor[i];
mixing_factor[i] = v; if (v < 0) v = mixing_factor[i] = 0;
mix_total += v; mix_total += v;
} }
// Scale values if they don't add up to ~1.0 // Scale all values if they don't add up to ~1.0
if (mix_total < 0.9999 || mix_total > 1.0001) { if (mix_total < 0.9999 || mix_total > 1.0001) {
ECHO_EM("Warning: Mix factors must add up to 1.0. Scaling."); ECHO_EM("Warning: Mix factors must add up to 1.0. Scaling.");
float mix_scale = 1.0 / mix_total; float mix_scale = 1.0 / mix_total;
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
mixing_factor[i] *= mix_scale; mixing_factor[i] *= mix_scale;
}
}
}
// Get mixing parameters from the GCode
// Factors that are left out are set to 0
// The total "must" be 1.0 (but it will be normalized)
void gcode_get_mix() {
const char* mixing_codes = "ABCDHI";
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
mixing_factor[i] = code_seen(mixing_codes[i]) ? code_value() : 0;
} }
normalize_mix();
} }
#endif #endif
...@@ -5264,7 +5287,6 @@ inline void gcode_M122() { ...@@ -5264,7 +5287,6 @@ inline void gcode_M122() {
*/ */
inline void gcode_M129() { EtoPPressure = 0; } inline void gcode_M129() { EtoPPressure = 0; }
#endif #endif
#endif //BARICUDA #endif //BARICUDA
/** /**
...@@ -5276,7 +5298,6 @@ inline void gcode_M140() { ...@@ -5276,7 +5298,6 @@ inline void gcode_M140() {
} }
#if ENABLED(ULTIPANEL) && TEMP_SENSOR_0 != 0 #if ENABLED(ULTIPANEL) && TEMP_SENSOR_0 != 0
/** /**
* M145: Set the heatup state for a material in the LCD menu * M145: Set the heatup state for a material in the LCD menu
* S<material> (0=PLA, 1=ABS, 2=GUM) * S<material> (0=PLA, 1=ABS, 2=GUM)
...@@ -5355,7 +5376,6 @@ inline void gcode_M140() { ...@@ -5355,7 +5376,6 @@ inline void gcode_M140() {
} }
} }
} }
#endif #endif
#if ENABLED(BLINKM) #if ENABLED(BLINKM)
...@@ -5372,6 +5392,55 @@ inline void gcode_M140() { ...@@ -5372,6 +5392,55 @@ inline void gcode_M140() {
#endif // BLINKM #endif // BLINKM
#if ENABLED(COLOR_MIXING_EXTRUDER)
/**
* M163: Set a single mix factor for a mixing extruder
* This is called "weight" by some systems.
*
* S[index] The channel index to set
* P[float] The mix value
*
*/
inline void gcode_M163() {
int mix_index = code_seen('S') ? code_value_short() : 0;
float mix_value = code_seen('P') ? code_value() : 0.0;
if (mix_index < DRIVER_EXTRUDERS) mixing_factor[mix_index] = mix_value;
}
#if MIXING_VIRTUAL_TOOLS > 1
/**
* M164: Store the current mix factors as a virtual tools.
*
* S[index] The virtual tools to store
*
*/
inline void gcode_M164() {
int tool_index = code_seen('S') ? code_value_short() : 0;
if (tool_index < MIXING_VIRTUAL_TOOLS) {
normalize_mix();
for (int8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
mixing_virtual_tool_mix[tool_index][i] = mixing_factor[i];
}
}
}
#endif
/**
* M165: Set multiple mix factors for a mixing extruder.
* Factors that are left out will be set to 0.
* All factors together must add up to 1.0.
*
* A[factor] Mix factor for extruder stepper 1
* B[factor] Mix factor for extruder stepper 2
* C[factor] Mix factor for extruder stepper 3
* D[factor] Mix factor for extruder stepper 4
* H[factor] Mix factor for extruder stepper 5
* I[factor] Mix factor for extruder stepper 6
*
*/
inline void gcode_M165() { gcode_get_mix(); }
#endif // COLOR_MIXING_EXTRUDER
#if HAS(TEMP_BED) #if HAS(TEMP_BED)
/** /**
* M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
...@@ -5538,7 +5607,6 @@ inline void gcode_M206() { ...@@ -5538,7 +5607,6 @@ inline void gcode_M206() {
} }
#if ENABLED(FWRETRACT) #if ENABLED(FWRETRACT)
/** /**
* M207: Set firmware retraction values * M207: Set firmware retraction values
* *
...@@ -5646,23 +5714,6 @@ inline void gcode_M222() { ...@@ -5646,23 +5714,6 @@ inline void gcode_M222() {
} }
} }
#if ENABLED(COLOR_MIXING_EXTRUDER)
/**
* M223: Set the mix factors for a mixing extruder.
* Factors that are left out will be set to 0.
* All factors together must add up to 1.0.
*
* A[factor] Mix factor for extruder stepper 1
* B[factor] Mix factor for extruder stepper 2
* C[factor] Mix factor for extruder stepper 3
* D[factor] Mix factor for extruder stepper 4
* H[factor] Mix factor for extruder stepper 5
* I[factor] Mix factor for extruder stepper 6
*
*/
inline void gcode_M223() { gcode_get_mix(); }
#endif
/** /**
* M226: Wait until the specified pin reaches the state required (M226 P<pin> S<state>) * M226: Wait until the specified pin reaches the state required (M226 P<pin> S<state>)
*/ */
...@@ -5807,9 +5858,7 @@ inline void gcode_M226() { ...@@ -5807,9 +5858,7 @@ inline void gcode_M226() {
#endif // HAS(BUZZER) #endif // HAS(BUZZER)
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
/** /**
* M301: Set PID parameters P I D (and optionally C, L) * M301: Set PID parameters P I D (and optionally C, L)
* *
...@@ -5855,7 +5904,6 @@ inline void gcode_M226() { ...@@ -5855,7 +5904,6 @@ inline void gcode_M226() {
#endif // PIDTEMP #endif // PIDTEMP
#if ENABLED(PREVENT_DANGEROUS_EXTRUDE) #if ENABLED(PREVENT_DANGEROUS_EXTRUDE)
void set_extrude_min_temp(float temp) { extrude_min_temp = temp; } void set_extrude_min_temp(float temp) { extrude_min_temp = temp; }
/** /**
...@@ -5864,7 +5912,6 @@ inline void gcode_M226() { ...@@ -5864,7 +5912,6 @@ inline void gcode_M226() {
inline void gcode_M302() { inline void gcode_M302() {
set_extrude_min_temp(code_seen('S') ? code_value() : 0); set_extrude_min_temp(code_seen('S') ? code_value() : 0);
} }
#endif // PREVENT_DANGEROUS_EXTRUDE #endif // PREVENT_DANGEROUS_EXTRUDE
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
...@@ -6657,292 +6704,310 @@ inline void gcode_M999() { ...@@ -6657,292 +6704,310 @@ inline void gcode_M999() {
* F[mm/min] Set the movement feedrate * F[mm/min] Set the movement feedrate
*/ */
inline void gcode_T(uint8_t tmp_extruder) { inline void gcode_T(uint8_t tmp_extruder) {
if (tmp_extruder >= EXTRUDERS) { bool good_extruder = false;
ECHO_SMV(DB, "T", (int)tmp_extruder);
ECHO_EM(" " SERIAL_INVALID_EXTRUDER);
}
else {
target_extruder = tmp_extruder;
#if ENABLED(DONDOLO) #if ENABLED(COLOR_MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
bool make_move = true;
#else
bool make_move = false;
#endif
if (code_seen('F')) { // T0-T15: Switch virtual tool by changing the mix
if (tmp_extruder < MIXING_VIRTUAL_TOOLS) {
good_extruder = true;
for (int8_t j = 0; j < DRIVER_EXTRUDERS; j++) {
mixing_factor[j] = mixing_virtual_tool_mix[tmp_extruder][j];
}
ECHO_LMV(DB, SERIAL_ACTIVE_COLOR, (int)tmp_extruder);
}
#if EXTRUDERS > 1 #else // !COLOR_MIXING_EXTRUDER && MIXING_VIRTUAL_TOOLS
make_move = true;
#endif
float next_feedrate = code_value(); if (tmp_extruder < EXTRUDERS) {
if (next_feedrate > 0.0) feedrate = next_feedrate; good_extruder = true;
} target_extruder = tmp_extruder;
#if EXTRUDERS > 1
#if ENABLED(NPR2) #if ENABLED(DONDOLO)
if(target_extruder != old_color) bool make_move = true;
#else #else
if(target_extruder != active_extruder) bool make_move = false;
#endif // NPR2 #endif
{
// Save current position to return to after applying extruder offset if (code_seen('F')) {
set_destination_to_current();
#if ENABLED(DUAL_X_CARRIAGE)
if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() &&
(delayed_move_time != 0 || current_position[X_AXIS] != x_home_pos(active_extruder))) {
// Park old head: 1) raise 2) move to park position 3) lower
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT,
current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT,
current_position[E_AXIS], max_feedrate[X_AXIS], active_extruder, active_driver);
plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS],
current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
st_synchronize();
}
// apply Y & Z extruder offset (x offset is already used in determining home pos) #if EXTRUDERS > 1
current_position[Y_AXIS] = current_position[Y_AXIS] - make_move = true;
hotend_offset[Y_AXIS][active_extruder] + #endif
hotend_offset[Y_AXIS][target_extruder];
current_position[Z_AXIS] = current_position[Z_AXIS] -
hotend_offset[Z_AXIS][active_extruder] +
hotend_offset[Z_AXIS][target_extruder];
active_extruder = target_extruder; float next_feedrate = code_value();
if (next_feedrate > 0.0) feedrate = next_feedrate;
}
#if EXTRUDERS > 1
#if ENABLED(NPR2)
if(target_extruder != old_color)
#else
if(target_extruder != active_extruder)
#endif // NPR2
{
// Save current position to return to after applying extruder offset
set_destination_to_current();
#if ENABLED(DUAL_X_CARRIAGE)
if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() &&
(delayed_move_time != 0 || current_position[X_AXIS] != x_home_pos(active_extruder))) {
// Park old head: 1) raise 2) move to park position 3) lower
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT,
current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT,
current_position[E_AXIS], max_feedrate[X_AXIS], active_extruder, active_driver);
plan_buffer_line(x_home_pos(active_extruder), current_position[Y_AXIS], current_position[Z_AXIS],
current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
st_synchronize();
}
// This function resets the max/min values - the current position may be overwritten below. // apply Y & Z extruder offset (x offset is already used in determining home pos)
set_axis_is_at_home(X_AXIS); current_position[Y_AXIS] = current_position[Y_AXIS] -
hotend_offset[Y_AXIS][active_extruder] +
hotend_offset[Y_AXIS][target_extruder];
current_position[Z_AXIS] = current_position[Z_AXIS] -
hotend_offset[Z_AXIS][active_extruder] +
hotend_offset[Z_AXIS][target_extruder];
if (dual_x_carriage_mode == DXC_FULL_CONTROL_MODE) { active_extruder = target_extruder;
current_position[X_AXIS] = inactive_extruder_x_pos;
inactive_extruder_x_pos = destination[X_AXIS]; // This function resets the max/min values - the current position may be overwritten below.
} set_axis_is_at_home(X_AXIS);
else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position if (dual_x_carriage_mode == DXC_FULL_CONTROL_MODE) {
if (active_extruder == 0 || active_extruder_parked)
current_position[X_AXIS] = inactive_extruder_x_pos; current_position[X_AXIS] = inactive_extruder_x_pos;
else inactive_extruder_x_pos = destination[X_AXIS];
current_position[X_AXIS] = destination[X_AXIS] + duplicate_hotend_x_offset; }
inactive_extruder_x_pos = destination[X_AXIS]; else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
extruder_duplication_enabled = false; active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position
} if (active_extruder == 0 || active_extruder_parked)
else { current_position[X_AXIS] = inactive_extruder_x_pos;
// record raised toolhead position for use by unpark else
memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); current_position[X_AXIS] = destination[X_AXIS] + duplicate_hotend_x_offset;
raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT; inactive_extruder_x_pos = destination[X_AXIS];
active_extruder_parked = true; extruder_duplication_enabled = false;
delayed_move_time = 0; }
} else {
#else // !DUAL_X_CARRIAGE // record raised toolhead position for use by unpark
// Offset hotend (XYZ) memcpy(raised_parked_position, current_position, sizeof(raised_parked_position));
#if HOTENDS > 1 raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT;
for (int i = X_AXIS; i <= Z_AXIS; i++) active_extruder_parked = true;
current_position[i] += hotend_offset[i][target_extruder] - hotend_offset[i][active_extruder]; delayed_move_time = 0;
#endif // HOTENDS > 1 }
#else // !DUAL_X_CARRIAGE
#if ENABLED(MKR4) // Offset hotend (XYZ)
#if (EXTRUDERS == 4) && HAS(E0E2) && HAS(E1E3) && (DRIVER_EXTRUDERS == 2) #if HOTENDS > 1
for (int i = X_AXIS; i <= Z_AXIS; i++)
current_position[i] += hotend_offset[i][target_extruder] - hotend_offset[i][active_extruder];
#endif // HOTENDS > 1
#if ENABLED(MKR4)
#if (EXTRUDERS == 4) && HAS(E0E2) && HAS(E1E3) && (DRIVER_EXTRUDERS == 2)
st_synchronize(); // Finish all movement
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e1();
break;
case 2:
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e2();
break;
case 3:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, HIGH);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e3();
break;
}
#elif (EXTRUDERS == 4) && HAS(E0E1) && HAS(E0E2) && HAS(E0E3) && (DRIVER_EXTRUDERS == 1)
st_synchronize(); // Finish all movement
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E1_CHOICE_PIN, LOW);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 2:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 3:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E0E3_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
}
#elif (EXTRUDERS == 3) && HAS(E0E2) && (DRIVER_EXTRUDERS == 2)
st_synchronize(); // Finish all movement
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e1();
break;
case 2:
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
}
#elif (EXTRUDERS == 3) && HAS(E0E1) && HAS(E0E2) && (DRIVER_EXTRUDERS == 1)
st_synchronize(); // Finish all movement
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E1_CHOICE_PIN, LOW);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 2:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
}
#elif (EXTRUDERS == 2) && HAS(E0E1) && (DRIVER_EXTRUDERS == 1)
st_synchronize(); // Finish all movement
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E1_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
}
#endif // E0E1_CHOICE_PIN E0E2_CHOICE_PIN E1E3_CHOICE_PIN
previous_extruder = active_extruder;
active_extruder = target_extruder;
ECHO_LMV(DB, SERIAL_ACTIVE_DRIVER, (int)active_driver);
ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder);
#elif ENABLED(NPR2)
long csteps;
st_synchronize(); // Finish all movement st_synchronize(); // Finish all movement
disable_e(); if (old_color == 99) {
switch(target_extruder) csteps = (color_position[target_extruder]) * color_step_moltiplicator;
{
case 0:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e1();
break;
case 2:
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E1E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e2();
break;
case 3:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E1E3_CHOICE_PIN, HIGH);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e3();
break;
} }
#elif (EXTRUDERS == 4) && HAS(E0E1) && HAS(E0E2) && HAS(E0E3) && (DRIVER_EXTRUDERS == 1) else {
st_synchronize(); // Finish all movement csteps = (color_position[target_extruder] - color_position[old_color]) * color_step_moltiplicator;
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E1_CHOICE_PIN, LOW);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 2:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E0E3_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 3:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
WRITE_RELE(E0E3_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
} }
#elif (EXTRUDERS == 3) && HAS(E0E2) && (DRIVER_EXTRUDERS == 2) if (csteps < 0) colorstep(-csteps, false);
st_synchronize(); // Finish all movement if (csteps > 0) colorstep(csteps, true);
disable_e(); previous_extruder = active_extruder;
switch(target_extruder) old_color = active_extruder = target_extruder;
{ active_driver = 0;
case 0: ECHO_LMV(DB, SERIAL_ACTIVE_COLOR, (int)active_extruder);
WRITE_RELE(E0E2_CHOICE_PIN, LOW); #elif ENABLED(DONDOLO)
active_driver = 0; st_synchronize();
delay_ms(500); // 500 microseconds delay for relay servo[DONDOLO_SERVO_INDEX].attach(0);
enable_e0(); if (target_extruder == 0) {
break; servo[DONDOLO_SERVO_INDEX].write(DONDOLO_SERVOPOS_E0);
case 1:
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 1;
delay_ms(500); // 500 microseconds delay for relay
enable_e1();
break;
case 2:
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
} }
#elif (EXTRUDERS == 3) && HAS(E0E1) && HAS(E0E2) && (DRIVER_EXTRUDERS == 1) else if (target_extruder == 1) {
st_synchronize(); // Finish all movement servo[DONDOLO_SERVO_INDEX].write(DONDOLO_SERVOPOS_E1);
disable_e();
switch(target_extruder)
{
case 0:
WRITE_RELE(E0E1_CHOICE_PIN, LOW);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 1:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, LOW);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
case 2:
WRITE_RELE(E0E1_CHOICE_PIN, HIGH);
WRITE_RELE(E0E2_CHOICE_PIN, HIGH);
active_driver = 0;
delay_ms(500); // 500 microseconds delay for relay
enable_e0();
break;
} }
#elif (EXTRUDERS == 2) && HAS(E0E1) && (DRIVER_EXTRUDERS == 1) delay_ms(DONDOLO_SERVO_DELAY);
st_synchronize(); // Finish all movement servo[DONDOLO_SERVO_INDEX].detach();
disable_e(); previous_extruder = active_extruder;
switch(target_extruder) active_extruder = target_extruder;
{ active_driver = 0;
case 0: set_stepper_direction(true);
WRITE_RELE(E0E1_CHOICE_PIN, LOW); ECHO_LMV(DB, SERIAL_ACTIVE_DRIVER, (int)active_driver);
active_driver = 0; ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder);
delay_ms(500); // 500 microseconds delay for relay #else
enable_e0(); previous_extruder = active_extruder;
break; active_driver = active_extruder = target_extruder;
case 1: ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder);
WRITE_RELE(E0E1_CHOICE_PIN, HIGH); #endif // end MKR4 || NPR2 || DONDOLO
active_driver = 0; #endif // end no DUAL_X_CARRIAGE
delay_ms(500); // 500 microseconds delay for relay
enable_e0(); #if MECH(DELTA) || MECH(SCARA)
break; sync_plan_position_delta();
} #else // NO DELTA
#endif // E0E1_CHOICE_PIN E0E2_CHOICE_PIN E1E3_CHOICE_PIN sync_plan_position();
previous_extruder = active_extruder; #endif // !DELTA
active_extruder = target_extruder; // Move to the old position if 'F' was in the parameters
ECHO_LMV(DB, SERIAL_ACTIVE_DRIVER, (int)active_driver); if (make_move && IsRunning()) prepare_move();
ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder); }
#elif ENABLED(NPR2)
long csteps;
st_synchronize(); // Finish all movement
if (old_color == 99) {
csteps = (color_position[target_extruder]) * color_step_moltiplicator;
}
else {
csteps = (color_position[target_extruder] - color_position[old_color]) * color_step_moltiplicator;
}
if (csteps < 0) colorstep(-csteps, false);
if (csteps > 0) colorstep(csteps, true);
previous_extruder = active_extruder;
old_color = active_extruder = target_extruder;
active_driver = 0;
ECHO_LMV(DB, SERIAL_ACTIVE_COLOR, (int)active_extruder);
#elif ENABLED(DONDOLO)
st_synchronize();
servo[DONDOLO_SERVO_INDEX].attach(0);
if (target_extruder == 0) {
servo[DONDOLO_SERVO_INDEX].write(DONDOLO_SERVOPOS_E0);
}
else if (target_extruder == 1) {
servo[DONDOLO_SERVO_INDEX].write(DONDOLO_SERVOPOS_E1);
}
delay_ms(DONDOLO_SERVO_DELAY);
servo[DONDOLO_SERVO_INDEX].detach();
previous_extruder = active_extruder;
active_extruder = target_extruder;
active_driver = 0;
set_stepper_direction(true);
ECHO_LMV(DB, SERIAL_ACTIVE_DRIVER, (int)active_driver);
ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder);
#else
previous_extruder = active_extruder;
active_driver = active_extruder = target_extruder;
ECHO_LMV(DB, SERIAL_ACTIVE_EXTRUDER, (int)active_extruder);
#endif // end MKR4 || NPR2 || DONDOLO
#endif // end no DUAL_X_CARRIAGE
#if MECH(DELTA) || MECH(SCARA) #if ENABLED(EXT_SOLENOID)
sync_plan_position_delta(); st_synchronize();
#else // NO DELTA disable_all_solenoids();
sync_plan_position(); enable_solenoid_on_active_extruder();
#endif // !DELTA #endif // EXT_SOLENOID
// Move to the old position if 'F' was in the parameters
if (make_move && IsRunning()) prepare_move();
}
#if ENABLED(EXT_SOLENOID) #endif // EXTRUDERS > 1
st_synchronize(); }
disable_all_solenoids(); #endif // !COLOR_MIXING_EXTRUDER
enable_solenoid_on_active_extruder();
#endif // EXT_SOLENOID
#endif // EXTRUDERS > 1 if (!good_extruder) {
ECHO_SMV(DB, "T", (int)tmp_extruder);
ECHO_EM(" " SERIAL_INVALID_EXTRUDER);
} }
} }
...@@ -7205,6 +7270,17 @@ void process_next_command() { ...@@ -7205,6 +7270,17 @@ void process_next_command() {
gcode_M150(); break; gcode_M150(); break;
#endif //BLINKM #endif //BLINKM
#if ENABLED(COLOR_MIXING_EXTRUDER)
case 163: // M163 S<int> P<float> set weight for a mixing extruder
gcode_M163(); break;
#if MIXING_VIRTUAL_TOOLS > 1
case 164: // M164 S<int> save current mix as a virtual tools
gcode_M164(); break;
#endif
case 165: // M165 [ABCDHI]<float> set multiple mix weights
gcode_M165(); break;
#endif
#if HAS(TEMP_BED) #if HAS(TEMP_BED)
case 190: // M190 - Wait for bed heater to reach target. case 190: // M190 - Wait for bed heater to reach target.
gcode_M190(); break; gcode_M190(); break;
...@@ -7248,12 +7324,6 @@ void process_next_command() { ...@@ -7248,12 +7324,6 @@ void process_next_command() {
gcode_M221(); break; gcode_M221(); break;
case 222: // M222 T<extruder> S<factor in percent> - set density extrude factor percentage for purge case 222: // M222 T<extruder> S<factor in percent> - set density extrude factor percentage for purge
gcode_M222(); break; gcode_M222(); break;
#if ENABLED(COLOR_MIXING_EXTRUDER)
case 223: // M223 Set the mix factors for a mixing extruder
gcode_M223(); break;
#endif
case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required
gcode_M226(); break; gcode_M226(); break;
......
...@@ -253,7 +253,7 @@ ...@@ -253,7 +253,7 @@
/** /**
* DRIVER_EXTRUDERS * DRIVER_EXTRUDERS
*/ */
#if DISABLED(MKR4) && DISABLED(NPR2) && DISABLED(DONDOLO) #if DISABLED(MKR4) && DISABLED(NPR2) && DISABLED(DONDOLO) && DISABLED(COLOR_MIXING_EXTRUDER)
#undef DRIVER_EXTRUDERS #undef DRIVER_EXTRUDERS
#define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder #define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder
#endif #endif
......
...@@ -271,6 +271,18 @@ ...@@ -271,6 +271,18 @@
#endif #endif
#endif #endif
#if ENABLED(COLOR_MIXING_EXTRUDER)
#if EXTRUDERS > 1
#error COLOR_MIXING_EXTRUDER supports plus one extruder.
#endif
#if DRIVER_EXTRUDERS < 2
#error You must set DRIVER_EXTRUDERS >= 2 for a mixing extruder.
#endif
#if ENABLED(FILAMENT_SENSOR)
#error COLOR_MIXING_EXTRUDER is incompatible with FILAMENT_SENSOR. Comment out this line to use it anyway.
#endif
#endif
#if ENABLED(NPR2) #if ENABLED(NPR2)
#if DISABLED(COLOR_STEP) #if DISABLED(COLOR_STEP)
#error DEPENDENCY ERROR: Missing setting COLOR_STEP #error DEPENDENCY ERROR: Missing setting COLOR_STEP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment