How-to prevent bed drop during config save restart (Z Belted printer)

Basic Information:

Printer Model: Pi 4 => Octopus v1.1 => EBB36 v1.2. Building a V1E MP3DP v4 CoreXY with 3 Z Steppers. Link to 60sec build montage below.
MCU / Printerboard: Octopus v1.1 with EBB36
klippy.log (not relevant). Shared my printer.cfg on github.

:white_check_mark: Tried to self help via Knowledge Base

:white_check_mark: Tried to self help via this and this post***
[/quote]

Describe your issue:

Is there a config/macro, or code change, way to prevent Beds on Z Belted printers from violently dropping when config changes are saved and restart occurs? Is there a way to have the Z steppers remain energized throughout the shutdown-restart sequence? Ignore power outage scenarios for now.

Main goal is to prevent the back EMF killing the Controller board. We’re seeing larger heavy builds with Glass+Alu bed assemblies violently free falling and killing Controller boards (SKR 1.2).

For me, slowing/stopping the bed to reduce physical trauma to the overall assembly is a secondary goal (e.g. use some TPU dampers to soften/absorb impact).

Several folks on the V1E forum are discussing various mechanical (e.g. Constant Tension Springs and/or counter weights), and electrical solutions (e.g. Nero3D, STOP THE DROP! - Project R3D Zmotor Brake Board ). However, am wondering whether there’s some Klipper based partial/full solution?

60 sec build montage for my V1E MP3DP v4 printer…

If there’s no way to maintain bed position between config saves, then will try ensuring a shutdown macro always moves bed to a safe position.

Cheers!

[fyi @Jonathjon]

1 Like

It seems like a poor design choice to make a printer that crashes violently whenever power is lost to the drivers.

You can pull the driver enable pins high or low in the menuconfig settings when building firmware, but messing with driver pins before the MCU has initialized could possibly damage the drivers.

4 Likes

Fully agree with @jakep_82 here. There is no software solution possible since at certain constellations this will fail.
The only true solution is a “normally closed” mechanical or electromechanical solution.
Steppers with brakes might be a solution, but I do not know if they are NC or NO.

1 Like

Does Klipper support something like SHUTDOWN or BEFORE_SHUTDOWN macros that can automatically execute as part of Klipper’s restart sequence, before steppers are deenergized? During config saves, that trigger restarts, would like to best effort attempt moving Bed to a safe location.

Something that’s a counterpart to the existing hook for invoking startup macros… https://www.klipper3d.org/Config_Reference.html?h=initial_duration#delayed_gcode ?

Obviously am **** out of luck if for power outage and various unexpected fail scenarios.

Various folks are looking into design, mechanical and electrical solutions too.
Pros/cons/tradeoffs… Am looking to understand and maximize what’s possible through software in the meantime.

You can write macros for save_config and restart using the rename_existing feature. That would allow you to move the bed before the restart is executed.

2 Likes

I have the same printer as @azab2c. I’m still very early in the learning phase of Macros. Would something like this work?

[gcode_macro SAVE_CONFIG]
rename_existing: SAVE_CONFIG
gcode:
     G28                       #home all axis
     G0 Z375 F2000             #drive bed to max z to prevent drop
     SAVE_CONFIG               #save config and restart

If that wont work do you have any suggestions for what will? Thank you!

1 Like

Hey @Jonathjon, just turned on my printer, am currently editing and trying this out too… Will update on what I end up with, unless you/someone chimes in before me.

Not this…

[gcode_macro SAVE_CONFIG]
rename_existing: SAVE_CONFIG
gcode:
     G28                       #home all axis
     G0 Z375 F2000             #drive bed to max z to prevent drop
     SAVE_CONFIG               #save config and restart
ERROR: gcode command SAVE_CONFIG already registered

Or this…

[gcode_macro AZA_SAVE_CONFIG]
rename_existing: SAVE_CONFIG
gcode:
     G28                       #home all axis
     G0 Z375 F2000             #drive bed to max z to prevent drop
     SAVE_CONFIG               #save config and restart
Existing command 'AZA_SAVE_CONFIG' not found in gcode_macro rename

Hmm, am RT*M’n more and looking for examples…

1 Like

