Skip to content

Commit

Permalink
Chameleon multi-extruder
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Jun 22, 2023
1 parent 2871541 commit be4f916
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 17 deletions.
1 change: 1 addition & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@
* PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
* EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware)
* EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware)
* CHAMELEON : Chameleon with up to 4 switchable filaments
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* See additional options in Configuration_adv.h.
Expand Down
30 changes: 29 additions & 1 deletion Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -4325,7 +4325,35 @@

//#define MMU2_DEBUG // Write debug info to serial output

#endif // HAS_PRUSA_MMU2
#elif HAS_CHAMELEON
#define CHAMELEON_BUTTON1_X X_MAX_POS // Button 1 depressed position
#define CHAMELEON_BUTTON2_X X_MIN_POS // Button 2 depressed position (Used for EXTRUDERS > 2)
//#define CHAMELEON_TOOLCHANGE_Y Y_CENTER // A standard Y position for all tool-changes
//#define CHAMELEON_TOOLCHANGE_Z Z_MAX_POS // Enable and adjust if the switch is top-mounted

// Design the ramming sequence to first retract out of the hotend,
// then do blob elimination at the tip, then retract all the way
// back out of the feeder splitter.
#define CHAMELEON_RAMMING_SEQUENCE \
{ -10, 10000 }, /* < fast (shape) */ \
{ -40, 600 }, /* < slow (cool) */ \
{ +50, 10000 }, /* > fast (shape) */ \
{ -10, 10000 }, /* < fast (shape) */ \
{ -40, 600 }, /* < slow (cool) */ \
{ +51, 10000 }, /* > fast (unblob) */ \
{ -11, 10000 }, /* < fast (shape) */ \
{ +11, 10000 }, /* > fast (unblob) */ \
{ -11, 10000 }, /* < fast (shape) */ \
{ +11, 10000 }, /* > fast (unblob) */ \
{ -11, 10000 }, /* < fast (shape) */ \
{ -40, 100 }, /* < slow (cool) */ \
{ -110, 10000 }, /* < fast (shape) */ \
{ +40, 1000 }, /* > fast (shape) */ \
{ -40, 1000 }, /* < fast (shape) */ \
{ +40, 1000 }, /* > fast (shape) */ \
{ -130, 5000 } /* < fast (unload) */

#endif

