Jump to content

Heat Soak Macro's


mvdveer

Recommended Posts

Seeing this came up in a previous discussion/thread, I thought I would share what I found and have been using to heat soak the chamber on my Voron 2.4r2 300mm build. 

Must say, still have not achieved putting a heat soak parameter in the Start_print macro with success, but I will keep trying. I have a summary of the thread that I attached as a .txt file for this interested.

This is from the Klipper Discord group:

https://klipper.discourse.group/t/interruptible-heat-soak/1552

I include garethky's repository and Klipper configuration as acknowledgement of his work and is at:

https://github.com/garethky/klipper-voron2.4-config

Statement: I do not know the author or have any affiliation with the author.

Hope this may be of use to someone.

Interuptible Heat soak.txt

Link to comment
Share on other sites

46 minutes ago, rkolbi said:

Thanks for that - can this be called from the Print_Start macro? The one thing I have not ventured into is macro creation. My next learning objective - UNDERSTANDING macros. Currently as a language, I think Latin is easier than Klipper macros 🙂

PS: Your macros to me is extensive but must be honest, as a noob - do not understand them. (Had a look at your repository - impressive work

Edited by mvdveer
Added comment to clarify
Link to comment
Share on other sites

7 hours ago, mvdveer said:

can this be called from the Print_Start macro?

I have been working with this same issue.

[gcode_macro HEAT_SPREAD]
gcode:
  STATUS_STANDBY                  ; turn on LEDs
  G28                             ; home all axes
  G0 Z5 F4000                     ; move Z to 5mm above buildplate
  G0 X60 Y60 F6000                ; move toolhead to center of build plate
  M140 S100                       ; set bed temp to 100C
  M106 S204                       ; turn on part cooling fans at 80%

Calling it as standalone it works great but when called (or ran as commands) within the PRINT_START it will read ahead to the set_bed_temp part and treat it as M190 (wait for bed temp). I have no idea where to change this behavior.

Link to comment
Share on other sites

What exactly do you want in the print start? I just turn the bed on and the nozzle to 170deg, then say it should wait till the chamber thermistor reaches the temp that comes from the slicer, then heating the nozzle to the final temp and everything else.

Link to comment
Share on other sites

1 hour ago, fl0w said:

What exactly do you want in the print start?

I use the part cooling fans above the center of the bed as it heats to speed up the chamber heating. This means that I would like the PRINT_START to allow the homing, moving the toolhead to the center of the build plate and turning on the fans BEFORE turning on the bed heater and waiting for it to reach temperature but this is not the default behavior when calling print_start.

When I print ASA then I get better results leaving the chamber open so I am less concerned with the chamber temperature sensor. I use that for my reference. If I wanted to add a specific heat soak time I could add something like G4 P60000 to add a one minute wait.

Link to comment
Share on other sites

 

So this is my Heat_Soak Macro, I found it somewhere but sadly did not write down who created it in the first place so cannot give credits to them. I modified it by adding the Stealthburner LED Macros and firing up the Nevermore Filter. The Maybe_Home function is from RatOS so maybe you have to go back to Home or G28 there, or you check out RatOS in its DEV Branch on Github as the Voron 2.4 and 0.1 is included now

[gcode_macro CENTER]
description: move Toolhead to centered Position
gcode:
    G0 X150 Y150 Z50 F3500

[gcode_macro HEAT_SOAK]
description: heats the bed for a while

variable_target_temp: 0
variable_stage: None ## heating -> soaking -> done -> None

## in seconds
variable_check_interval: 10
variable_soak_time_remaining: 0
variable_total_time_elapsed: 0

gcode:
    {% set TARGET = params.TARGET | default(0) | float %}
    {% set DURATION = (params.DURATION | default(15) | int) * 60 %} ## minutes to seconds

    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=target_temp         VALUE={ TARGET }
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=stage               VALUE="'heating'"
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=soak_time_remaining VALUE={ DURATION }
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=total_time_elapsed  VALUE=0
    ;; fire up the heateR
    SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={ TARGET }
    ;; run the fan to circulate air
    SET_FAN_SPEED FAN=Nevermore SPEED=0.65
    ;; put the bed and nozzle where they're a safe distance apart
    STATUS_HOMING
    MAYBE_HOME
    CENTER
    M84 ;; turn off steppers
    STATUS_BUSY
    UPDATE_DELAYED_GCODE ID=heat_soaker DURATION={ check_interval }
    ;; pause the print during heat soak
    PAUSE_BASE

[gcode_macro CANCEL_HEAT_SOAK]
description: cancels an in-progress HEAT_SOAK cycle
gcode:
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=stage VALUE="'cancel'"
    UPDATE_DELAYED_GCODE ID=heat_soaker DURATION=1
    SET_FAN_SPEED FAN=Nevermore SPEED=0

[delayed_gcode heat_soaker]
; ## debug
; { action_respond_info( printer['gcode_macro HEAT_SOAK'] | tojson )}
gcode:
    {% set heat_soak = printer['gcode_macro HEAT_SOAK'] %}
    ## update total time elapsed
    {% set total_time_elapsed = heat_soak.total_time_elapsed + heat_soak.check_interval %}
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=total_time_elapsed VALUE={ total_time_elapsed }
    {% set stage = heat_soak.stage %}
    {% if stage == "heating" and printer.heater_bed.temperature >= heat_soak.target_temp %}
        {% set stage = "soaking" %}
    {% endif %}
    {% if stage == "soaking" %}
        ## update soak countdown
        {% set soak_time_remaining = [heat_soak.soak_time_remaining - heat_soak.check_interval, 0] | max %}
        SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=soak_time_remaining VALUE={ soak_time_remaining }
        {% if soak_time_remaining == 0 %}
            {% set stage = "done" %}
        {% endif %}
    {% endif %}
    SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=stage VALUE="'{ stage }'"
    {% if stage in ("done", "cancel") %}
        {% if stage == "cancel" %}
            {% set stage = "done" %}
            TURN_OFF_HEATERS
            M107 ; turn off fan
            M117 { "soak cancelled after ~%.1fm" | format(total_time_elapsed / 60.0) }
            ;; heat soak was cancelled -- also cancel the print
            CANCEL_PRINT
        {% else %}
            M117 { "soak complete after %.1fm" | format(total_time_elapsed / 60.0) }
            ;; heat soak is complete. Call the complete macro prior to starting the print
            SOAK_COMPLETE
            ;; resume / start the print
            RESUME_BASE
            STATUS_READY
        {% endif %}
        ## reset all state vars, except stage, which may be queried via the api
        SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=target_temp         VALUE=0
        SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=soak_time_remaining VALUE=0
        SET_GCODE_VARIABLE MACRO=HEAT_SOAK VARIABLE=total_time_elapsed  VALUE=0
    {% else %}
       {% if total_time_elapsed % 90 == 0 %}
            ## output status periodically
            {% if stage == "heating" %}
                M117 { "heating -- %.1fm elapsed" | format(total_time_elapsed / 60.0) }
            {% elif stage == "soaking" %}
                M117 { "soaking -- %.1fm remaining" | format(soak_time_remaining / 60.0) }
            {% endif %}
        {% endif %}
        ## trigger ourselves again
        UPDATE_DELAYED_GCODE ID=heat_soaker DURATION={ heat_soak.check_interval }
        ## dwell for 1ms to prevent from going idle
        G4 P1
    {% endif %}

 

Link to comment
Share on other sites

2 hours ago, atrushing said:

not the default behavior when calling print_start

At least I found the source of my problem and it wasn't Klipper. When Prusa Slicer exports the gcode it adds the following two lines before it applies my print_start gcode:

M190 S100 ; set bed temperature and wait for it to be reached
M104 S255 ; set temperature

Then it calls the PRINT_START.

If I remove the M190 line then my print_start works as expected. Now I just have to solve the Prusa Slicer issue or add a post processing script to remove that line automatically. Maybe I should just upgrade to Super Slicer!

Link to comment
Share on other sites

1 hour ago, atrushing said:

At least I found the source of my problem and it wasn't Klipper. When Prusa Slicer exports the gcode it adds the following two lines before it applies my print_start gcode:

M190 S100 ; set bed temperature and wait for it to be reached
M104 S255 ; set temperature

Then it calls the PRINT_START.

If I remove the M190 line then my print_start works as expected. Now I just have to solve the Prusa Slicer issue or add a post processing script to remove that line automatically. Maybe I should just upgrade to Super Slicer!

In your start gcode in Superslicer/Prusaslicer, add this above your PRINT_START call:

M104 S0 ; Stops PS/SS from sending temp waits separately
M140 S0
PRINT_START <rest of your parameters>

 

  • Thanks 1
Link to comment
Share on other sites

14 hours ago, mvdveer said:

can this be called from the Print_Start macro

 

Print_Start gets divided into two parts.

Non-blocking waiting:
https://github.com/rkolbi/voron2.4/blob/main/MY_V24-350 ADAPTIVE_MESH/ACTIVE/MACRO-WAITING_ROUTINES.cfg
Lines 54 through 117

Print_Start:
https://github.com/rkolbi/voron2.4/blob/main/MY_V24-350 ADAPTIVE_MESH/ACTIVE/MACRO-PRINT_HANDLING.cfg
Lines 44 through 123

PRINT_START:
Lines 64 and 65 save the EXTRUDER_READY and EXTRUDER_TEMP information passed from the start_gcode to the non-blocking waiting routine. Line 70 gets the duration of the soak from the passed start_gcode as SOAK.
Rest of PRINT_START homes and QGL the printer (if desired). Line 97 calls the non-blocking soak routine, passing the SOAK time.  

_PRINT_START2:
Picks up from where PRINT_START left off before the soak, using EXTRUDER_READY and EXTRUDER_TEMP information (lines 104 and 105) that was stored previously.

 

  • Thanks 1
Link to comment
Share on other sites

I simplified mine a bit. 

Relevant snippet from print_start

{% if printer["temperature_fan chamber"].temperature < chambertemp %}
  _HEATSOAK TEMP={bedtemp} MOVE=1                                           # Set up to heat soak if chamber temp is set higher than current reading
  M190 S{bedtemp}                                                           # Set target bed temp & wait for it
  TEMPERATURE_WAIT SENSOR="temperature_fan chamber" MINIMUM={chambertemp}   # Do the actual heat soak wait, until chamber temp is at target
{% else %}
  {% if printer.heater_bed.temperature < (bedtemp-2) %}
    _HEATSOAK TEMP={bedtemp} MOVE=1	        						       # Bed is below target temp, get it heating & safely park toolhead
    M190 S{bedtemp}                                                        # Set bed target temp & wait for it
  {% else %}
    _HEATSOAK TEMP={bedtemp} MOVE=0                                        # Just do a bed heat, no champer temp (open case for PLA)
  {% endif %}
{% endif %}
M106 S0                                                                    # Turn off part cooling fan from heatsoak

Heat soak macro it calls

[gcode_macro _HEATSOAK]
description: Helper: Set up to heat soak printer. Usage: _HEATSOAK [TEMP=temp(110)] [MOVE=move(1)]
gcode:
  {% set temp = params.TEMP|default(110)|int %}
  {% set move = params.MOVE|default(1)|int %}
	
	LED_HEATING
	_PRINT_AR T="Warming up"
	M141 S0                                                 # Turn off exhaust fan
	M140 S{temp}                                            # Heat the bed
	{% if temp >= 100 %}                                    # It's ABS or other high-temp plastic, closed case
		M104 S170                                             # Set hotend to no-ooze temp
		M106 S205                                             # Turn on part fan to 80% for 
		SET_FAN_SPEED FAN=nevermore SPEED=1                   # Turn on Nevermore fans to circulate & accelerate chamber soak
	{% else %}
		M106 S0                                               # Turn off part fan. Open case, no need
		SET_FAN_SPEED FAN=nevermore SPEED=0                   # Make sure Nevermore is off
	{% endif %}
	
	{% if move == 1 %}
		_CG28                                                 # Conditional home
		PARK P=bed                                            # Park toolhead in safe location (center volume)
		LED_HEATING
	{% endif %}

I have SuperSlicer set to pass a target chamber temp for each filament which is passed to print_start. SuperSlicer of course has the M104 & M140 lines @geekandi mentioned. 

So, essentially I send a target chamber temp as my heatsoak parameter. For example PLA sends 0, ABS sends 30. PLA prints skip right to getting things going, ABS waits for the chamber to hit about 30C. It's not interruptible, but that's rare--like I realized I missed something and need to cancel the print. Then I just e-stop the printer and restart it.

I cribbed from the zellneralex Github and modified heavily from there.

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...