# Specific 3D Printers, Scanners, & Hardware > RepRap Format Printer Forum > Firmware Enhancements to Marlin >  Filament Change Command for Non-Ultipanel Users

## Roxy

Having the ability to change filaments during the middle of a print is a very useful feature.  It lets you do things like this without having multiple extruders:

http://3dprintboard.com/showthread.p...-Roxy-Iris-Box

If you are running with an Ultipanel, you can enable the experimental 'Filament Change' command.  You go into the Configuration_Adv.h file and find the:

  #define FILAMENTCHANGEENABLE  

line and enable it.   At that point you can use the M600 command in the GCode to strategically stop a print, move the nozzle a safe distance away from what is already printed and change the filament.   Usually you would do this to switch colors but there are other reasons to change the filament.

OK...  Fine...  But what if you don't have an Ultipanel?   Well, that is what this thread is all about.  You can still make use of the 'Filament Change'
command!   

I'm speculating but my guess is the 'Filament Change' command and it's code were done by the Ultipanel people to promote sales of the Ultipanel.  The code is well done but it requires the presence of an Utipanel to use it.

We can change that fact. (Not the fact that the code is well done!  Just the fact you need an Ultipanel to use it.)  I'm running on a PrintrBoard so the code and directions presented here will reflect that fact.  With that said, it won't be hard to modify these directions to reflect any board that is running the Marlin firmware.

OK, lets get down to business.   First, we need to wire up a switch to your controller board.  The purpose of this switch is to let the controler board
know you have completed the filament change and it can continue with the print.

If you are running with a PrintrBoard, pull up the attached diagram of the PrintrBoard.   You will want to wire a Normally Open switch to pin 14 of the EXP-2 header.  It will be the pin closest to the Atmel 90USB1286 chip.   You will need to ground the other connector of the switch.   This will allow you to tell the controller board to continue once you get the filament changed during the middle of a print.  If you are using a RAMPS board or something else, you can still do this but we will need to find a suitable pin for you to connect your switch up to.  Please make a post if you are having trouble getting an extra switch wired up to your controller board.  It would be ideal if the RAMPS board can use the exact same GPIO pin of the Atmel processor but what ever the answer is, lets document it so people can follow in your foot paths.  (Just to be clear, we need to know both the Virtual Pin # and where it comes out on the board you are using.)


Printrboard-PC-Board---Roxy detail added.jpg

With the hardware changes out of the way, we need to make a few changes to the firmware.  First, go into Configuration_Adv.h     Find the section that says:

//adds support for experimental filament exchange support M600; requires display
#ifdef ULTIPANEL
  #define FILAMENTCHANGEENABLE
  #ifdef FILAMENTCHANGEENABLE
    #define FILAMENTCHANGE_XPOS 3
    #define FILAMENTCHANGE_YPOS 3
    #define FILAMENTCHANGE_ZADD 10
    #define FILAMENTCHANGE_FIRSTRETRACT -2
    #define FILAMENTCHANGE_FINALRETRACT -100
  #endif
#endif

You don't have an ULTIPANEL but you want the ability to change filament in the middle of a print.  We are going to comment out the ULTIPANEL requirement.   Change this block to look like this:

//adds support for experimental filament exchange support M600; requires display
//#ifdef ULTIPANEL
  #define FILAMENTCHANGEENABLE
  #ifdef FILAMENTCHANGEENABLE
    #define FILAMENTCHANGE_XPOS 3
    #define FILAMENTCHANGE_YPOS 3
    #define FILAMENTCHANGE_ZADD 10
    #define FILAMENTCHANGE_FIRSTRETRACT -2
    #define FILAMENTCHANGE_FINALRETRACT -100
  #endif
//#endif

You don't need to do what I did, but I wanted the nozzle further away from the print so I had more room to work.  My origin is in the back right corner so it may not make sense for you to change the X & Y like I did.  But I do encourage you to consider changing the Z to a bigger number.  The reason is, when you are feeding in the new filament during the change you will be extruding some hot plastic.  You don't want it getting on your partially printed part while it is still hot.  If you have the room in your print envelope to move further than 10 mm away, you probably want to do it.

My block of #define's for the filament change looks like this:

//adds support for experimental filament exchange support M600; requires display 
//#ifdef ULTIPANEL  // Filament change no longer requires an Ultipanel!
  #define FILAMENTCHANGEENABLE
  #ifdef FILAMENTCHANGEENABLE
    #define FILAMENTCHANGE_XPOS 130
    #define FILAMENTCHANGE_YPOS 130
    #define FILAMENTCHANGE_ZADD 35
    #define FILAMENTCHANGE_FIRSTRETRACT -2
    #define FILAMENTCHANGE_FINALRETRACT -100
  #endif
//#endif

Now we need to go make a few changes in Marlin_Main.CPP.   We first need to add the support routines the M600 code will need to know you pressed the switch to continue.   I put them after the Setup() function.   Find the defination for:  void Setup()   and go about 60 lines further down in the file.  You should see these lines of code:

 lcd_init();
  _delay_ms(1000);    // wait 1sec to display the splash screen

  #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
    SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
  #endif

  #ifdef DIGIPOT_I2C
    digipot_i2c_init();
  #endif
}

