Hello,
I have recently been recovering prints with klipper. I have found that it is not as hard as it seems, and I am putting out this tutorial for anyone and everyone to use. Be this as it may, PLEASE do not take anything in this tutorial completely seriously. My printer is different to yours, and I seriously doubt that anyone will be able to directly implement the changes I made to recover their print. I will be producing a companion video for this post, but for now, this will have to do.
Be it if the power turned off, or the filament ran out, there are a few prerequisites that need to happen if you are to recover a lost print.
-
You need to have notepad++ installed, or some other text editor.
-
You need to have a program called Winscp installed. This allows you to upload your modified gcode files directly to your printer’s ip address.
-
You need to be able to home the printer.
-
If you have a traditional endstop, the printer needs to be able to touch it without hitting your print (duh).
-
If you have an abl sensor, it needs to be able to safely touch down ANYWHERE on the bed without the print being hit.
-
You need to be able/willing to get your feet wet and edit your printer.cfg and your start print macro. I assume that you are, bc why else would you be trying to recover a print?
-
The heated bed needs to be hot, if the print has released, you can’t pull this off.
-
You need to have a bed mesh saved if you are using abl
-
This one is more of a step you need to do after EVERY SAVE AND RESTART. HEAT YOUR BED BACK UP. This is needed to keep your print on the bed. A couple of degrees lost won’t really affect your print negatively.
-
Take note of all changes so you can put them back right once your print finishes.
-
If your nozzle has stuck to the print, make sure that it is hot before you try to move it away.
Now that we have these prerequisites out of the way, let us now dive into how to recover a print with klipper. It all started one day when I lost a print that I needed to finish to get to someone I knew by the next day. Due to time limitations I couldn’t restart the print, that would take too much time. I figured that the print was a goner anyway, so I decided to give recovering the print a try. I pulled a quick yt search, and to my surprise, no one had ever made a video on this subject, let alone even tried it and said “no, sorry this doesn’t work.” I decided to give it a shot, and found that yes, you can in fact recover a lost print with klipper, no matter the way it failed.
The first step to recovering a print with klipper is to make sure that all of the prerequisites that I listed above check out. After that, we are going to have to edit our gcode file that we used to print. Locate the gcode file that you used to print, and download it using the blue and white cloud icon in the "gcode files’’ section. Once you have done that, we need to figure out the height that the print failed at. You can simply measure this height with a ruler that has millimeters, it is it slightly off, that won’t matter. We’ll have to deal with this issue later. Once you have determined the height, write it down somewhere. Next, open your gcode file in your preferred text editor. Use the “find” function to determine your z height. In prusa slicer, the z height is determined by " ;z: your height ". Every slicer is different, so figure it out if you are not using prusa slicer. Then, when you find that line of code, delete every line of code before it except for your start print gcode and other necessities. Cnc kitchen has a really good video, and from 6:33–8:33 he explains how to do this perfectly. Don’t worry, what he does in that segment of video will work with klipper. Simply then save the file to desktop on your computer. Because of the way Winscp works, it needs to be the desktop. I usually call it "Recovery_File_“Print_Name”.gcode. The next step is to upload this file to your printer.
To upload your files directly to your printer we’re going to use Winscp. It is a software that allows you to connect two devices together, and is usually used to get the klipper update files for your mainboard chip off of your pi. Upon opening of this program, you will be prompted to enter the host name: just enter your printer ip address here. then it will ask for a username, and then a password, enter the username and password that you usually use to access your pi. Once done correctly it will bring up a directory of your computers files, and your printers files. Simply navigate to your desktop in the Winscp popup window and find the recovery file. We now have to find the directory where the gcode’s are stored on our printer. Mine was stored in: home/biqu/printer_data/gcodes/. Now drag over the file from your desktop, to this directory. When done, there will be your file in the gcodes section of your online klipper control panel. Hooray!
The next thing that we have to do is a bit more difficult, and will apply whether you have an abl sensor or if you have a typical endstop. You need to home the printer. With marlin you can fool the printer into thinking that it is at a certain height, and you can with klipper too. . . But as @Piezo said: " A [force_move]
config will enable the SET_KINEMATIC_POSITION
command which can be used to fake homing. Please read the documentation carefully as it is one of the dangerous commands." It isn’t considered a safe thing to do. I may come out with a version of this recovery process in the future with this implemented.
However, since I don’t know much about this feature, I will keep it out for now. If the print is small enough, you can set the head down onto the bed. Adjust the z safe home feature if you have abl to pinpoint home the nozzle anywhere on the bed. Save and restart to save changes, then heat the bed. If you have a typical endstop, make sure that it will home as intended without hitting the print. Now comes the part where abl users need to do a couple of extra steps. If you have a typical endstop, skip to the end of the paragraph and read on. If you are using abl you are going to adjust your fine movement buttons on the home screen klipper control panel. This can be done by going into the settings and changing the fine movement to: “ .1 , .05 , and .025 ” respectively. Once that is done, raise z to the specific height failed, and position the nozzle so as it is right above the print. Slide a piece of paper underneath the print and the nozzle, and use the fine movement adjustments to move the nozzle to where it scrapes the paper. Take note of how much you moved the nozzle up or down, and add or take away that value from your z offset. For example, my z offset is 2.5, and I needed to move the nozzle down by .2, my new z offset would be 2.7. This setting is weird, if you need to move the nozzle down, add that number to your z offset, if you need to move it up, take it away from your z offset. This will insure that your print will start a good spot regardless of the wacky unusual point that you homed at. Of course take note of your old z offset so you can reimplement it later. And with that, we are moving on to the next and last step which is editing your start print macro.
Editing your start print macro is probably the easiest part, it just requires some basic logic on what we want done when the print starts. For example, here is my start print macro:
[gcode_macro START_PRINT]
gcode:
{% set BED_TEMP = params.BED_TEMP|default(80)|float %}
{% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(240)|float %}
# Use absolute coordinates
M104 S120 ; set temporary nozzle temp to prevent oozing during homing
M140 S{BED_TEMP} ; set final bed temp
# Start bed heating
G90
# Reset the G-Code Z offset (adjust Z offset if needed)
SET_GCODE_OFFSET Z=0.0
# Home the printer
G28
#Build Bed Mesh
BED_MESH_CALIBRATE
# Move the nozzle near the bed
G1 Z5 F3000
# Move Nozzle To Edge Of Bed
G1 X2.0 Y8.0 F18000 ; go to edge of bed
G1 Z0.2 F5000
# Move the nozzle very close to the bed and wait for print to start
#Heat Bed and Nozzle
M104 S{EXTRUDER_TEMP} ; set final nozzle temp
M190 S{BED_TEMP} ; wait for bed temp to stabilize
M109 S{EXTRUDER_TEMP} ; wait for nozzle temp to stabilize
#Purge Line
G1 X0.0 Y8.0 F18000 ; go to edge of bed
G1 Z0.2 F5000 ; lower nozzle
G92 E0.0 ; reset extruder position
G1 Y100.0 E16.0 F1000.0 ; start intro line
G92 E0.0 ; reset extruder position
G1 Y180.0 E18.0 F1000.0 ; finish thicker
G92 E0.0 ; reset extruder position
My current macro says a bunch of things, a lot of which are a big no-no when it comes to restarting a failed print, number one, it says to probe the bed before every print. We want to change that to restore the bed mesh that we have previously stored in our .cfg file. It also says to create a purge line on top of other things, we want none of that. All we want is for it to heat up, home, restore a mesh, and start the print. Here’s how my start print macro looks after that.
[gcode_macro START_PRINT]
gcode:
{% set BED_TEMP = params.BED_TEMP|default(80)|float %}
{% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(240)|float %}
# Use absolute coordinates
M104 S120 ; set temporary nozzle temp to prevent oozing during homing
M140 S{BED_TEMP} ; set final bed temp
# Start bed heating
G90
# Reset the G-Code Z offset (adjust Z offset if needed)
SET_GCODE_OFFSET Z=0.0
# Home the printer
G28
#Restore Bed Mesh
BED_MESH_PROFILE LOAD=YOUR_SAVED_BED_MESH_NAME
#Raise z to maximum to avoid hitting the print when going to the "edge" of bed.
G1 Z350.0
# Move Nozzle To Edge Of Bed
G1 X2.0 Y8.0 F18000 ; go to edge of bed
#Heat Bed and Nozzle
M104 S{EXTRUDER_TEMP} ; set final nozzle temp
M190 S{BED_TEMP} ; wait for bed temp to stabilize
M109 S{EXTRUDER_TEMP} ; wait for nozzle temp to stabilize
You can also make this a separate start print macro, comment it out for when you don’t need it, and then uncomment it and comment out your OG macro when you need to recover a file. That looks like this:
#****************Normal Start Gcode****************#
[gcode_macro START_PRINT]
gcode:
{% set BED_TEMP = params.BED_TEMP|default(80)|float %}
{% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(240)|float %}
# Use absolute coordinates
M104 S120 ; set temporary nozzle temp to prevent oozing during homing
M140 S{BED_TEMP} ; set final bed temp
# Start bed heating
G90
# Reset the G-Code Z offset (adjust Z offset if needed)
SET_GCODE_OFFSET Z=0.0
# Home the printer
G28
#Calibrate Bed Mesh
BED_MESH_CALIBRATE
# Move the nozzle near the bed
G1 Z5 F3000
# Move Nozzle To Edge Of Bed
G1 X2.0 Y8.0 F18000 ; go to edge of bed
G1 Z0.2 F5000
# Move the nozzle very close to the bed and wait for print to start
#Heat Bed and Nozzle
M104 S{EXTRUDER_TEMP} ; set final nozzle temp
M190 S{BED_TEMP} ; wait for bed temp to stabilize
M109 S{EXTRUDER_TEMP} ; wait for nozzle temp to stabilize
#Purge Line
G1 X3.0 Y8.0 F18000 ; go to edge of bed
G1 Z0.2 F5000 ; lower nozzle
G92 E0.0 ; reset extruder position
G1 Y100.0 E16.0 F1000.0 ; start intro line
G92 E0.0 ; reset extruder position
G1 Y180.0 E18.0 F1000.0 ; finish thicker
G92 E0.0 ; reset extruder position
#****************Recovery File Start Gcode****************#
#[gcode_macro START_PRINT]
#gcode:
# {% set BED_TEMP = params.BED_TEMP|default(80)|float %}
# {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(240)|float %}
# # Use absolute coordinates
# M104 S120 ; set temporary nozzle temp to prevent oozing during homing
# M140 S{BED_TEMP} ; set final bed temp
# # Start bed heating
# G90
# # Reset the G-Code Z offset (adjust Z offset if needed)
# SET_GCODE_OFFSET Z=0.0
# # Home the printer
# G28
# #Restore Bed Mesh
# BED_MESH_PROFILE LOAD=default
# #Raise Z To Maximum Height So As To Not Hit The Print When Moving To "Edge" Of The Bed
# # Move Nozzle To Edge Of Bed
# G1 X2.0 Y8.0 F18000 ; go to edge of bed
# #Heat Bed and Nozzle
# M104 S{EXTRUDER_TEMP} ; set final nozzle temp
# M190 S{BED_TEMP} ; wait for bed temp to stabilize
# M109 S{EXTRUDER_TEMP} ; wait for nozzle temp to stabilize
Thanks to @NiXXiN for suggesting this great addition! Make sure to save, restart, and heat the bed. (Ideally you should be able to paste this macro in instead of yours and have it work, so settings in here are going to be printer specific.) And that is the last step! On to starting the print.
I mean, now is the moment of truth! Hit start on your recovery file print, and keep your mouse on the emergency stop button, or your finger or the power switch. If all goes well, you should see the printer start heating up, go over to a designated spot, wait for a couple seconds (or minutes if you have slow heaters) and start the print again! This has worked for me multiple times, and one one print I had to recover it twice, on the same print! And this step by step process worked both times.
And with that, you should be able to recover a print with these simple steps. It is quite hard to put all of this detail into words, so like I said, I will be making a video, but in the meantime, This should suffice. Before you go and blindly trust these settings for a big print, I encourage you to go off and print a benchy, and then turn off the power for a second mid print! Turn the power back on, and once your printer comes back online, make sure to heat up the bed, and then try to recover it! If it works well, comment below and let me know. If it DIDN’T, let me know so I can try and make this work for everybody!
Ps: If you don’t have a bed mesh saved for abl, do it now so you can recover prints down the road. Position prints so that you can home properly. Set yourself up for success. As @enderbender mentioned, a power loss recover unit would be a good idea, so the bed never turns off, and the printers position is saved (assuming you have set the auto timeout feature high enough.) But this guide is still helpful if, for example, you get a filament jam, a clogged nozzle, or you just ran out of filament. I’ll still be looking into the ups as it would be nice to keep the printer’s position, and keep the bed hot.
Happy Printing Everyone,
Blake