FIRMWARE_RESTART is what Klipper calls it when you hit save config and it restarts. But I tried a few different ways and nothing worked for me. I forgot to take screenshots

1 Like

These issues can be handled by, and are best handled by a mechanical implementation. If the bed is heavy and is belted and is dropping/sagging when de-energized, it’s best to use a gear ratio to give the stepper motor’s detent torque the mechanical advantage.

Larger motors with higher detent torque can be used as well.

If you need some ideas to achieve this, look at Voron 2.4’s Z gearbox. A 16T pulley and an 80T pulley are coupled with a belt to provide an 80:16 gear ratio. The same principle can be carried over to any other application. Of course this means some work on your end to find what’s best, but it’s a start.

The only other thing I can think of would be an electronic brake using relays tied to a winding for the motor or something like that, but there is some risk there.

Best of luck! I am eager to see what you come up with.

1 Like

That won’t work. You need to rename the existing to a name that doesn’t exist. Something like the macro below should work.

[gcode_macro SAVE_CONFIG]
rename_existing: _SAVE_CONFIG
gcode:
     G28                       #home all axis
     G0 Z375 F2000             #drive bed to max z to prevent drop
     _SAVE_CONFIG              #save config and restart
1 Like

Thank you @jakep_82, the syntax makes more sense to me now. That saved without error. But the Macro didn’t kick in and execute as expected (when Save and Close or Save & Restart are clicked in mainsail).

[gcode_macro SAVE_CONFIG]
rename_existing: _SAVE_CONFIG
gcode:
    M117 Save Config override, move bed to safe pos
    G28                       #home all axis
    G0 Z230 F5000             #drive bed to max z to prevent drop
    _SAVE_CONFIG              #save config and restart

Am still RT*M’n and digging…

EDIT: Am updating to ensure I’m running latest bits…

Try adding M400 before _SAVE_CONFIG

1 Like

There’s another, simpler way… My printer has a ~700mm Z axis that is belt lifted. I chose a mechanical method of preventing bed drop after a seriously loud drop occurred during testing. I looked at brakes, counterweights, and even a seat-belt type centrifugal brake, but ultimately decided upon a 30:1 worm gear drive reducer that prevents bed movement when power is cut, and even allows for continuing a print after power is interrupted. It has been working with 100% reliability for about 6 years.

Here is the motor/gearbox that I used, currently priced at $118. You also need a keyed, 8mm shaft to go with it.

The beauty of this is its simplicity. It is permanently lubricated. There’s no weird config or wiring to switch a brake solenoid, no complex belting to get some gear reduction for small vertical steps, and no external drivers required. All you do is set the steps/mm, speed (about 15 mm/sec), and motor current. With 30:1 reduction, the bed moves 20 um per full step of the motor and can lift a lot of weight. There’s no possibility of backlash because the weight of the bed assembly keeps the gear teeth in contact on one side at all times.

The bed assembly in my printer weighs about 3.5 kg. I run the motor at about 1/2 its rated current so it doesn’t even get warm, and the driver chips on the Duet 2 controller board have no trouble driving it. I have tested it with an additional 4kg load piled on the bed and it works without any problems.

There are other worm gear boxes out there, but unless the gears are very well made, you may see repeating Z axis artifacts in prints. The Rino that I used has very high quality gears (the part costs $800 new!) that do not produce print artifacts.

With worm gear drives, it is sometimes possible to back-drive the gears. The 30:1 Ondrives Rino I used is not guaranteed to be impossible to back drive (higher ratios can sometimes be guaranteed) but it would require a much bigger load than the 7.5 kg I have tested it with. In my printer, the bed doesn’t move at all when power is cut. If you want to resume a print after a power loss, the bed might jump a bit when power is restored, which might leave a visible defect in the print depending on how much the motor jumps. At 20 um per full step it’s probably not going to be too bad.

2 Likes

Yeah, nice solution but putting a 600+ USD gear into 750 USD printer seems, uhmm…less economical (unless you get a working one used for cheap)

Typically, worm gears at a “hobby price point” are not a solution, since they suffer from an abysmal backlash.

3 Likes

