Filament change with Klipper in Octoprint

I am trying to work out how to implement a filament change.
After watching Youtube tutorials and searching various forums I see I need to implement an M600 macro, so I have added this to my printer.cfg file:

[gcode_macro M600]
gcode:
    {% set X = params.X|default(175)|float %}
    {% set Y = params.Y|default(0)|float %}
    {% set Z = params.Z|default(10)|float %}
    SAVE_GCODE_STATE NAME=M600_state
    PAUSE
    G91
    G1 E-.8 F2700
    G1 Z{Z}
    G90
    G1 X{X} F3000
    G1 Y{Y} F3000
    G91
    G1 E-50 F1000
    RESTORE_GCODE_STATE NAME=M600_state

But there are a number of things I donā€™t understand here.

I appreciate the SAVE_GCODE_STATE command is recording the current state of the print but I donā€™t understand why ā€œPAUSEā€ is being called directly after.

It then looks like we are retracting 0.8mm of filament, raising the nozzle 10mm and moving to the front centre of the bed (my print volume is 350x350x400), then retracting a further 50mm of filament. My thought would be that this would then be the time to pause rather than before.

It then reloads the state saved before and presumably goes back to printing. My thought would be that ā€œMOVE=1ā€ should be on that restore command but perhaps that isnā€™t necisary and the next command in the GCODE will just bring it back (hopefully not extruding filament along the way).

The issues I have are:

  • Why does the PAUSE happen right after the SAVE rather than when the printhead reaches itā€™s resting location
  • What state the Extruder stepper is in at the end of the sequence
  • How to set the print going after the filament has been change.

I have tried running this code with less than satisfactory results.

  • I was unsure of how exactly I should resume the print after changing the filament and just clicked the ā€œresumeā€ button on the Octoprint interface. It kind of seemed to work but Iā€™m not sure if this is the correct way to do it.
  • While the print head moved to the correct X/Y coordinates it still remained well above the print itself.
  • Although I was sure to run a good amount of the new filament threw the nozzle during the change none of this new filament ever came out of the nozzle once printing was resumed.

I suspect the reason none of the new filament ever came out may have been because I pressed the Extrude filament button (with the amount set to 100mm) several times to purge the nozzle of the old filament. Is it possible the stepper has been advanced several hundred mm beyond where the print job thought it was so basically just backed the new filament all the way out when resuming?

I may have manually raised the nozzle (or rather lowered the bed) during the filament change. If I did would this explain the nozzle not returning to the print, and if so how do I get the nozzle to go back to itā€™s proper starting location?

Hello @Slartibartfast !

It would be way more easy for us if you would have attached the requested klippy.log

You find the reason in the PAUSE macro.

Obviously the PAUSE macro moves the printhead away from the print to do the stuff. (Canā€™t tell, because the klippy.log is missing)

What command is that?

Hmm, Iā€™m not sure what happened there but it seems my post got truncated. Fortunately I had it backed up so have just repasted it in fullā€¦

I can add the klippy.log if you wish but I donā€™t think it will help. Iā€™m trying to work out what GCODE I should add rather than diagnose an error as such.

So I have read through the pause macro and I donā€™t quite understand it. It seems to save state as well before calling BASE_PAUSE then appears to park the printhead as well. In both cases I would expect the pause to be called after parking the print head rather than before and that is what I am asking about. Iā€™m sure there is a valid reason, I just donā€™t know that it is: ĀÆ_(惄)_/ĀÆ

I can include the ā€œ[gcode_macro PAUSE]ā€ code as well if you would find it useful. I didnā€™t included it originally as I didnā€™t want to flood the post too much.

My thought was that it was required to actually move the print head to the saved location as apposed to just re-load the values but I could well be mistaken.

With the klippy.log we can explain what is happening with the code inside.

For further information on gcodes:

https://reprap.org/wiki/G-code

Yeah, I get that.

The reason it doesnā€™t seem relevant is because Iā€™m not really ready to run the method yet and it seems pointless to provide a klippy.log that hasnā€™t even run the code. As I say, there are a number of lines in that code block I got from a Youtube tutorial that I donā€™t understand and thatā€™s what I am asking about here.

I just recently (about two weeks ago) went through this whole thing myself. I am still learning, or more accurately teaching myself, so keep in mind some of the things I did might not be optimal.

Your PAUSE macro is moving the head out of the way (aka parks it) before doing anything else. In my case, it raises Z either +5 or to maximum, then moves X and Y to maximum. However, it does not actually interrupt the M600 macro. Apparently once a macro has begun, it has to actually complete it, a macro cannot be paused mid-execution. It is pausing the print, not the macro.

You want the pause at the beginning (more or less) so it pauses the print while it does everything else. In this case, after pausing the print and moving to the park position, it retracts slightly to reduce oozing, moves to a location where itā€™ll be easy to manipulate the filament, then ejects the filament. If you have a direct drive, this will probably move the filament all the way out of the extruder (it does on mine).

A move (G0) at this point is unnecessary. When it resumes, the next command in the gcode will tell it where to move to. You could add a move (G0) if you want, in order to rapid-travel back to the starting location, but that gets really complicated with having to store the current location into variables before doing anything else in the macro, then calling the variables to get back into position, all to save a few seconds of it traveling at printing speeds?

Well, I already answered the first one. The PAUSE is pausing the print before making any changes. As for the second one, thatā€™s part of what the SAVE_GCODE_STATE thing does, it returns everything to the way it was at that moment, including the state of the extruder. However, youā€™re still going to have to get the filament into position. Presumably the next step is going to be a purge block (you DID set your slicer to have a purge block, right?), so youā€™re going to have to push the filament at least far enough in to begin to ā€œoozeā€ a little.

