load unload macro with endless loop and cancel condition
-
Hi there,
mighty duet-folks,has anybody played around in the new RRF3.x with loops and the corresponding break-out-conditions?
Would like to make a filament load and unload where the process of the actual e-movements for e.g. 5 seconds is repeated endless with a small pause of around 2 seconds between each un-/load. The reason for it is
a) when changing colours to use the load already as purge to wait as long until happy with the filamentcolour
b) when tightening the "tension-screw" for a BMG (double-gear-extruder) to have some time to play aroundcancel/break-out could be via a user-interaction via the duet-display or DWC (and of course for security reasons after an absurd high number of loops like 25 or so)...
Ideas are heartly welcomed - somebody please help me where to start...
-
So you could try using a combination for M291 and M292 within the loop (I have not tried this. basically the idea would be to prompt the user to cancel, using M291, if the user does not press the cancel button within a set dwell time (defined by G4) then you use M292 to cancel the message and repeat.
The "iterations" counter can be used for the >25 loops test.
https://duet3d.dozuki.com/Wiki/GCode_Meta_Commands#Section_Named_constants
-
It doesn't fit exactly your criteria as I've used distance rather than time, but I have just started using the filaments macros and have this far done this for each filament type. The move code is used for all filaments.
A couple of bits of code may be redundant because RRF already seems to checks the condition, but I was playing it safe.Typical filament files.
load.g (Filaments Directory)
;; load.g ;; M291 R"Loading ABS" P"Loading config and heating" S1 T3 G4 S3 M703 ; load config.g of this filament ; only run if not in a job if job.file.fileName!=null M291 R"Cancel loading" P"Print job in progress. Skipping load moves" S1 T5 M99; ;check if ABS is already loaded if move.extruders[state.currentTool].filament="ABS" M291 R"Cancel loading" P"Filament already loaded. Skipping load moves" S1 T5 M99; ;we know ABS isn't loaded, but if something else is, we need to unload it first ; this part of the code is untested!! if move.extruders[state.currentTool].filament!=null M98 P"0:/filaments/" ^ {move.extruders[state.currentTool].filament} ^ "/unload.g" M291 R"Unload finished" P"Press OK when ready to load new filament" S3 M291 R"Loading ABS" P"Waiting for nozzle loading temperature..." S1 T0 M98 P"0:/macros/heating/preheat_ABS.g" M116 ; Wait for temperature M291 R"Loading ABS" P"Feeding and priming..." S1 T0 M98 P"/macros/filament/do_moves_for_load.g" M292 ; Clear messages
"do moves for load.g"
Does max five loops and prompts to feed 120mm on each loop.
I have a bowden, so this equates to longer than the bowden tube if needed.do_moves_for_load.g (/macros/filaments/ directory)
;do moves for load.g - run when filament change is required. M291 P"loading do_moves_for_load.g" S1 T0 M400 ; wait for any moves if (state.currentTool=-1) || ({heat.heaters[tools[state.currentTool].heaters[0]].current < heat.coldExtrudeTemperature}) M291 P"No tool active or temp to low for loading" R"Can't proceed" S1 T10 abort; M83 ; set relative extrusion while true if iterations = 5 break M291 P"Press OK to feed 120mm of filament or CANCEL to abort" R"Ready" S3 M291 P"Feeding filament.. Please wait" R"Feeding" S1 T45 G1 E120 F180 ; feed 120mm to load filament G1 E-2 ; Retract 2mm to reduce pressure M400 ; wait for moves to finish M292 ; Clear messages M400 ; wait for moves to finish M291 R"Done" P{move.extruders[state.currentTool].filament} ^ " Filament loaded. Clear nozzle to proceed" S3
config.g (filaments/ABS directory)
; Used to set parameters for filament such as retracts, temperatures etc M291 P"loading config.g for ABS" R"Loading config" S1 T5 M302 S200 R120 ; set cold extrude and retract temperatures ;M592 D0:1 A0.012 B0 ; Set non linear extrusion M572 D0 S0.08 ;Set pressure advance M207 S0.7 F2400 Z0 ; Set retraction ;M593 F25 ; cancel ringing at 25Hz
preheat_ABS.g (macros/heating directory)
M291 R"Preheating" P"Setting preheat temperatures" S1 T0 if state.currentTool=-1 T0 M140 S90 R50 ; set bed temp M703 ; load config.g for this filament G10 P0 S{heat.coldExtrudeTemperature+10} R{heat.coldRetractTemperature+5} ; set tool temps M116 ; wait for temps M291 R"Preheating" P"Preheating... Done" S1 T5
In Prusa Slicer I have this in the start code.
This will load all the specific temp and other settings in the filament config.g like retraction etc for the specified filament.
It can be tricky using meta commands because Prusa Slicer has its own conditional code which can confuse thing, but between the two you can have very powerful and prtable code..T[current_extruder] ; select tool M104 S0 R0 T[current_extruder] ; Set temps to zero to stop slicer adding them M106 P[current_extruder] S0 ;Start with fan off M701 S"[filament_type]"; define filament ; All retraction and temp settings done in 0:/filaments/[filament_type]/config.g M703 ; load config file for [filament_type] M291 S0 T3 P"Homing..." G32 ; Level bed & home M400 ; wait for last move M83 ; Set relative extrusion ;G4 S4 ; Wait 4 Seconds for PanelDue only required if M80 is used M98 P"0:/macros/songs/charge.g" ; play start tune G4 S4 ; Wait 4 Seconds for song G21 ;metric values G90 ; Switch to using Absolute Coordinates G4 S1 ; Wait 1 Second M280 P0 S160 I1 ; Reset BL Touch M280 P3 S90 I1 ; Retract proibe M140 S[first_layer_bed_temperature_0] R{first_layer_bed_temperature[0] /2 }; Set fast bed temp & standby - Standby is half first layer temp. M116 ; Wait for bed before doing mesh probe. M561 ; clear any bed transform M557 TBD ; parameters will be set automatically to suit size of printed area G29 S0 ; do mesh for printed area G29 S1 ; load small mesh G01 X{"{move.axes[0].min }"} Y{"{move.axes[1].max}"} Z0.6 F1500 ; Move to back corner while heating G10 P0 R{"{heat.coldExtrudeTemperature+5}"} S[first_layer_temperature_0] T[current_extruder] ; (set standby and active temperatures for active tool. Standby is 5 degrees above cold extrude temp ) M118 P3 S" Waiting for temps..." G4 S1 ; Wait 1 Second M116 ; Wait for all temps to stabilise G1 X1 Y{"{move.axes[1].max -10 }"} Z0.4 F1200 ; move to edge to wipe any oozed filament G1 X1 Y{"{move.axes[1].min +10 }"} F600 E15; move and extrude G1 X{"{move.axes[0].min +1}"} G1 Y{"{move.axes[1].max -10 }"} F600 E15; move and extrude G10 ; Retract G1 X{"{move.axes[0].min +50}"} F1200 ; wipe M118 P3 S" Printing..." ;Put printing message on screen
-
@OwenD said in load unload macro with endless loop and cancel condition:
> M98 P"0:/filaments/" ^ {move.extruders[state.currentTool].filament} ^ "/unload.g"
@LB
The above code in load.g is wrong.
It should be
Also filaments doesn't return null if there isn't one loaded, it returns an empty string""M98 P{"0:/filaments/" ^ {move.extruders[state.currentTool].filament} ^ "/unload.g"}
The extra curly braces are required to form a proper filename parameter.
Note that RRF doesn't allow you to change filaments from within a print file using M701.
It returns an error, however it does not cancel the print!
You can call the macro using M98, but that's kind of working against the checks RRF has in place, which is that you would manually unload an existing filament before trying to load a new one.
I can see a case for both methods. With enough sensors etc, fully automated loading would be possible.Following more testing I have settled on this (for now )
;; load.g M291 R"Loading ABS" P"Loading config and heating" S1 T3 M302 S210 R120 ; set cold extrude and retract temperatures ;check if no tool selected or if heater is off if state.currentTool=-1 T0 P0 if heat.heaters[state.currentTool].state="off" T0 P0 G10 P{state.currentTool} R0 S0 M291 R"Loading ABS" P"Waiting for nozzle loading temperature..." S1 T0 M98 P"0:/macros/heating/preheat_ABS.g" M116 ; Wait for temperature ;check if ABS is already loaded if move.extruders[state.currentTool].filament="ABS" M291 R"Cancel loading" P"Filament already loaded. Skipping load moves" S1 T5 M99 ; cancel macro but not print ; only run if not in a job (M701 won't allow this, but manually calling this macro is possible) ;if we want to auto load/unload at the start of a print we'd have to remove this if job.file.fileName!=null M291 R"Cancel loading" P"Print job in progress. Skipping load moves" S1 T5 G4 S3 M99 ;cancel macro but not print ;we know ABS isn't loaded, but if something else is, we need to unload it first if move.extruders[state.currentTool].filament!="" if move.extruders[state.currentTool].filament!="ABS" M702 S{"{move.extruders[state.currentTool].filament}"} M291 R"Unload finished" P"Press OK when ready to load new filament" S3 M701 S"ABS" ; this seems to be needed to update DWC if we unload first ; we check filament loaded again in case this is a second loop from an unload/reload above. if move.extruders[state.currentTool].filament!="ABS" M291 R"Loading ABS" P"Feeding and priming..." S1 T0 M98 P"/macros/filament/do_moves_for_load.g" M292 ; Clear messages
I have also added M703 to 0:/sys/config.g to load any settings if a filament is already loaded for the active tool.
-
-
M106 P[current_extruder] S0 ;Start with fan off
-> Is P within M106 not the fan but the extruder?Do you have defined these variables like in "G10 P0 S{heat.coldExtrudeTemperature+10} R{heat.coldRetractTemperature+5}" or if not where can I find a "reference" about all predefined variables like these?
And why do you specify [current_extruder] within M104 as T but not within G10 as P, since in the G-Code-Reference of duet both are the "tool number"?
-
@LB said in load unload macro with endless loop and cancel condition:
M106 P[current_extruder] S0 ;Start with fan off
-> Is P within M106 not the fan but the extruder?
M106
Pnnn Fan number (optional, defaults to 0). (In RRF_3 relates to the fan number created by M950, NOT the fan pin number on the board)In my case the part fan is F0
M950 F0 C"fan0" Q500 ; create fan 0 on pin fan0 and set its frequency M106 P0 C"Part_Fan" S0 B2.0 H-1
However I also use a post processing script in Prusa Slicer to try to ensure that if there were multiple tools, the correct fan is selected (see below)
Do you have defined these variables like in "G10 P0 S{heat.coldExtrudeTemperature+10} R{heat.coldRetractTemperature+5}" or if not where can I find a "reference" about all predefined variables like these?
These are object model meta commands which refer to the values you set in M302.
You woud typically set these in config.g , but it would be more accurate to have them in each filament config.g
I found that the filament config.g isn't loaded until after the load.g is complete so in order to reference these values I had to put the M302 in the preheat macro for each filament.
It would be nice if M703 accepted parameters so you could load the correct values at the start of a filament change.And why do you specify [current_extruder] within M104 as T but not within G10 as P, since in the G-Code-Reference of duet both are the "tool number"?
Probably laziness
At present I only use a single extruder, so it's not really an issue for me.
I try to make everything I do as portable as possible, so that any hardware changes take as little re-writing of individual macros etc as possible.
For accuracy and completeness it should be as you say.I should point out that I also have post processors in Prusa Slicer which adjust the code to suit RRF flavour better.
In the case of G10 temps this will soon be possible within Prusa Slicer.
At present M104 is used and will set both active and standby temps to whatever is in the slicer at every temp change#RRF-fixes.py # Save in Prusa Slicer Scripts folder # Add to Prusa Slicer post processing scripts import sys #open G Code fand store in memory "filedata" f = open(sys.argv[1],"r") filedata = f.read() f.close() # search filedata and put the results into newdata newdata = filedata.replace("M104 S","G10 S") # replace all M104 with G10 # now we keep searching newdata newdata = newdata.replace("M109 S","G10 S") # replace all M104 with G10 newdata = newdata.replace("M204 S","M204 P") # replace all M204 S parameters with Parameter newdata = newdata.replace("M106 S","M106 P{tools[state.currentTool].fans[0]} S") # replace all M106 with code to select tool newdata = newdata.replace("M107","M106 P{tools[state.currentTool].fans[0]} S0") # replace all M107 with M1106 to turn off heater f = open(sys.argv[1],"w") f.write(newdata) # write info back to G Code file f.close()
.
I should also point out that my day job is making sparks and smoke (welding)
I try not to bring that to coding, but "caveat emptor" applies if you use any of my code. -
@OwenD
AAHHH sorry bout the Fan-question with m106 - seems I mixed that up..."It would be nice if M703 accepted parameters so you could load the correct values at the start of a filament change." +1 here!
Where did you pick up the
M104 S0 R0
Why do they have to be "zeroed", couldn´t just the filament-config.g temps get loaded instead?
Doesn´t work yet I guess...?(Not your dayjob - woah, don´t make me fear my image in the mirror ...)
-
@LB said in load unload macro with endless loop and cancel condition:
Where did you pick up the
M104 S0 R0
Why do they have to be "zeroed", couldn´t just the filament-config.g temps get loaded instead?If there is no M104 in your start Gcode, prusa slicer (and others) will add it automatically.
This just tricks the slicer into not doing that, so that all temps are as we intended. -
This post is deleted! -
for some sort of end.g for the print files, I do not even get this to work:
G1 X{"{move.axes[0].min+5}"} Y{"{move.axes[1].max-5}"} F500 ; position for easy part removal
edit: seems to work with:
G1 X{move.axes[0].min+5} Y{move.axes[1].max-5} F500 ; position for easy part removal
yeah! juhuu my first conditional g-code...
O.K. next:
;set temps for all heaters to have time to cool down below 60°C touch-safe temp with an additional -5°C for safety to account for measurement-tolerances, what gives then 55°C ;make conditional: only if S>55 do the following, else skip: ;M104 S55 ; turn extruder-heater off -> DEPRACTED in RRF>=3.x ;if T0 > S55 ;G10 S55 ; turn extruder-heater to a touch-safe temperature ;if P0 > S55 ;M140 S55 ; turn print-heat-plate to a touch-safe temperature
Nobody here to know what the variable for the current heater0 & heater1 is or where I find an overview how these variables are called/named?
-
@LB said in load unload macro with endless loop and cancel condition:
for some sort of end.g for the print files, I do not even get this to work:
G1 X{"{move.axes[0].min+5}"} Y{"{move.axes[1].max-5}"} F500 ; position for easy part removal
edit: seems to work with:
G1 X{move.axes[0].min+5} Y{move.axes[1].max-5} F500 ; position for easy part removal
yeah! juhuu my first conditional g-code...
Yes, by using quotes you turned it into a string instead of a meta command
You need to study this
https://duet3d.dozuki.com/Wiki/GCode_Meta_CommandsO.K. next:
;set temps for all heaters to have time to cool down below 60°C touch-safe temp with an additional -5°C for safety to account for measurement-tolerances, what gives then 55°C ;make conditional: only if S>55 do the following, else skip: ;M104 S55 ; turn extruder-heater off -> DEPRACTED in RRF>=3.x ;if T0 > S55 ;G10 S55 ; turn extruder-heater to a touch-safe temperature ;if P0 > S55 ;M140 S55 ; turn print-heat-plate to a touch-safe temperature
Nobody here to know what the variable for the current heater0 & heater1 is or where I find an overview how these variables are called/named?
In DWC go to the settings section and select "Object Model"
You can drill down to find what you want.
You may have to update RRF & DWC to see it.
You can also use M409 but it can't return the entire model. -
@OwenD said in load unload macro with endless loop and cancel condition:
In DWC go to the settings section and select "Object Model"
You can drill down to find what you want.
You may have to update RRF & DWC to see it.
You can also use M409 but it can't return the entire model.Thanks so much!
Where do I find the "settings" section for DWC -> on the project hosting page? At least I could not find anything in the webbrowser that´s named like this...
-
@LB I'm guessing you're not running the 3.2 beta, so if you're still on 3.1.1 you wouldn't see the object model browser.
-
@OwenD
@Phaedrux
Ah! Thanks -> have so much work with setting up the stuff, will wait for 3.2-alpha I guess...For now this should be enough: https://duet3d.dozuki.com/Wiki/Object_Model_of_RepRapFirmware#Section_Uses
Combining with the
https://duet3d.dozuki.com/Wiki/GCode_Meta_Commands#Section_Object_model_properties
should work...
(Saw that tree-structure in the first place but didn´t know what to do but reading slowly in I think I get the hold somehwere there ) -
Thanks everybody,
because of the code-snippets posted by you I was able to implement it in a way I am happy for now:duet2ethernet1.0.4 with RRF3.1.1
load:
; https://duet3d.dozuki.com/Wiki/Filaments ; load.g if (state.currentTool=-1) M291 P"No tool active" R"Can't proceed" S1 T10 abort; M703 ;load from filament-config.g: G10 S235 ; Set current tool temperature S___ ,for PETG 230-255°C ;G10 S___ ; get from filament-config.g M291 R"...heating up hotend..." P"...for loading filament..." S0 T100 ; Display message P=main-message R=secondary-message T=timer in sec ;https://duet3d.dozuki.com/Wiki/Gcode#Section_M116_Wait ;M116 ; Wait for ALL temperatures to be reached (if no secondary parameters like H, C or S are defined) M116 P0 ; Wait for P0=Tool0 to reach temp ;M116 P_ ; make automatic for tool selected M292 ; Clear messages ; reliable max speed for extrusion seems to be below 10mm/s for PETG, retract can be higher M83 ; Extruder to relative mode ;old style fix: ;G1 E50 F200 ; Feed+/Retract- E__mm of filament at F___mm/min ;G1 E250 F500 ; Feed+/Retract- E__mm of filament at F___mm/min ;M400 ; Wait for moves to complete ;G4 P5 ; Wait/Dwell P___ MILLIsecond(s), S___ second(s) ;G1 E-2 F1000 ; Feed+/Retract- E__mm of filament at F___mm/min ;new style interactive: M400 ; wait for moves to finish while true if iterations = 25 break ;M292 ; Clear messages M291 P"Press OK to feed 50mm of filament (or CANCEL to abort)" R"Extrude?" S3 M291 P"...moving the filament..." R"...wait..." S0 T50 ; make long enough to be displayed longer then it takes to extrude G1 E50 F250 ; Feed+/Retract- E__mm of filament at F___mm/min G1 E-2 ; Feed+/Retract- E__mm of filament at F___mm/min M400 ; wait for moves to finish ;M292 ; Clear messages M400 ; wait for moves to finish M291 R"Done loading" P{move.extruders[state.currentTool].filament ^ " Filament"} S1 ; Display new message ; set all back G10 S0 ; Set current tool temperature S___ ;M292 ; Hide message
unload:
; https://duet3d.dozuki.com/Wiki/Filaments ; unload.g if (state.currentTool=-1) M291 P"No tool active" R"Can't proceed" S1 T10 abort; M703 ;load from filament-config.g: G10 S220 ; Set current tool temperature S___ ,for PETG 230-255°C ;G10 S___ ; get from filament-config.g M291 R"...heating up hotend..." P"...to unload filament..." S0 T100 ; Display message P=main-message R=secondary-message T=timer in sec ;https://duet3d.dozuki.com/Wiki/Gcode#Section_M116_Wait ;M116 ; Wait for ALL temperatures to be reached (if no secondary parameters like H, C or S are defined) M116 P0 ; Wait for P0=Tool0 to reach temp ;M116 P_ ; make automatic for tool selected M292 ; Clear messages ; reliable max speed for extrusion seems to be below 10mm/s for PETG, retract can be higher M83 ; Extruder to relative mode ;old style fix: ;G1 E50 F200 ; Feed+/Retract- E__mm of filament at F___mm/min ;G1 E250 F500 ; Feed+/Retract- E__mm of filament at F___mm/min ;M400 ; Wait for moves to complete ;G4 P5 ; Wait/Dwell P___ MILLIsecond(s), S___ second(s) ;G1 E-2 F1000 ; Feed+/Retract- E__mm of filament at F___mm/min ;new style interactive: M400 ; wait for moves to finish while true if iterations = 25 break ;M292 ; Clear messages M291 P"Press OK to un-feed 50mm of filament (or CANCEL to abort)" R"Un-load?" S3 M291 P"...moving the filament..." R"...wait..." S0 T50 ; make long enough to be displayed longer then it takes to extrude G1 E-47 F500 ; Feed+/Retract- E__mm of filament at F___mm/min G1 E-3 F300 ; Feed+/Retract- E__mm of filament at F___mm/min M400 ; wait for moves to finish ;M292 ; Clear messages M400 ; wait for moves to finish M291 R"Done unloading" P{move.extruders[state.currentTool].filament ^ " Filament"} S1 ; Display new message ; set all back G10 S0 ; Set current tool temperature S___ ;M292 ; Hide message
Thanks!
Please close as "solved"
-
@LB Do you ever have the message done loading/unloading ? I tried your solution but as soon as i cancel the purge, it kills the macro and don't finish it.
-
@Krohm-Koala said in load unload macro with endless loop and cancel condition:
@LB Do you ever have the message done loading/unloading ? I tried your solution but as soon as i cancel the purge, it kills the macro and won't finish it.
likewise in the above case, abort would kill the macro (and print)At present if you hit cancel in an M291 S3 dialog it will cancel the macro, so no, you would never get the finished message in that instance.
There was discussion about adding a third option to M291, but it doesn't seem to be on the current list for implementation.
Perhaps some some time after 3.2 is finalized. -
@OwenD said in load unload macro with endless loop and cancel condition:
@Krohm-Koala said in load unload macro with endless loop and cancel condition:
@LB Do you ever have the message done loading/unloading ? I tried your solution but as soon as i cancel the purge, it kills the macro and won't finish it.
likewise in the above case, abort would kill the macro (and print)At present if you hit cancel in an M291 S3 dialog it will cancel the macro, so no, you would never get the finished message in that instance.
There was discussion about adding a third option to M291, but it doesn't seem to be on the current list for implementation.
Perhaps some some time after 3.2 is finalized.@OwenD
Thanks for pointing this out! That is what I assumed! Conditional G-code is pretty new, so not everything can be there from the start. But over time I guess there will be an option so I just let the code there to change it whenever the solution arrives...
@Krohm-Koala
To be honest I feel settled with the no "final" message since anyway in DWC it shows you that it has loaded everything -> since I currently only work with printers with only 1 extruder (and no colourchanger or stuff like that) the filamentchange-code posted is good enough for me now... hope you understand -
@LB Totally understand it's just me who want too much