After this closing brace for Setup() add this code:


// Roxy substitute routine to provide user confirmation easily on a PrintrBoard.
// It looks at GPIO PC1 pin 11 value for input value change.
// This routine looks for a button press to confirm everything is OK.
// This allows the firmware to provide the Filament Change feature without
// an LCD panel installed.   The switch is wired from the Expansion Port 2
// header pin closest to AT90USB1286 chip to a switch that can connect it to 
// Ground.

#ifdef FILAMENTCHANGEENABLE
#ifndef ULTIPANEL

bool lcd_clicked()
 {
        int pin_being_examined;
        int ii, iii, jj;

        pin_being_examined=12;                      // This is PC1 on PrintrBoard

        pinMode(pin_being_examined, INPUT_PULLUP);  // Set it to Input with a pull up if it hasnt
        delay(50);                                  // been used since RESET.

        iii = digitalRead(pin_being_examined);      // Get the current state of pin.  

        return !iii;
}

void lcd_pressed()
 {

    while( lcd_clicked() != 0 )            // Wait for the switch to be released
        ;
    delay(50);
    while( lcd_clicked() != 1 )            // Wait for the switch to be pressed
        ;
    delay(50);
}
#endif 
#endif 

This is going to provide the support functions for the M600 command.   You are ready to compile and load your controller board with the new firmware.

*HOW TO USE THE NEW M600 COMMAND:*

OK, now its time to test the new command.   What I typically do is have a flat surface on my print but have letters or a pattern that rise higher up.   I
slice the .STL file and then open up the GCode in    http://gcode.ws/#  You can use this website to find the exact layer where you want to change
colors.   Once you know the layer, you pull the GCode file into your text editor and look for the place where it tells your printer to go to that level.

Suppose I wanted a different color starting at 12.650 mm.  It will typically take the form of this:

G1 Z12.650 F7800.000 ; move to next layer (68)

You want to search for "G1 Z12.65" and then add a line after this that gives it an M600 command.

G1 Z12.650 F7800.000 ; move to next layer (68)
M600

Now when the printer is printing and gets to the M600 command, it will back the nozzle away from the part and allow you change filament!  Once you have the filament changed, press the continue button and start printing with the new filament.   The M600 command has a lot of nice parameters.  You can just put M600 into your GCode to use it.  It will behave very nicely in its default case.  But if you need the nozzle to go to a different location or you need more room to work or you want it to pull more filament out of the nozzle automatically, the parameters are there to do it.  I encourage you to examine the actual code in Marlin_Main.cpp for the full detail.  (You can find the code by searching for 600:  )

----------

