diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 119f81415a30d..c9a70967bdedc 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -376,6 +376,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.
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index da9f3a66c688d..af4a2a986a465 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -4352,7 +4352,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
diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h
index bb2bea2e30282..47cf997042667 100644
--- a/Marlin/src/core/macros.h
+++ b/Marlin/src/core/macros.h
@@ -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
@@ -551,6 +557,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)
@@ -586,6 +603,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)
diff --git a/Marlin/src/feature/mmu/chameleon.cpp b/Marlin/src/feature/mmu/chameleon.cpp
new file mode 100644
index 0000000000000..a10daa0f9aa80
--- /dev/null
+++ b/Marlin/src/feature/mmu/chameleon.cpp
@@ -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 .
+ *
+ */
+
+#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
diff --git a/Marlin/src/feature/mmu/chameleon.h b/Marlin/src/feature/mmu/chameleon.h
new file mode 100644
index 0000000000000..1a2597741f1b4
--- /dev/null
+++ b/Marlin/src/feature/mmu/chameleon.h
@@ -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 .
+ *
+ */
+#pragma once
+
+#include
+
+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;
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index b069e2d2b173b..79615781e3c12 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -585,6 +585,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
@@ -597,6 +598,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
@@ -606,6 +609,7 @@
#undef PRUSA_MMU1
#undef PRUSA_MMU2
#undef PRUSA_MMU2S
+#undef CHAMELEON
#undef EXTENDABLE_EMU_MMU2
#undef EXTENDABLE_EMU_MMU2S
@@ -629,14 +633,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
@@ -690,7 +686,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
@@ -702,7 +698,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
@@ -787,6 +783,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
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index cfc3b20cd5014..7e2cca7a7e1ad 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -643,13 +643,22 @@ 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
#ifndef MAX_EXTRUDERS
- #if HAS_EXTENDABLE_MMU
+ #if HAS_CHAMELEON
+ #define MAX_EXTRUDERS 32
+ #elif HAS_EXTENDABLE_MMU
#define MAX_EXTRUDERS 15
#else
#define MAX_EXTRUDERS 8
diff --git a/Marlin/src/module/stepper/indirection.h b/Marlin/src/module/stepper/indirection.h
index e82ab66e00d06..9e9f6f9c7b2e0 100644
--- a/Marlin/src/module/stepper/indirection.h
+++ b/Marlin/src/module/stepper/indirection.h
@@ -587,6 +587,12 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define FWD_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? HIGH : LOW ); }while(0)
#define REV_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? LOW : HIGH); }while(0)
+#elif ENABLED(CHAMELEON) // One multiplexed stepper driver, reversed on T2/T3, T6/T7, T10/T11, etc.
+
+ #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
+ #define NORM_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 1) ? HIGH : LOW ); }while(0)
+ #define REV_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 1) ? LOW : HIGH); }while(0)
+
#elif E_STEPPERS > 1
#if E_STEPPERS > 7
diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp
index 4c286c81a0ade..17e184cf4ca89 100644
--- a/Marlin/src/module/tool_change.cpp
+++ b/Marlin/src/module/tool_change.cpp
@@ -81,6 +81,8 @@
#include "../feature/mmu/mmu.h"
#elif HAS_PRUSA_MMU2
#include "../feature/mmu/mmu2.h"
+#elif HAS_CHAMELEON
+ #include "../feature/mmu/chameleon.h"
#endif
#if HAS_MARLINUI_MENU
@@ -1106,6 +1108,12 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
mixer.T(new_tool);
#endif
+ #elif HAS_CHAMELEON
+
+ UNUSED(no_move);
+
+ chameleon.tool_change(new_tool);
+
#elif HAS_PRUSA_MMU2
UNUSED(no_move);
diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560
index 46de664e43b64..2236d078620f1 100755
--- a/buildroot/tests/mega2560
+++ b/buildroot/tests/mega2560
@@ -39,20 +39,20 @@ exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE ..."
# Add a Sled Z Probe, use UBL Cartesian moves, use Japanese language
#
use_example_configs AnimationExample
-opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO LCD_LANGUAGE jp_kana DEFAULT_EJERK 10 \
- EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 5 TEMP_SENSOR_3 20 TEMP_SENSOR_4 1000 TEMP_SENSOR_BED 1
+opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO \
+ EXTRUDERS 8 TEMP_SENSOR_BED 1 MMU_MODEL CHAMELEON DEFAULT_EJERK 10 LCD_LANGUAGE jp_kana
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI SHOW_CUSTOM_BOOTSCREEN BOOT_MARLIN_LOGO_SMALL \
SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES \
SDSUPPORT LONG_FILENAME_WRITE_SUPPORT SDCARD_SORT_ALPHA NO_SD_AUTOSTART USB_FLASH_DRIVE_SUPPORT CANCEL_OBJECTS \
Z_PROBE_SLED AUTO_BED_LEVELING_UBL UBL_HILBERT_CURVE UBL_TILT_ON_MESH_POINTS UBL_TILT_ON_MESH_POINTS_3POINT \
RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT \
EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_MENU_MAIN \
- MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE QUICK_HOME \
+ NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE CLASSIC_JERK LIN_ADVANCE QUICK_HOME \
NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL \
SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
- BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET DOUBLECLICK_FOR_Z_BABYSTEPPING BABYSTEP_HOTEND_Z_OFFSET BABYSTEP_DISPLAY_TOTAL
+ BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET DOUBLECLICK_FOR_Z_BABYSTEPPING BABYSTEP_DISPLAY_TOTAL
opt_disable SEGMENT_LEVELED_MOVES
-exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE | Sled Probe | Skew | JP-Kana | Babystep offsets ..." "$3"
+exec_test $1 $2 "Azteeg X3 Pro | Chameleon (x8) | RRDFGSC | UBL | LIN_ADVANCE | Sled Probe | Skew | JP-Kana | Babystep offsets ..." "$3"
#
# 5 runout sensors with distinct states
diff --git a/ini/features.ini b/ini/features.ini
index 1a3546e575fdc..6b6c355c7b73f 100644
--- a/ini/features.ini
+++ b/ini/features.ini
@@ -258,6 +258,7 @@ HAS_MEATPACK = build_src_filter=+ +
HAS_PRUSA_MMU1 = build_src_filter=+
HAS_PRUSA_MMU2 = build_src_filter=+ +
+HAS_CHAMELEON = build_src_filter=+
PASSWORD_FEATURE = build_src_filter=+ +
ADVANCED_PAUSE_FEATURE = build_src_filter=+ + +
PSU_CONTROL = build_src_filter=+