
i woulld like to know how i could add another stepper motor to be the extruder for 4 more filaments i have no idea how to code but i know its posible by selecting one motor for filaments t0-t3 then selecting the new one for t4-t7 just wandering if someone knows how to code this into the firmware
My thoughts on this... (unfinished)
Changes to Original Mk4.1 for 8 color setup (one sel. + two ext.) Work in progress
*************************************************
From here on the real works might start. We need to change extStep to either ext1Step or extStep2 and we have to change extDir to either ext1Dir or ext2Dir in case of T0-T3 or T4-T7.
*************************************************
Untested / Unfinished
CNC Shield v3:
// Settings on Shield
// A4988 in base X (ext1)
// A4988 in base Z (ext2) <--- new ext2
// defines pins numbers - Arduino UNO with CNC Shield V3
// A4988 in base Y (sel)
// X.STEP /DR (ext1)
// Z.STEP /DR (ext2)
// Y.STEP /DR (sel)
// END STOPS Z+ (clippy)
// CoolEn (trigger)
// DA (s_limit)
// CL (filament)
#define ext1Enable 8
#define ext1Step 2
#define ext1Dir 5
#define ext2Enable 8
#define ext2Step 4
#define ext2Dir 7
#define selEnable 8
#define selStep 3
#define selDir 6
#define trigger A3
#define s_limit A4
#define filament A5
filamentCutter.attach(11);
...
// Sets the four pins as Outputs
pinMode(ext1Enable, OUTPUT);
pinMode(ext2Enable, OUTPUT);
pinMode(ext1Step, OUTPUT);
pinMode(ext2Step, OUTPUT);
pinMode(ext1Dir, OUTPUT);
pinMode(ext2Dir, OUTPUT);
...
// display command for each button pulse
void displayCommand(long commandCount)
{
switch(commandCount)
{
case 2:
displayText(25, " Switch to T0");
break;
case 3:
displayText(25, " Switch to T1");
break;
case 4:
displayText(25, " Switch to T2");
break;
case 5:
displayText(25, " Switch to T3");
break;
case 5:
displayText(25, " Switch to T4");
break;
case 6:
displayText(25, " Switch to T5");
break;
case 7:
displayText(25, " Switch to T6");
break;
case 8:
displayText(25, " Switch to T7");
break;
case 9:
displayText(25, " Home/Load T0");
break;
case 10:
displayText(28, " Unload/Home");
break;
case 11:
displayText(50, " Home");
break;
case 12:
displayText(50, " Next");
break;
case 13:
displayText(40, " Random");
break;
default:
displayText(30, " No Command");
break;
}
...
// select case for commands
switch (commandCount)
{
case 2: // unload current, switch to #0, load
displayText(30, " T0 Selected");
currentExtruder = 0;
processMoves();
displayText(35, " Idle - T0");
break;
case 3: // unload current, switch to #1, load
displayText(30, " T1 Selected");
currentExtruder = 1;
processMoves();
displayText(35, " Idle - T1");
break;
case 4: // unload current, switch to #2, load
displayText(30, " T2 Selected");
currentExtruder = 2;
processMoves();
displayText(35, " Idle - T2");
break;
case 5: // unload current, switch to #3, load
displayText(30, " T3 Selected");
currentExtruder = 3;
processMoves();
displayText(35, " Idle - T3");
break;
case 6: // unload current, switch to #4, load
displayText(30, " T4 Selected");
currentExtruder = 4;
processMoves();
displayText(35, " Idle - T4");
break;
case 7: // unload current, switch to #5, load
displayText(30, " T5 Selected");
currentExtruder = 5;
processMoves();
displayText(35, " Idle - T5");
break;
case 8: // unload current, switch to #6, load
displayText(30, " T6 Selected");
currentExtruder = 6;
processMoves();
displayText(35, " Idle - T6");
break;
case 9: // unload current, switch to #7, load
displayText(30, " T7 Selected");
currentExtruder = 7;
processMoves();
displayText(35, " Idle - T7");
break;
case 10: //home and reload #1
displayText(40, " Homing...");
homeSelector();
displayText(15, " Press to Load T0");
gotoExtruder(0, 0);
if(loaderMode>0)rotateExtruder1(clockwise, loadDistance);
if(loaderMode>0)gotoExtruder(0, 1);
currentExtruder = 0;
lastExtruder = 0;
displayText(35, " Idle - T0");
break;
case 11: // unload current and rehome selector
displayText(30, " Cutting...");
connectGillotine();
cutFilament();
switch(lastExtruder)
{
case 0:
displayText(10, " Press to Unload T0");
break;
case 1:
displayText(10, " Press to Unload T1");
break;
case 2:
displayText(10, " Press to Unload T2");
break;
case 3:
displayText(10, " Press to Unload T3");
break;
case 4:
displayText(10, " Press to Unload T4");
break;
case 5:
displayText(10, " Press to Unload T5");
break;
case 6:
displayText(10, " Press to Unload T6");
break;
case 7:
displayText(10, " Press to Unload T7");
break;
// How to change these lines of code to work for T0-T7? Help is needed...
}
if(loaderMode>0)gotoExtruder1((lastExtruder==3?2:lastExtruder+1),lastExtruder);
if(lastExtruder<2)
{
if(loaderMode>0)rotateExtruder1(counterclockwise, unloadDistance);
}
else
{
if(loaderMode>0)rotateExtruder1(clockwise, unloadDistance);
}
disconnectGillotine();
displayText(50, " Idle");
break;
case 12:
displayText(40, " Homing...");
homeSelector();
displayText(50, " Idle");
break;
case 13: // move to next available filament
displayText(30, " Cutting...");
connectGillotine();
cutFilament();
displayText(30, " Next Tool");
currentExtruder++;
if(currentExtruder==4)currentExtruder=0;
processMoves();
displayText(35, " Idle");
break;
case 14: // move to a random filament
displayText(30, " Cutting...");
connectGillotine();
cutFilament();
displayText(30, " Random Tool");
...
//if(displayEnabled){
oled.clear();
oled.println("");
oled.println(" 3DChameleon Mk4"); //print a welcome message
oled.println("");
oled.println("");
oled.println(str);
oled.println("");
oled.println("");
if(ioEnabled)
{
oled.print(" ");
if(T0Loaded)
{
oled.print("0 ");
}
else
{
oled.print("+ ");
}
if(T1Loaded)
{
oled.print("1 ");
}
else
{
oled.print("+ ");
}
if(T2Loaded)
{
oled.print("2 ");
}
else
{
oled.print("+ ");
}
if(T3Loaded)
{
oled.println("3");
}
else
{
oled.println("+");
}
if(T4Loaded)
{
oled.println("4");
}
else
{
oled.println("+");
}
if(T5Loaded)
{
oled.println("5");
}
else
{
oled.println("+");
}
if(T6Loaded)
{
oled.println("6");
}
else
{
oled.println("+");
}
if(T7Loaded)
{
oled.println("7");
}
else
{
oled.println("+");
}
}
else
{
oled.println(" - - - -");
}
// }
}
...
// ok... then wait for the 2nd button press to unload it
switch(lastExtruder)
{
case 0:
displayText(10, " Press to Unload T0");
break;
case 1:
displayText(10, " Press to Unload T1");
break;
case 2:
displayText(10, " Press to Unload T2");
break;
case 3:
displayText(10, " Press to Unload T3");
break;
case 4:
displayText(10, " Press to Unload T4");
break;
case 5:
displayText(10, " Press to Unload T5");
break;
case 6:
displayText(10, " Press to Unload T6");
break;
case 7:
displayText(10, " Press to Unload T7");
break;
}
...
// ok... filament unloaded, time to load the new... so tell the user
switch(currentExtruder)
{
case 0:
displayText(15, " Press to Load T0");
break;
case 1:
displayText(15, " Press to Load T1");
break;
case 2:
displayText(15, " Press to Load T2");
break;
case 3:
displayText(15, " Press to Load T3");
break;
case 3:
displayText(15, " Press to Load T4");
break;
case 3:
displayText(15, " Press to Load T5");
break;
case 3:
displayText(15, " Press to Load T6");
break;
case 3:
displayText(15, " Press to Load T7");
break;
}
...
// move the first extruder motor in a specific direction for a specific distance (unless it's a "until button is not pressed")
void rotateExtruder1(bool direction, long moveDistance)
{
// note to bill: make this acecelerate so it's very fast!!!
digitalWrite(ext1Enable, LOW); // lock the motor
digitalWrite(ext1Dir, direction); // Enables the motor to move in a particular direction
const int fastSpeed = speedDelay/2; // double time
// this is depricated right now... might bring it back in the future
if(loaderMode==1)
{
// Makes 50 pulses for making one full cycle rotation
for (long x = 0; x < (moveDistance-1); x++)
{
// this is how we pulse the motor to get it to step
digitalWrite(ext1Step, HIGH);
delayMicroseconds(fastSpeed);
digitalWrite(ext1Step, LOW);
delayMicroseconds(fastSpeed);
}
}
if(loaderMode==2)
{
// keep waiting until button is pressed
while (digitalRead(trigger) != 0)
{
delay(50);
}
// Move while button is pressed
while (digitalRead(trigger) == 0)
{
// this is how we pulse the motor to get it to step
digitalWrite(ext1Step, HIGH);
delayMicroseconds(fastSpeed);
digitalWrite(ext1Step, LOW);
delayMicroseconds(fastSpeed);
}
}
// ok, done pressing button, so make sure we're not energized (high is no, low is yes)
digitalWrite(ext1Enable, HIGH);
}
// move the second extruder motor in a specific direction for a specific distance (unless it's a "until button is not pressed")
void rotateExtruder2(bool direction, long moveDistance)
{
// note to bill: make this acecelerate so it's very fast!!!
digitalWrite(ext2Enable, LOW); // lock the motor
digitalWrite(ext2Dir, direction); // Enables the motor to move in a particular direction
const int fastSpeed = speedDelay/2; // double time
// this is depricated right now... might bring it back in the future
if(loaderMode==1)
{
// Makes 50 pulses for making one full cycle rotation
for (long x = 0; x < (moveDistance-1); x++)
{
// this is how we pulse the motor to get it to step
digitalWrite(ext2Step, HIGH);
delayMicroseconds(fastSpeed);
digitalWrite(ext2Step, LOW);
delayMicroseconds(fastSpeed);
}
}
if(loaderMode==2)
{
// keep waiting until button is pressed
while (digitalRead(trigger) != 0)
{
delay(50);
}
// Move while button is pressed
while (digitalRead(trigger) == 0)
{
// this is how we pulse the motor to get it to step
digitalWrite(ext2Step, HIGH);
delayMicroseconds(fastSpeed);
digitalWrite(ext2Step, LOW);
delayMicroseconds(fastSpeed);
}
}
// ok, done pressing button, so make sure we're not energized (high is no, low is yes)
digitalWrite(ext2Enable, HIGH);
}
************************************************** Last edit: 06.05.2025
The firmware won't care... you'll need to turn the appropriate extruder motor in your gcode instead... which should be E0 (or just E) and E1. The firmware for the 3DChameleon will still only have 4 positions, but it never knows what you're doing with it, so the E value is irrelevant to it. In your gcode, if your next_extruder is <4, you use E0 and if it's >3 then the it'll be E1.
Bill