Correct. Once youā€™re ready to move on to the purge step, you just press the resume button.

I canā€™t really help with the rest of the stuff, except to repeat that macros cannot be paused in the middle. It will reload the state before you can add the new filament, so you cannot make any manual changes. Klipper, and by extension Octoprint, will not know you have made any changes, and will therefore continue as if you did not when you hit the resume button. You need to make sure the ā€œsetā€ commands at the beginning of the M600 macro set the X and Y to the actual location you want them to be for swapping the filament (no manual X/Y movements), and the Z to the actual height you want it to lift off the print before moving into position for the filament change. Then when you load the new filament, if you want to clear the nozzle (thatā€™s what a purge block is for, but okay) then keep the extruder lever pressed and push the filament by hand as if you were loading it (do not do a manual extrude) until you get it cleared.

Hope that helps. It certainly confused me at first when I was setting it up.
(edit: fixed a spelling error)

Thankyou @BlaiddGwyn, thatā€™s some very useful information you have there.

That is very interesting and relevant information, thank you.

When I say:

I am referring to the ā€œRESTORE_GCODE_STATEā€ command itself.
As in:
RESTORE_GCODE_STATE NAME=M600_state MOVE=1

From what I understand the ā€œRESTORE_GCODE_STATEā€ on its own simply loads the saved state back into the printer but doesnā€™t instruct the printhead to actually go there. To do that you need to add the ā€œMOVE=1ā€ directive to the end. The reason I thought this would be necessary is because if the print head is left in the ā€œparkā€ position and the next G0 command also extrudes filament you could possibly get filament extruded from the ā€œpark positionā€ to that point rather than from the ā€œsaved positionā€ to the point. I may have misunderstood this but my resume macro (rather than me M600 macro) did come with the ā€œMOVE=1ā€ command appended:

[gcode_macro PAUSE]
rename_existing: BASE_PAUSE
gcode:
   SAVE_GCODE_STATE NAME=PAUSE_state
   BASE_PAUSE

   G91
   G1 E-1 F1500
   G1 Z10
   G90
   G1 X10 Y10 F6000

[gcode_macro RESUME]
rename_existing: BASE_RESUME
gcode:
   G91
   G1 E2 F1500
   G90
   RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1
   BASE_RESUME

Although now that I think about this more, perhaps the reason the ā€œM600ā€ macro omits the MOVE=1 directive is because it gets executed at the end of that ā€œM600ā€ macro leaving the printer in the ā€œre-loadedā€ state while you change the filament without actually moving there. If MOVE=1 were to be appended at that stage the print head may move to the ā€œpark positionā€ then immediately revert to the save position without giving you the opportunity to actually change the filament. In the ā€œRESUMEā€ macro however itā€™s fine to go directly to the saved position so the MOVE=1 is included.

Given there is a G1 X10 Y10 F6000 command in my PAUSE macro it does make the similar line in the M600 macro redundant. I also find it curious that the PAUSE macro has G1 E-1 F1500 while the RESUME has G1 E2 F1500. Would this not extrude 1mm of filament upon resuming??

By the way, Iā€™m assuming itā€™s that BASE_PAUSE call that is actually pausing the print job itself then, yeah?

Right, that is a concern. Any idea how I could reset the extruder value without actually moving the stepper? Really thatā€™s what I would like to do.

I appreciate that is what the purge block is for but given it is only this one layer that is really using it I figured Iā€™d just manually feed it through until I was happy with the colour, snip of the stream and continue on. I know I could do this by hand bit I find it eaiser to just purge 100mm with the extruder, check the stream and, if discoloured purge another 100mm and check again.

By the way, in my searching I did come across this poorly shot video which does seem to imply that ā€œclickingā€ the resume button is different to ā€œsendingā€ a resume command and implies that ā€œsendingā€ the command is the correct way to do things:
https://www.youtube.com/watch?v=PPN6_VAteeA&ab_channel=A12StudiosInc.

Okay, finally got this to work.

The trick was to basically just remove everything from that M600 macro and simply call ā€œpauseā€ and rely upon the PAUSE and RESUME macros to do all the work:

[gcode_macro M600]
gcode:
    PAUSE

I found it was good to also call G92 E0.0 in both the PAUSE and RESUME macros to make sure and manual extrudes do not interfere with the print itself:

[gcode_macro PAUSE]
rename_existing: BASE_PAUSE
gcode:
    SAVE_GCODE_STATE NAME=PAUSE_state
    BASE_PAUSE
   
    # Suck up the filament for the journey
    G91
    G1 E-10 Z100 F1500

    # Head to the parking location
    G90
    G1 X150 Y0 F6000

    M83                   # Put the extruder into relative mode
    G92 E0.0           # Reset the extruder so that it thinks it is at position zero

   
[gcode_macro RESUME]
rename_existing: BASE_RESUME
gcode:
    # Suck filament up for the journey back to the print
    G91
    G0 E-10

    G92 E0.0           # Reset the extruder again so that it thinks it is at position zero again (still in relative mode)
    M82                   # Put the extruder back into absolute mode.

    # Back to work again.
    G90   
    RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1

    # re-prime the filament.
    G91
    G1 E10
    G90

    # As you were
    BASE_RESUME

And finally itā€™s important to resume the print by typing RESUME into the terminal rather than pressing the resume button on the control tab of Octoprint.

Note the macro retracts the filament for the journey back to the print then re-primes it just before resuming, so you should have the extruder ready to extrude when you send the RESUME command.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.