Running gcode after a print, but not part of a print (async)
-
Hi,
A bit of a niche request, but is it possible to run a gcode after a print but not as part of a print?
I added air filters to my printer, and want to run them for 20 minutes following a print, but also don't want to block myself from starting a new print and/or running other gcode in the console.
Currently using stop / dwell will extend the print time for those 20 minutes, I'd like to do this async.
No big deal if there's no way to do this, I can fallback to implementing it on the raspberry pi.
-
Using M0 in your slicer end gcode will call the a stop.g file in the sys folder. In that macro you could turn on the fan you want and set a variable.
Then using daemon.g you could have a loop that checks for that variable and when set waits your time amount and then turns off the fan again.
You can find an overview of what's possible here: https://docs.duet3d.com/en/User_manual/Reference/Gcode_meta_commands
-
Interesting! Thanks!
-
Works perfectly, thanks again! For reference:
enable_filters_for_time.g
echo "enable filters for time" if !exists(global.disable_filter_at) global disable_filter_at = 0 ; if !exists(global.is_filter_enabled) global is_filter_enabled = false ; set global.disable_filter_at = {state.upTime + 10} set global.is_filter_enabled = true ; Turn on filter fans M98 P"filters/enable.g"
auto_disable.g
if exists(global.disable_filter_at) && exists(global.is_filter_enabled) && global.is_filter_enabled if state.upTime >= global.disable_filter_at set global.is_filter_enabled = false M98 P"filters/disable.g" ;
daemon.g
M98 P"filters/auto_disable.g"
-
Well done!
-
Since I have been using TPE, I have begun thinking about a HEPA + Carbon filter myself due to the smell, but in truth I should have one anyway as I use mainly ABS.
I'm yet to reconcile the need for fume extraction with the need for a heated chamber.
I suppose the exhaust from the filter will have to go back into the chamber to maintain temperature.
Is this what you have done?Anyway, my code takes the view that the view that the filter should be on whenever any of the extruders are either not turned off or are at a temperature greater than the cold extraction temperature.
This is to cover cases when the extruder is on standby, on, or tuning.I have also complicated it more than many would need in order to cover tools with multiple heaters, such as a mixing hotend.
To do that I needed a loop inside a loop, so I needed an extra global to track one of the loop counts.I'm yet to fully implement this, but I've tested it as a stand alone macro to debug.
It hasn't been tested with something like a mixing hotend, but should cover that.This is the section creating the global variables which would go in config.g
; ****************** EXTRACTION FAN CONFIGURATION SECTION ********************** ;This section goes in config.g ; ; configure your extraction fan output. ; we assume here a gpio is used with an SSR to control a mains powered extraction/filter ; You could configure and use a fan output and change the code in daemon.g to use M106 instead of M42 ; see https://duet3d.dozuki.com/Wiki/M950 M950 P5 C"exp.e5_stop" ; Output 5 uses E5_STOP pin M42 P5 S1 ; Start with the output turned on so extraction happens immediately on a restart ; create or reset a global variable that sets how long the fan runs after heating if !exists(global.ExtractionTime) global ExtractionTime = 20 * 60 ; Time in seconds for fan to run after heating finished else set global.ExtractionTime = 20 * 60 ; ; create or reset global variable to store the time we want the fan to shut down if !exists(global.FanShutDownTime) global FanShutDownTime = state.time ; this will be reset in daemon.g if needed else set global.FanShutDownTime = state.time ;create or reset a global variable the records whether a heater is active or at melt temperature if !exists(global.NeedFan) global NeedFan = false else set global.NeedFan = false ; ****************** END OF EXTRACTION FAN CONFIGURATION SECTION **********************
Then in daemon.g we need this.
Note, by default daemon.g runs every 10 seconds, but that's suitable for this usage case.; create a variable so we can loop through multiple tools with multiple heaters if !exists(global.ToolsChecked) global ToolsChecked = 0 else set global.ToolsChecked = 0 ; Check to see if the globals have been created yet in case daemon.g started before config.g finished ; If the last global created exists we run the code if exists(global.NeedFan) set global.NeedFan = false ; first we set the fan requirement to false ;echo "start first loop" while global.ToolsChecked < #tools ; create a loop to check all extruder heaters. If the heater isn't off or it is over melt temp then we need the fan to run another X minutes ;echo " Tool loop " ^ global.ToolsChecked while iterations < #tools[global.ToolsChecked].heaters ;echo "heater loop " ^ iterations if (heat.heaters[tools[global.ToolsChecked].heaters[iterations]].state != "off") || ((heat.heaters[tools[global.ToolsChecked].heaters[iterations]].current) >= (heat.coldRetractTemperature)) ;echo "heater " ^ iterations ^ " matches pattern" set global.FanShutDownTime = statetime + global.ExtractionTime ; extend the shutdown time set global.NeedFan = true ; set the fan variable M42 P5 S1 ; Turn on the fan output. Use M106 instead if using fan output. set global.ToolsChecked = #tools ; this will break the first loop break ; no need to keep checking in the second loop as we've found a heater that needs extraction ;echo "increment ToolsChecked" set global.ToolsChecked = (global.ToolsChecked + 1) ; increment the counter for the tools we've checked ; Now we can check if the fan needs to be turned off ;echo "time : " ^ state.time ^ " shut down due " ^ global.FanShutDownTime if state.time >= global.FanShutDownTime M42 P5 S0 ; turn off the fan because it's more than the required time since it was last needed. ;echo "fan turned off" ;else ;echo "fan left on" ; ****************** END EXTRACTION FAN REQUIREMENT CHECK **********************