Hi Gang
This is my first attempt to do anything remotely usefull, but a good place to start i think...
I have created - in my own fork:
https://github.com/stigjoergensen/Marlin
a menu method to change filament when not printing...
The menu looks sort of like this:
I have included the changes in this mail (i know this is not the right way of doing this, but as this is my first attempt i thought it would be better - and hense my next question)
What would be the best way of doing this? create a pull request from MarlinFirmware/Marlin/RCBugFix - but what happens next?
I can all ready see that there is a change made that i dont have in my copy (even though its a sync pull from 3-4 hours ago ;)... how is that handled?
and i would love to get comments on the code - this is my very arduino code, my first c++ and my first use of github - what a mouth full eh?
It consist of the following changes:
configuration.h:
//
// Change filament menu wizard
//
// add the posibility to change filament on a "cold" extruder
//
#define LCD_FILAMENT_CHANGE_FEATURE
#ifdef LCD_FILAMENT_CHANGE_FEATURE
#define lcd_filament_change_min_temperature 190
#define lcd_filament_change_max_temperature 250
#define lcd_filament_change_unload_length 50
#define lcd_filament_change_load_length 50
#define lcd_filament_change_speed 200
#endif
language_en.h
#ifndef MSG_FILAMENT_CHANGE_Extruder
#define MSG_FILAMENT_CHANGE_Extruder "Extruder"
#endif
#ifndef MSG_FILAMENT_CHANGE_Temperature
#define MSG_FILAMENT_CHANGE_Temperature "Temperature"
#endif
#ifndef MSG_FILAMENT_CHANGE_Load
#define MSG_FILAMENT_CHANGE_Load "Load Filament"
#endif
#ifndef MSG_FILAMENT_CHANGE_UnLoad
#define MSG_FILAMENT_CHANGE_UnLoad "Unload Filament"
#endif
#ifndef MSG_FILAMENT_CHANGE_Cancel
#define MSG_FILAMENT_CHANGE_Cancel "Cancel"
#endif
#ifndef MSG_FILAMENT_CHANGE_Wait
#define MSG_FILAMENT_CHANGE_Wait "Please wait."
#endif
#ifndef MSG_FILAMENT_CHANGE_Heating
#define MSG_FILAMENT_CHANGE_Heating "Heating"
#endif
and ultralcd.cpp
in top (line 120 or there about)
#ifdef LCD_FILAMENT_CHANGE_FEATURE
static void lcd_filament_change_menu();
#endif
and later from line 639
/**
*
* change filament sub menu
* by stig.joergensen
*
* Select extruder MSG_FILAMENT_CHANGE_Extruder
* Select Temperature MSG_FILAMENT_CHANGE_Temperature
* Load filament MSG_FILAMENT_CHANGE_Load
* Heating
* Cancel MSG_FILAMENT_CHANGE_Cancel
* UnLoad filament MSG_FILAMENT_CHANGE_UnLoad
* Heating
* Cancel MSG_FILAMENT_CHANGE_Cancel
* Back
* Back
*/
byte lcd_filament_change_state = 0;
int16_t lcd_filament_change_temp;
int16_t lcd_filament_change_extruder;
static void lcd_filament_change_heat() { // lets heat the choosen hotend
char buffer[8]; // "###/###o"
thermalManager.setTargetHotend(lcd_filament_change_temp, lcd_filament_change_extruder);
safe_delay(250);
bool menuclick = false; // lcd_clicked is not updated in this busy wait loop, so we get it our self
while(thermalManager.isHeatingHotend(lcd_filament_change_extruder) && !menuclick) {
START_MENU();
#if LCD_HEIGHT > 2
STATIC_ITEM(MSG_FILAMENT_CHANGE_Wait, true, false);
#endif
sprintf_P(buffer, PSTR("%i/%i" LCD_STR_DEGREE ), int(thermalManager.current_temperature[lcd_filament_change_extruder]), int(thermalManager.target_temperature[lcd_filament_change_extruder]));
STATIC_ITEM(MSG_FILAMENT_CHANGE_Heating ": ", true, false, buffer);
STATIC_ITEM(">" MSG_FILAMENT_CHANGE_Cancel,false,false); // simulate a menu item
END_MENU();
menuclick = LCD_CLICKED;
safe_delay(250); // wait a 1/4 sec before we update the display again in the loop, or we exit due to cancel
}
if(menuclick) { // we got a click on our simulated cancel menu item
defer_return_to_status = false; // revert to normal menu behaivour if we canceled the operation
lcd_quick_feedback(); // do audio feed back on the click
thermalManager.setTargetHotend(0, lcd_filament_change_extruder);
lcd_filament_change_state = 0; // Revert to Change filament menu
} else {
lcd_buzz(800,2000);
}
lcd_clicked=false; // reset the lcd clicked just in case we actually got it from our manual menu_item
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
}
static void lcd_filament_change_unload() {
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
lcd_filament_change_heat();
if (lcd_filament_change_state != 0) {
// I wonder if the last parameter buffer_line_kinematic should be the extuder choosen, and if i need to change extruder with T?? or should i set active_extruder?
enqueue_and_echo_commands_P(PSTR("T" STRINGIFY(lcd_filament_change_extruder)));
current_position[E_AXIS] -= lcd_filament_change_unload_length;
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(lcd_filament_change_speed), lcd_filament_change_extruder);
}
}
static void lcd_filament_change_load() {
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
lcd_filament_change_heat();
if (lcd_filament_change_state != 0) {
// I wonder if the last parameter buffer_line_kinematic should be the extuder choosen, and if i need to change extruder with T?? or should i set active_extruder?
enqueue_and_echo_commands_P(PSTR("T" STRINGIFY(lcd_filament_change_extruder)));
current_position[E_AXIS] += lcd_filament_change_load_length;
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(lcd_filament_change_speed), lcd_filament_change_extruder);
}
}
static void lcd_filament_change_setTemperature() {
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
lcd_filament_change_state = 2;
}
static void lcd_filament_change_setExtruder() {
defer_return_to_status = true; // make sure we dont go to status screen while we are chaning filament
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
lcd_filament_change_state = 1;
}
static void lcd_filament_change_done() {
lcd_goto_previous_menu();
defer_return_to_status = false; // revert to normal menu behaivour if we canceled the operation
thermalManager.setTargetHotend(0, lcd_filament_change_extruder);
lcd_filament_change_state = 0; // Revert to Change filament menu
}
static void lcd_filament_change_menu() {
START_MENU();
switch(lcd_filament_change_state) {
case 0:
MENU_ITEM_EDIT_CALLBACK(int3, MSG_FILAMENT_CHANGE_Extruder, &lcd_filament_change_extruder, 0, EXTRUDERS-1, lcd_filament_change_setExtruder);
MENU_BACK(MSG_MAIN);
break;
case 1:
MENU_ITEM_EDIT_CALLBACK(int3, MSG_FILAMENT_CHANGE_Temperature, &lcd_filament_change_temp, lcd_filament_change_min_temperature, lcd_filament_change_max_temperature, lcd_filament_change_setTemperature);
MENU_BACK(MSG_MAIN);
break;
case 2:
MENU_ITEM(function,MSG_FILAMENT_CHANGE_UnLoad,lcd_filament_change_unload);
MENU_ITEM(function,MSG_FILAMENT_CHANGE_Load,lcd_filament_change_load);
MENU_ITEM(function,MSG_MAIN,lcd_filament_change_done);
break;
}
END_MENU();
} // lcd_filament_change()
I applaud your effort, but isn't that already available?
As far as i have seen, and tested that change_filament its mostly (here i write mostly, as im not 100% sure either way) for changing filament when printing. atleast thats what it sais when issuing M600 on a cold hotend. so i read this as total different thing.
besides, i seem to recall a thread about a person complaining about only having two different temperatures - so i have attempted to fix that.
@stigjoergensen I did something similar a few month ago and find it extremely useful. See #5052
When https://github.com/MarlinFirmware/Marlin/blob/d97dc10216d9a431278052e5b60973bafeeed7e0/Marlin/Configuration_adv.h#L604
came up i tried it right away and was a little disapointed that it ONLY works (is accessible) during printing.
I moved the entry in ultralcd.cpp from https://github.com/MarlinFirmware/Marlin/blob/d97dc10216d9a431278052e5b60973bafeeed7e0/Marlin/ultralcd.cpp#L829
to here
https://github.com/MarlinFirmware/Marlin/blob/d97dc10216d9a431278052e5b60973bafeeed7e0/Marlin/ultralcd.cpp#L622
This made it accessible, but it won't work as it requires a manual heatup of the extruder.
I returned to my version i always used, as it works perfect. BUT, only exactly for my setup. I always wanted to make it configurable and open a PR, but there was always other stuff to do :)
I greatly appreciate if you continue with your attempt. This looks very promising!
If you have a display you usually have a sd-card.
If you have a display and a sd-card you can select start files from the sd-card.
With directories you can rebuild a menu structure.
About everything what you can do, as long no other print is active, can be done by a g-code script.
Writing a filament change script is trivial.
PLA2PLA.G
PLA2ABS.G
ABS2PLA.G
ABS2ABS.G
COLDPULL.G
...
Why bloating Marlin?
Personally I use GCode files named "load.gcode", "eject.gcode", etc., and keep them in a "utilities" folder on the SD card. For example, here's my fancy "Eject.gcode" script which starts slowly but then increases speed…
Eject With Status Update
; Eject the Filament
M109 S200 ;heat up to 200C
M117 Ejecting filament...
G92 E50 ;set extruder at 50mm...
G91 ;relative positioning
;eject 60x1mm (Stoppable)
M117 Ejecting 60mm...
G1 F30 E-1
M117 Ejecting 59mm...
G1 F30 E-1
M117 Ejecting 58mm...
G1 F30 E-1
M117 Ejecting 57mm...
G1 F31 E-1
M117 Ejecting 56mm...
G1 F31 E-1
M117 Ejecting 55mm...
G1 F31 E-1
M117 Ejecting 54mm...
G1 F32 E-1
M117 Ejecting 53mm...
G1 F32 E-1
M117 Ejecting 52mm...
G1 F32 E-1
M117 Ejecting 51mm...
G1 F33 E-1
M117 Ejecting 50mm...
G1 F33 E-1
M117 Ejecting 49mm...
G1 F33 E-1
M117 Ejecting 48mm...
G1 F34 E-1
M117 Ejecting 47mm...
G1 F34 E-1
M117 Ejecting 46mm...
G1 F34 E-1
M117 Ejecting 45mm...
G1 F35 E-1
M117 Ejecting 44mm...
G1 F35 E-1
M117 Ejecting 43mm...
G1 F35 E-1
M117 Ejecting 42mm...
G1 F36 E-1
M117 Ejecting 41mm...
G1 F36 E-1
M117 Ejecting 40mm...
G1 F36 E-1
M117 Ejecting 49mm...
G1 F37 E-1
M117 Ejecting 48mm...
G1 F37 E-1
M117 Ejecting 47mm...
G1 F37 E-1
M117 Ejecting 46mm...
G1 F38 E-1
M117 Ejecting 45mm...
G1 F38 E-1
M117 Ejecting 44mm...
G1 F38 E-1
M117 Ejecting 43mm...
G1 F39 E-1
M117 Ejecting 42mm...
G1 F39 E-1
M117 Ejecting 41mm...
G1 F39 E-1
M117 Ejecting 40mm...
G1 F40 E-1
M117 Ejecting 39mm...
G1 F40 E-1
M117 Ejecting 38mm...
G1 F40 E-1
M117 Ejecting 37mm...
G1 F41 E-1
M117 Ejecting 36mm...
G1 F41 E-1
M117 Ejecting 35mm...
G1 F41 E-1
M117 Ejecting 34mm...
G1 F42 E-1
M117 Ejecting 33mm...
G1 F42 E-1
M117 Ejecting 32mm...
G1 F42 E-1
M117 Ejecting 31mm...
G1 F43 E-1
M117 Ejecting 30mm...
G1 F43 E-1
M117 Ejecting 29mm...
G1 F43 E-1
M117 Ejecting 28mm...
G1 F44 E-1
M117 Ejecting 27mm...
G1 F44 E-1
M117 Ejecting 26mm...
G1 F44 E-1
M117 Ejecting 25mm...
G1 F45 E-1
M117 Ejecting 24mm...
G1 F45 E-1
M117 Ejecting 23mm...
G1 F45 E-1
M117 Ejecting 22mm...
G1 F46 E-1
M117 Ejecting 21mm...
G1 F46 E-1
M117 Ejecting 20mm...
G1 F46 E-1
M117 Ejecting 19mm...
G1 F47 E-1
M117 Ejecting 18mm...
G1 F47 E-1
M117 Ejecting 17mm...
G1 F47 E-1
M117 Ejecting 16mm...
G1 F48 E-1
M117 Ejecting 15mm...
G1 F48 E-1
M117 Ejecting 14mm...
G1 F48 E-1
M117 Ejecting 13mm...
G1 F49 E-1
M117 Ejecting 12mm...
G1 F49 E-1
M117 Ejecting 11mm...
G1 F49 E-1
M117 Ejecting 10mm...
G1 F50 E-1
M117 Ejecting 9mm...
G1 F50 E-1
M117 Ejecting 8mm...
G1 F50 E-1
M117 Ejecting 7mm...
G1 F51 E-1
M117 Ejecting 6mm...
G1 F51 E-1
M117 Ejecting 5mm...
G1 F51 E-1
M117 Ejecting 4mm...
G1 F52 E-1
M117 Ejecting 3mm...
G1 F52 E-1
M117 Ejecting 2mm...
G1 F52 E-1
M117 Ejecting 1mm...
G1 F52 E-1
M0 Filament ejected...
M104 S0 ;extruder heater off
And load…
; Load new filament
M109 S200 ;heat up to 200C
M0 Insert filament now!
M117 Loading filament...
G92 E0 ;set extruder at 0
G91 ;relative positioning
;eject 60x1mm (Stoppable)
M117 Loading 60mm...
G1 F40 E1
M117 Loading 59mm...
G1 F40 E1
M117 Loading 58mm...
G1 F40 E1
M117 Loading 57mm...
G1 F40 E1
M117 Loading 56mm...
G1 F40 E1
M117 Loading 55mm...
G1 F40 E1
M117 Loading 54mm...
G1 F40 E1
M117 Loading 53mm...
G1 F40 E1
M117 Loading 52mm...
G1 F40 E1
M117 Loading 51mm...
G1 F40 E1
M117 Loading 50mm...
G1 F40 E1
M117 Loading 49mm...
G1 F40 E1
M117 Loading 48mm...
G1 F40 E1
M117 Loading 47mm...
G1 F40 E1
M117 Loading 46mm...
G1 F40 E1
M117 Loading 45mm...
G1 F40 E1
M117 Loading 44mm...
G1 F40 E1
M117 Loading 43mm...
G1 F40 E1
M117 Loading 42mm...
G1 F40 E1
M117 Loading 41mm...
G1 F40 E1
M117 Loading 40mm...
G1 F40 E1
M117 Loading 49mm...
G1 F40 E1
M117 Loading 48mm...
G1 F40 E1
M117 Loading 47mm...
G1 F40 E1
M117 Loading 46mm...
G1 F40 E1
M117 Loading 45mm...
G1 F40 E1
M117 Loading 44mm...
G1 F40 E1
M117 Loading 43mm...
G1 F40 E1
M117 Loading 42mm...
G1 F40 E1
M117 Loading 41mm...
G1 F40 E1
M117 Loading 40mm...
G1 F40 E1
M117 Loading 39mm...
G1 F40 E1
M117 Loading 38mm...
G1 F40 E1
M117 Loading 37mm...
G1 F40 E1
M117 Loading 36mm...
G1 F40 E1
M117 Loading 35mm...
G1 F40 E1
M117 Loading 34mm...
G1 F40 E1
M117 Loading 33mm...
G1 F40 E1
M117 Loading 32mm...
G1 F40 E1
M117 Loading 31mm...
G1 F40 E1
M117 Loading 30mm...
G1 F40 E1
M117 Loading 29mm...
G1 F40 E1
M117 Loading 28mm...
G1 F40 E1
M117 Loading 27mm...
G1 F40 E1
M117 Loading 26mm...
G1 F40 E1
M117 Loading 25mm...
G1 F40 E1
M117 Loading 24mm...
G1 F40 E1
M117 Loading 23mm...
G1 F40 E1
M117 Loading 22mm...
G1 F40 E1
M117 Loading 21mm...
G1 F40 E1
M117 Loading 20mm...
G1 F40 E1
M117 Loading 19mm...
G1 F40 E1
M117 Loading 18mm...
G1 F40 E1
M117 Loading 17mm...
G1 F40 E1
M117 Loading 16mm...
G1 F40 E1
M117 Loading 15mm...
G1 F40 E1
M117 Loading 14mm...
G1 F40 E1
M117 Loading 13mm...
G1 F40 E1
M117 Loading 12mm...
G1 F40 E1
M117 Loading 11mm...
G1 F40 E1
M117 Loading 10mm...
G1 F40 E1
M117 Loading 9mm...
G1 F40 E1
M117 Loading 8mm...
G1 F40 E1
M117 Loading 7mm...
G1 F40 E1
M117 Loading 6mm...
G1 F40 E1
M117 Loading 5mm...
G1 F40 E1
M117 Loading 4mm...
G1 F40 E1
M117 Loading 3mm...
G1 F40 E1
M117 Loading 2mm...
G1 F40 E1
M117 Loading 1mm...
G1 F40 E1
M0 Filament loaded!
I must agree, that the SD-Card -> folder -> GCODE method is way more flexible and easier to adapt for different systems. I never thought of this way, but will switch to this method now. This makes configuring a new RCBugFix even easier for me as i always had to merge my filament change into it.
Btw: Is there a way of hiding hidden system folders in Marlin like "System Volume Information" which gets created by windows on the SD Card?
This is actually a part of a bigger plan... doing filament/spool tracking.
I see the idea about using gcodes files from the SD card... but that means keep the same set of files on multiple cards.
@Blue-Marlin - well, that could be said of about 50% of the menu already... so i dont think it bloating.
@thinkyhead - cool scripts.
but i really wish that you would comment on the codeing and the implementation of the idea rather than just the idea... that was my biggest wish. and alsp on how to get this into marlin - if it should get there.
@stigjoergensen That's more or less the same thing, I was trying to write in the summer, but than some problems appeared so all my big plans were gone. I find this funtion extremely useful, K8400 has it implemented in their fork (although just by passing G-codes from menu which can't be used widely).
cool scripts. but i really wish that you would comment on the codeing and the implementation
Thanks @stigjoergensen.
In terms of the implementation, well, I'd say carefully look at the way other features are implemented in ultralcd.cpp
and try to follow suit. I don't have time to comment on all aspects of your code right now. If it works well, make a pull request and I will give it a full review.
Is there a way of hiding hidden system folders in Marlin like "System Volume Information" which gets created by windows on the SD Card?
@Kaibob2 Windows should really be setting the DIR_ATT_HIDDEN
attribute on the folder. But you can filter by name in ultralcd.cpp
…
if (card.filenameIsDir) {
if (strcmp_P(card.longFilename, PSTR("System Volume Information")))
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
}
else {
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
}
The DIR_ATT_HIDDEN
seems to be set.
but it looks like this
When i use this
if (card.filenameIsDir) {
if (strcmp_P(card.longFilename, "System Volume Information"))
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
}
else {
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
}
it compiles with an "}" missing error.
This compiles but doesn't change anything. The System volume Information is still shown
if (card.filenameIsDir) {
if (strcmp_P(card.longFilename, "System Volume Information"))
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
}
else
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
}
Oops. That string compare should've been this instead:
strcmp_P(card.longFilename, PSTR("System Volume Information"))
But anyway, don't do that. I think we can check the attribute…
The DIR_ATT_HIDDEN seems to be set.
Try adding this in cardreader.cpp
instead, in CardReader::lsDive
:
filenameIsDir = DIR_IS_SUBDIR(&p);
+ if (p.attributes & DIR_ATT_HIDDEN) continue;
if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue;
@thinkyhead PERFECT. That did the trick. Normal folders are shown, Hidden ones are hidden.
Will you integrate in RCBugFix or shall i raise a PR?
I don't mind adding it in. And I don't even need no stinkin' PR!
I don't know if this could help anyone , I Got the M600
working with 600mm though my Bowden tubes, in Configuration.h
line 383 #define EXTRUDE_MAXLENGTH 700
you need to add values to what you need then change the parameters for your setup in Configuration_adv.h
. then I wrote a simple gcode to heat the hotend followed by the M600
command.
@tibuck
I don't know if this could help anyone , I Got the M600 working with 600mm though my Bowden tubes, in Configuration.h line 383 #define EXTRUDE_MAXLENGTH 700 you need to add values to what you need then change the parameters for your setup in Configuration_adv.h. then I wrote a simple gcode to heat the hotend followed by the M600 command.
after hotend heats and it starts retracting for a filament change, can you press the lcd button to stop the retraction? or would you have to wait the whole 700mm or whatever value you use?
@jordathan
sadly it would have to run the 700mm there is no lcd manual stop .
The g26 validation has a press when primed feature so you can make sure it's ready. I'm just trying to figure out how to implement other features into others like if you have to stop a print via LCD it should also disable steppers
@jordathan Eventually that would be good, as there is more and more users with Duet's, with that nice big touch screen there could a lot more options like those. im at the mercy of smarter folks as I have Zero know how with it comes to programing. if it wasn't for all the wonderful work from everyone I would have 3d printer, I just couldn't afford it.
I'd love to learn just not sure it I would need to check out arduino, or marlin first. Plus marlin is a mix of grbl and sprinter or whatever. Just not sure where to start
Most helpful comment
I don't mind adding it in. And I don't even need no stinkin' PR!