It’s not a $600+ part. It’s a $118 part- look at the ebay listing. The fact that is costs $800 new tells me it’s probably a pretty high quality part (and my experience bears that out). You may have other ideas, but I want more high quality parts in my printer, not fewer. I’d never spend $800 to buy one of those worm drives new, but I’m happy to get it for $118 (actually $108 when I bought mine about 7 years ago). I also like reliability. Adding brakes and additional electronics decreases reliability.

With worm gear drive in the Z axis, backlash is all but impossible because the weight of the bed assembly keeps the same gear surfaces in contact at all times. The problem with “hobbyist grade” worm drives (and probably many cheap industrial drives) is that the surfaces of the gears are poorly (or not) ground. That leads to repeating artifacts in the Z axis each time the worm and disc gears make complete revolutions. (I have tested this).

I am also in favor of driving the Z axis with a single motor so you don’t have to worry about the bed tilting when power is cycled. That eliminates the need for auto leveling/tramming, and so eliminates the need for a bed sensor, additional motors, drivers, and cables and all the configuration that goes into getting all that stuff to work. Improved reliability though simplicity!

1 Like

Don’t get me wrong, I like your design and I’m absolutely in favor of using solid hardware.

Still, it is kind of a solution like recommending high quality used ballscrews, e.g. THK or Rexroth instead of going belted. Also with the very same arguments you have above.

In the end various (high quality) solutions might reach the same goal.

2 Likes

Cheers for the suggestions and discussion. Tried the following without much luck, still not seeing any evidence of the macro being invoked. Did briefly look at where SAVE_CONFIG is referenced Code search results · GitHub

[gcode_macro SAVE_CONFIG]
rename_existing: _SAVE_CONFIG
gcode:
    SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=1
    SET_STEPPER_ENABLE STEPPER=stepper_z1 ENABLE=1
    SET_STEPPER_ENABLE STEPPER=stepper_z2 ENABLE=1
    M117 Save Config override, move bed to safe pos
    # G28                       #home all axis
    G0 Z230 F5000             #drive bed to max z to prevent drop
    M400
    _SAVE_CONFIG              #save config and restart
    SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=1
    SET_STEPPER_ENABLE STEPPER=stepper_z1 ENABLE=1
    SET_STEPPER_ENABLE STEPPER=stepper_z2 ENABLE=1

Still need mechanical solution for some failure scenarios, so looking into those for now…

This is how industrial robots do it (albeit with servo motors with battery-backup on their encoders).

OP, could you setup something similar with a solenoid system with a cog-wheel and just pull the solenoids in when Klipper boots up (spring loaded so that in the event of a power loss they engage the cog)? Maybe even with rounded edges such that if SHTF the cog-wheel could still turn albeit slowly and with more force.

Now that I think about it, I just described a brake drum. You could just set up a band on a drum with a solenoid.

1 Like

Lots of good mechanical solutions posted!

This isn’t the most practical solution, but you could solve this with electronics by having a normally-closed relay on each stepper (DPST, double pole, single throw), such that when the relay is off, it’s shorting out the individual windings. This will make the motors very hard to turn and the bed would descend very slowly (and the stepper drivers will see basically no back EMF).

When the printer is on, the relays would always be energized and thus out of circuit. If you only needed power-loss protection, you could drive the relay coils directly from your power supply. Otherwise, you’d need a transistor and switch them on via a GPIO pin (or maybe one of the stepper enable pins).

TMC2209’s (and maybe other drivers) have short-circuit protection, but if you wanted to be safe you could put a ~1ohm resistor in series with the relay contacts.

This is pretty involved, though it could be made as a small external board you run your stepper cables through.

Edit: Apologies, this seems to be exactly what is covered in a video you linked! Didn’t notice it before posting…

1 Like

For what it is worth, I don’t know of any “good” way to accomplish what you are looking for.

I suppose one could not declare an enable_pin in the stepper motor config section (that option is not required). I suppose one could define an [output_pin] config section with the actual enable pin. One could, theoretically, then ensure via macros that any print start, print end, print idle, etc invokes the proper manual SET_PIN commands to actually enable/disable the stepper. It is also possible, I suppose, for one to force set the pin in “make menuconfig” (under the low-level options) if a particular setting was required during micro-controller startup. I’m sure there are many cases where this manual setup could cause confusing and poor results, so I would not call this a “good” solution.

Cheers,
-Kevin

1 Like