Closed TTom1088 closed 7 months ago
Ah, that is true. Good catch. It's all because of the way that klipper uses jinja templates -- the context is evaluated before execution and thus printer variables will not change within a macro. A classic trick is to have one macro call another so the execution context is renewed. This would probably work, but I'll have to think about if there is anything I can do better. Yes I can set earlier, but the pause occurs before I know if it is a runout or not. There may be a way, I'll look into it.
Ok. I pushed a branch that you can validate. It is a small change but I want to be careful with this. To switch to this branch:
cd ~Happy-Hare
./install.sh -b issue219
Let me know it that works. I think it will. Once I hear back from you I'll merge into main..
BTW to get back to main branch you redo the above with -b main
First of all, thank you for the quick processing. I've now been able to do some tests and it works with a detour.
Runout is detected (tested via MMU_TEST_RUNOUT). But now no “pause” is activated. Therefore I had to go to the purge box using the __MMU_PRE_UNLOAD macro to switch. And use the _MMU_POST_LOAD to clean the nozzle and return to pressure level. Here is the modified macro
[gcode_macro _MMU_PRE_UNLOAD_RUNOUT] description: Optional pre unload routine for filament change with runout gcode: {% set vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %} {% set park_after_form_tip = vars.park_after_form_tip|default(false)|lower == 'true' %} SAVE_GCODE_STATE NAME=MMU_PRE_UNLOAD_state _MMU_AUTO_HOME _MMU_SAVE_POSITION {% if not park_after_form_tip %} _MMU_PARK {%endif% {vars.user_pre_unload_extension|default("")} RESTORE_GCODE_STATE NAME=MMU_PRE_UNLOAD_state _RUNOUT_ABFRAGE_POSITIONIERUNG
in the macro _RUNOUT_ABFRAGE_POSITIONIERUNG is then the query
{% set runout = printer['mmu'].runout %} {% if runout == True %}
and the same with the [gcode_macro _MMU_POST_LOAD_RUNOUT] macro I then used these in the parameters.cfg.
I'll test everything again in a real test one day by cutting the filament and see if everything fits.
Of course, if you have an idea to make the whole thing more user-friendly, I would be open to any idea. One idea would be to enter a runout macro directly in parameters.cfg. But that's how it works :-)
Thank you
Theoretically I could also insert the macros via the mmu_macro_vars
variable_user_pre_unload_extension : '' ; Executed after default logic
insert so: variable_user_pre_unload_extension : '_RUNOUT_QUERY_POSITIONING' ; Executed after default logic
The same then with variable_user_post_load_extension This is of course much more convenient :-)
My changes to the "issue219" branch were kind of quick. Basically I avoid sending the PAUSE until the last minute -- in theory if the runout is handled by endlessSpool, then there is not need to pause at all (it is just an inserted "toolchange"). I can't remember why are always pause but I don't think it is necessary.... [can you think of errors in this logic?]
By waiting to the last minute to pause I'm able to know better if it is a runout or a clog. The problem is that if the runout comes from a sensor that is NOT the encoder I know it is a runout (may need to pause but only if endless spool can't help). This the "runout" is from the encoder then I need a further test (wiggling the filament and looking for encoder movement) to know if its a runout or clog.
Anyway, is the way it is working in the branch and using the "pre_unload_extension" hook (which is the right way to do it and will survive upgrades and so be much less pain for you), is this working ok?
Hello, it's me again. The big practical test came today and I found a small hurdle. First I added my runout variable only in the mm_macro_vars. variable_user_pre_unload_extension :
variable_user_pre_unload_extension : '_RUNOUT_ABFRAGE_POSITIONIERUNG' variable_user_post_load_extension : '_RUNOUT_ABFRAGE_NOZZLE_REINIGEN'
this has worked so far. But the printer stopped printing after the change. https://youtube.com/shorts/aJ2YIaSp0Gk
first a change of the _MMU_PRE_UNLOAD and _MMU_POST_LOAD_RUNOUT Macros led to success because the entire MMU logic was switched off during runout
#########################################################################
[gcode_macro _MMU_PRE_UNLOAD_RUNOUT] description: Optional pre unload routine for filament change mit Runout gcode: {% set vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %} {% set park_after_form_tip = vars.park_after_form_tip|default(false)|lower == 'true' %} {% set runout = printer['mmu'].runout %}
{% if runout != True %}
SAVE_GCODE_STATE NAME=MMU_PRE_UNLOAD_state
_MMU_AUTO_HOME
_MMU_SAVE_POSITION
{% if not park_after_form_tip %}
_MMU_PARK
{% endif %}
#{vars.user_pre_unload_extension|default("")}
RESTORE_GCODE_STATE NAME=MMU_PRE_UNLOAD_state
{% endif %}
_RUNOUT_ABFRAGE_POSITIONIERUNG
####################################################################
[gcode_macro _MMU_POST_LOAD_RUNOUT] description: Optional post load routine for filament change mir Runout gcode: {% set vars = printer['gcode_macro _MMU_SEQUENCE_VARS'] %} {% set timelapse = vars.timelapse|default(false)|lower == 'true' %} {% set mmu_paused = printer.mmu.is_locked %} {% set runout = printer['mmu'].runout %}
{% if runout != True %}
SAVE_GCODE_STATE NAME=MMU_POST_LOAD_state
{% if timelapse %}
TIMELAPSE_TAKE_FRAME
{% endif %}
# A good place to implement custom purging logic and/or nozzle cleaning
# prior to returning to print/wipetower
#{vars.user_post_load_extension|default("")}
{% if not mmu_paused %}
_MMU_RESTORE_POSITION
{% endif %}
RESTORE_GCODE_STATE NAME=MMU_POST_LOAD_state
{% endif %}
_RUNOUT_ABFRAGE_NOZZLE_REINIGEN
############################################################### That's how it worked
I have now found another error. When the printer is on pause. e.g. because of a node in the buffer and you then remove the filament while it is paused, the runout process will still be started. Would it be possible to disable runout detection during _mmu_pause?
runout should be disabled. Can you share the mmu.log
...
Sorry. I reinstalled Klipper for this printer because there were mcu problems after a Klipper update. But the error only occurred at one point: For example, if T1 was loaded and a knot had formed in the buffer, it could not unload properly. Happy hare activated the pause macro. But T1 was "officially" still loaded. When I then removed the filament to untangle it, it activated the runout routine. This could of course also be due to the other sequence macro. This state is also difficult to simulate.
Once the fix for the runout variable has been made in the main branch, I will continue to work on it. For now, it has to run safely 😅. I have to finish printing my orders first.
mmu.log I found the MMU log on the old SD card. The runout event during the should be documented here at the end
https://drive.google.com/file/d/18GNN8Jb3gD8677Ru4ifZZiyWpYAvlbfN/view?usp=sharing
Since the last update the runout routine has been working perfectly. You definitely have to use the runout macro BASE_PAUSE and BASE_RESUME Install it so that the printer continues printing after changing the roll. Here are my runout macros as an example
############################################################
[gcode_macro _RUNOUT_ABFRAGE_POSITIONIERUNG] description: Runout wird abgefragt und es wird zur Purgebox gefahren. variable_fan_drehzahl: 0
gcode: {% set runout = printer['mmu'].runout %}
{% if runout == True %}
SET_GCODE_VARIABLE MACRO=_RUNOUT_ABFRAGE_NOZZLE_REINIGEN VARIABLE=runout VALUE=1
M118 Runout erkannt Druckkopf faehrt zur Purgebox
RESPOND PREFIX=tgalarm MSG="Endlessspool wechselt die Rolle"
SET_GCODE_VARIABLE MACRO=_RUNOUT_ABFRAGE_POSITIONIERUNG VARIABLE=fan_drehzahl VALUE={printer['fan'].speed}
M106 S0
M117 Rollenwechsel
G1 F96000
G90
SAVE_GCODE_STATE NAME=Rollenwechsel
G10
G91
G1 E-1 F2100
G1 Z1
G90
G1 X31 Y350 F96000
G92 E0
SAVE_GCODE_STATE NAME=Rollenwechsel_OBEN
G1 Z4.5
{% endif %}
###################################################
[gcode_macro _RUNOUT_ABFRAGE_NOZZLE_REINIGEN] description: nach Runout wird Nozzle gereinigt variable_runout:0 #wird nur in _RUNOUT_ABFRAGE_POSITIONIERUNG freigegeben variable_fluss_ausgleich:2 #0.5 SET_GCODE_VARIABLE MACRO=_RUNOUT_ABFRAGE_NOZZLE_REINIGEN VARIABLE=fluss_ausgleich VALUE=2
gcode:
{% if runout == 1 %}
G90
G1 F96000
G92 E0
G91
G1 F200 E15
G1 F2000 E-3
G92 E0
G10
G90
NOZZLE_WISCHEN
G1 X31 Y350 F96000
RESTORE_GCODE_STATE NAME=Rollenwechsel_OBEN MOVE=1 SPEED=200
M106 S{printer["gcode_macro _RUNOUT_ABFRAGE_POSITIONIERUNG"].fan_drehzahl*255}
G91
G1 F2000 E{3-fluss_ausgleich} #soll blobs verhindern
G90
G11
Licht_dunkel
LED_Drucken
RESTORE_GCODE_STATE NAME=Rollenwechsel MOVE=1 MOVE_SPEED=300
SET_GCODE_VARIABLE MACRO=_RUNOUT_ABFRAGE_NOZZLE_REINIGEN VARIABLE=runout VALUE=0
RESPOND PREFIX=tgalarm MSG="Rollenwechsel Erfolgreich"
M118 Rollenwechsel ist fertig
G11
BASE_PAUSE
BASE_RESUME
{% endif %}
###################################
These macros are then inserted into the mmu_macro_vars
variable_user_pre_unload_extension : '_RUNOUT_ABFRAGE_POSITIONIERUNG'
variable_user_post_load_extension : '_RUNOUT_ABFRAGE_NOZZLE_REINIGEN'
In the event of a "normal fault" the printer switches to my own PAUSE macro as normal. In case of runout, the variable "printer['mmu'].runout" should be set to "True". This means I can then activate a different procedure during runout in the pause macro.
If Runout is now activated, the printer goes directly to pause and the query: {% set runout = printer['mmu'].runout %} {% if runout == True %} is ignored. The variable is probably still set to “False”. I can only use my own macro because the print head also changes its Z height during runout. This requires a separate macro to avoid collisions.
Thank you in advance Thomas T.