/**
* Advanced Print Counter settings
Expand Down
34 changes: 34 additions & 0 deletions Marlin/src/core/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@
#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K)

// Macros for initializing arrays
#define LIST_32(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,EE,FF,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,EE,FF
#define LIST_31(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,EE,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,EE
#define LIST_30(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,DD
#define LIST_29(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,CC
#define LIST_28(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,BB,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,TU,V,W,X,Y,Z,AA,BB
#define LIST_27(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA
#define LIST_26(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
#define LIST_25(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y
#define LIST_24(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X
Expand Down Expand Up @@ -515,6 +521,17 @@
#define INC_18 19
#define INC_19 20
#define INC_20 21
#define INC_21 22
#define INC_22 23
#define INC_23 24
#define INC_24 25
#define INC_25 26
#define INC_26 27
#define INC_27 28
#define INC_28 29
#define INC_29 30
#define INC_30 31
#define INC_31 32
#define INCREMENT_(n) INC_##n
#define INCREMENT(n) INCREMENT_(n)

Expand Down Expand Up @@ -550,6 +567,23 @@
#define DEC_13 12
#define DEC_14 13
#define DEC_15 14
#define DEC_16 15
#define DEC_17 16
#define DEC_18 17
#define DEC_19 18
#define DEC_20 19
#define DEC_21 20
#define DEC_22 21
#define DEC_23 22
#define DEC_24 23
#define DEC_25 24
#define DEC_26 25
#define DEC_27 26
#define DEC_28 27
#define DEC_29 28
#define DEC_30 29
#define DEC_31 30
#define DEC_32 31
#define DECREMENT_(n) DEC_##n
#define DECREMENT(n) DECREMENT_(n)

Expand Down
128 changes: 128 additions & 0 deletions Marlin/src/feature/mmu/chameleon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

#include "../../inc/MarlinConfig.h"

#if HAS_CHAMELEON

#include "chameleon.h"
//#include "../../MarlinCore.h"
#include "../../module/planner.h"
#include "../../module/stepper.h"
#include "../../lcd/marlinui.h"

//#define DEBUG_OUT ENABLED(DEBUG_CHAMELEON)
#include "../../core/debug_out.h"

Chameleon chameleon;

struct E_Step {
float extrude;
feedRate_t feedRate;
};

// Change tools the Chameleon 3D way
void Chameleon::tool_change(const uint8_t index) {
const uint8_t switches = active_extruder ^ index;
if (!switches) return;

ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1));

#ifdef CHAMELEON_TOOLCHANGE_Y
current_position.y = CHAMELEON_TOOLCHANGE_Y;
#endif
#ifdef CHAMELEON_TOOLCHANGE_Z
NOLESS(current_position.z, CHAMELEON_TOOLCHANGE_Z);
line_to_current_position(5000);
#endif
if (switches & 0x1) {
current_position.x = CHAMELEON_BUTTON1_X + (X_CENTER > (CHAMELEON_BUTTON1_X)) ? 10 : -10;
}
else {
#if EXTRUDERS > 2
if (switches & 0x2)
current_position.x = CHAMELEON_BUTTON2_X + (X_CENTER > (CHAMELEON_BUTTON2_X)) ? 10 : -10;
#endif
}
line_to_current_position(5000);

static constexpr E_Step ramming_sequence[] PROGMEM = { CHAMELEON_RAMMING_SEQUENCE };
execute_extruder_sequence(ramming_sequence, COUNT(ramming_sequence));

toggle(switches);

active_extruder = index;

ui.reset_status();
}

// Execute a list of E moves
void Chameleon::execute_extruder_sequence(const E_Step * const sequence, const uint8_t steps) {
planner.synchronize();
stepper.enable_extruder();

const E_Step *step = sequence;

for (uint8_t i = 0; i < steps; ++i) {
const float es = pgm_read_float(&(step->extrude));
const uint16_t fr_or_ms = pgm_read_float(&(step->feedRate));

DEBUG_ECHO_MSG("Move E", es, " @ ", fr_or_ms);

if (es) {
current_position.e += es;
line_to_current_position(MMM_TO_MMS(fr_or_ms));
planner.synchronize();
}
else
safe_delay(fr_or_ms);

step++;
}

// Reset E to 0 for the new extruder tool
current_position.e = 0;
sync_plan_position_e();

stepper.disable_extruder();
}

// Bump the switches needed to change feeders
void Chameleon::toggle(const uint8_t switches) {
if (switches & 0x1) {
current_position.x = CHAMELEON_BUTTON1_X;
line_to_current_position(2000);
current_position.x += (X_CENTER > (CHAMELEON_BUTTON1_X)) ? 10 : -10;
line_to_current_position(2000);
}
#if EXTRUDERS > 2
if (switches & 0x2) {
current_position.x = CHAMELEON_BUTTON2_X;
line_to_current_position(2000);
current_position.x += (X_CENTER > (CHAMELEON_BUTTON2_X)) ? 10 : -10;
line_to_current_position(2000);
}
#endif
planner.synchronize();
}

#endif // HAS_CHAMELEON
38 changes: 38 additions & 0 deletions Marlin/src/feature/mmu/chameleon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once

#include <stdint.h>

struct E_Step;

class Chameleon {
public:
Chameleon() {}
static void tool_change(const uint8_t new_tool);

private:
static void execute_extruder_sequence(const E_Step * const sequence, const uint8_t steps);
static void toggle(const uint8_t switches);
};

extern Chameleon chameleon;
51 changes: 41 additions & 10 deletions Marlin/src/inc/Conditionals_LCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@
#define PRUSA_MMU1 1
#define PRUSA_MMU2 2
#define PRUSA_MMU2S 3
#define CHAMELEON 4
#define EXTENDABLE_EMU_MMU2 12
#define EXTENDABLE_EMU_MMU2S 13

Expand All @@ -581,6 +582,8 @@
#elif MMU_MODEL % 10 == PRUSA_MMU2S
#define HAS_PRUSA_MMU2 1
#define HAS_PRUSA_MMU2S 1
#elif MMU_MODEL == CHAMELEON
#define HAS_CHAMELEON 1
#endif
#if MMU_MODEL >= EXTENDABLE_EMU_MMU2
#define HAS_EXTENDABLE_MMU 1
Expand All @@ -590,6 +593,7 @@
#undef PRUSA_MMU1
#undef PRUSA_MMU2
#undef PRUSA_MMU2S
#undef CHAMELEON
#undef EXTENDABLE_EMU_MMU2
#undef EXTENDABLE_EMU_MMU2S

Expand All @@ -613,14 +617,6 @@
#else
#undef EXTRUDERS
#define EXTRUDERS 0
#undef TEMP_SENSOR_0
#undef TEMP_SENSOR_1
#undef TEMP_SENSOR_2
#undef TEMP_SENSOR_3
#undef TEMP_SENSOR_4
#undef TEMP_SENSOR_5
#undef TEMP_SENSOR_6
#undef TEMP_SENSOR_7
#undef SINGLENOZZLE
#undef SWITCHING_EXTRUDER
#undef MECHANICAL_SWITCHING_EXTRUDER
Expand Down Expand Up @@ -674,7 +670,7 @@
#define E_STEPPERS EXTRUDERS
#define E_MANUAL EXTRUDERS

#elif HAS_PRUSA_MMU2 // Průša Multi-Material Unit v2
#elif HAS_PRUSA_MMU2 || HAS_CHAMELEON // Multi-Material Unit

#define E_STEPPERS 1
#define E_MANUAL 1
Expand All @@ -686,7 +682,7 @@
#undef DISABLE_OTHER_EXTRUDERS
#endif

// Průša MMU1, MMU(S) 2.0 and EXTENDABLE_EMU_MMU2(S) force SINGLENOZZLE
// Chameleon, Průša MMU1, MMU(S) 2.0, and EXTENDABLE_EMU_MMU2(S) force SINGLENOZZLE
#if HAS_MMU
#define SINGLENOZZLE
#endif
Expand Down Expand Up @@ -771,6 +767,41 @@
#endif
#endif

#if HOTENDS <= 7
#undef TEMP_SENSOR_7
#define TEMP_SENSOR_7 0
#if HOTENDS <= 6
#undef TEMP_SENSOR_6
#define TEMP_SENSOR_6 0
#if HOTENDS <= 5
#undef TEMP_SENSOR_5
#define TEMP_SENSOR_5 0
#if HOTENDS <= 4
#undef TEMP_SENSOR_4
#define TEMP_SENSOR_4 0
#if HOTENDS <= 3
#undef TEMP_SENSOR_3
#define TEMP_SENSOR_3 0
#if HOTENDS <= 2
#undef TEMP_SENSOR_2
#define TEMP_SENSOR_2 0
#if HOTENDS <= 1
#undef TEMP_SENSOR_1
#define TEMP_SENSOR_1 0
#if HOTENDS == 0
#undef TEMP_SENSOR_0
#define TEMP_SENSOR_0 0
#undef TEMP_SENSOR_REDUNDANT
#define TEMP_SENSOR_REDUNDANT 0
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif

/**
* Number of Linear Axes (e.g., XYZIJKUVW)
* All the logical axes except for the tool (E) axis
Expand Down
11 changes: 10 additions & 1 deletion Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,12 +639,21 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#endif
#endif

#if HAS_CHAMELEON
#if EXTRUDERS > 32
#undef SINGLENOZZLE
#error "CHAMELEON only supports up to 32 EXTRUDERS. Please update your Configuration."
#endif
#endif

/**
* Options only for EXTRUDERS > 1
*/
#if HAS_MULTI_EXTRUDER

#if HAS_EXTENDABLE_MMU
#if HAS_CHAMELEON
#define MAX_EXTRUDERS 32
#elif HAS_EXTENDABLE_MMU
#define MAX_EXTRUDERS 15
#else
#define MAX_EXTRUDERS 8
Expand Down
Loading

0 comments on commit be4f916

Please sign in to comment.