Skip to content

shift register support for running stepper motors (useful for Prusa MMU2/3)#7223

Open
ErdbeermarmeladebrotmitHonig wants to merge 7 commits intoKlipper3d:masterfrom
ErdbeermarmeladebrotmitHonig:master
Open

shift register support for running stepper motors (useful for Prusa MMU2/3)#7223
ErdbeermarmeladebrotmitHonig wants to merge 7 commits intoKlipper3d:masterfrom
ErdbeermarmeladebrotmitHonig:master

Conversation

@ErdbeermarmeladebrotmitHonig
Copy link
Copy Markdown

Hi,
I just finished adding support for shift registers. This is not performed in Python but in C code, which enables using shift register pins as pins for stepper motors (I limited it to the DIR and EN pins intentionally, because a shift register might be too slow for running a STEP pin). This allows to run Klipper on a Prusa MM-Control board and therfore on Prusa MMU2/3. 🥳
Currently. this code is only tested on the Prusa MM-Control board and thus on the ATmega32U4 microcontroller. However, this code should also work with other microcontrollers.

Thanks to @Freakazo for his amazing work, I used his code as a basis. Furthermore, I used his code as basis for my pull-request to the MMU software Happy Hare which can be found here.

I have done this because I love my Prusa MK3S+ and MMU2S. Hopefully, this PR and the one in Happy Hare will be accepted in order to save a lot of Prusa MMUs (and probably Prusa MK3s) from being thrown away 🙏 😄

PS: I am planning to add support to Klippain and write a documentation how to upgrade both the Prusa MK3 (there is already a lot of documentation) and the Prusa MMU2/3 to Klipper and Happy Hare!

@nefelim4ag
Copy link
Copy Markdown
Collaborator

There is a bit of code and code duplication.
It would help if you explained how it is supposed to work and why it is how it is.

From what I can understand, from the schematics: https://github.com/prusa3d/MM-control-2.0/blob/master/rev.03/MM-control.pdf

74HC595 shift register used to drive EN/DIR pins on the drivers.
Where the drive of the EN pin can be easily done from the host, the DIR pin is much more complicated.
Because of the deep integration with step timings and the step queue.

So, I hope I understand correctly why it is how it is.

Looking at the actual implementation:

It seems to work only during the filament changes and releases the filament as soon as the extruder has a grip.
So, there were no requirements to have synchronous multi-MCU motion.

I honestly think it would be simpler to emulate the dir pin through the "shaft" register, for example.
generally doing the steppers' direction changes completely from the host.
So one can do:

MANUAL_STEPPER STEPPER=mmu_selector MOVE=10
M400
SET_PIN PIN=selector_dir VALUE=0
# or
SET_TMC_FIELD FIELD=shaft VALUE=1
MANUAL_STEPPER STEPPER=mmu_selector MOVE=-10

It is a little bit ugly and suboptimal, of course, but it should allow one to basically support this specific niche device, without large firmware complications.

Hope that helps,
-Timofey


Regardless, please make yourself aware of https://www.klipper3d.org/CONTRIBUTING.html
Normally, you at least have to add a sign-off to the commits or at least the original message.

@ErdbeermarmeladebrotmitHonig
Copy link
Copy Markdown
Author

Hi,

thanks for your reply! Acutally, I have never thought that this would already work with Klipper today, thanks for the tip!
And yes, you are totally right, that in the original firmware the MMU motors are only used during filament change.

However, this is actually what I wanted, because a lot of friction is added to the system through all the used PTFE tubes (printhead to MMU and MMU to filament). This might not be a problem with slower printing speeds but is problematic at higher speeds. Thus, I am using the extruder motor sync as implemented in the Happy Hare MMU software. I haven't inspected the timing behaviour too much, however on my machine this is working just fine and I haven't had timing issues at all.

I agree with you that the firmware changes for Klipper should be kept at a minimum, thus I tried to have as little changes to the original Klipper code as possible and add additional but optional files instead. Like the additional C-source files are not used as long as the shift register feature is enabled in the menuconfig. I think this is what you meant by code duplication, right?

However, I disagree about this device being a "niche device". Acutally, the MMU3 is still the state-of-the-art MMU for Prusa printers, at least until the INDX kits are available. I have not found any numbers about sold MMU2/3 units, however I assume that a lot of those units are out there.

Finally, I am sorry that I violated the contributing guide, but I just didn't have time to clean everything up this weekend and I wanted that people who are interested can already test it. I am currently ill but I will clean up this code as soon as possible.

Best Regards
Michael

@nefelim4ag
Copy link
Copy Markdown
Collaborator

nefelim4ag commented Mar 17, 2026

because a lot of friction ... problematic at higher speeds

A decent extruder should be able to create kilograms of force. I think Prusa's extruder should be decent.
You can verify that it can lift up the 1 kg spool from the floor through the PTFE tubes. Normally, it should be able to.
Where 1 kg of force is enough during normal printing. It will only require more, if you can't melt filament fast enough.

I am using the extruder motor sync as implemented in the Happy Hare MMU software.

On second thought, in any circumstances, this MMU will mostly run 1 stepper at a time.
So, as long as the shift register is capable of passing through the DIR pin to the active motor, it should work with a pure host-side implementation.

  1. Enable pins set up upon startup; steppers will be enabled/disabled through the SPI
  2. Idler stepper latched onto one direction only
  3. Leave us only 2 DIR pins: pulley motor and channel selector

Special care should be taken when switching between the motors. Because the toggle of the dir pin is expected to be stateful between the steppers, which is not the case in this example.

device being a "niche device".

The board is niche, even if it is widespread (50000 units);
One who needs to can replace it with anything else, and Prusa's MMU will still be "state-of-the-art MMU".

Finally, I am sorry that I violated the contributing guide ... I am currently ill

You have nothing to be sorry about. This is just about the general rules to follow.
Get well.


To sum up the things:
I don't think it is worth it to add a batch of code that duplicates and complicates the parts of the firmware to add support for one niche board, for one specific MMU out of many MMUs.
Regardless of specific implementation, I would be leery about touching the stepper.c and gpio.c

Where, I think,
It is possible to separately implement and merge the support for the 74HC595 shift register.
(Similar things were done for other board-specific solutions, like digipots).
If it will be fully controlled from the host side through the GPIO toggle, example SW I2C toggle - has been removed in the master.

Which, AFAIU, should be enough for the board resurrection under the Klipper.
That way, the only crucial part to discuss would be, I think, the DIR pin workarounds for the (manual?) stepper code.

Where one can later build MMU-specific code on top of that, if MMU-specific code is necessary at all.

Best Regards,
-Timofey


AFAIU, there is some willingness to work with multiplexers of different kinds: moggieuk/Happy-Hare#512
Maybe there are other boards with multiplexers; maybe it's worth considering.
Maybe one can simply use the TMC built-in motion ramp generator for this type of thing. No such thing on TMC2130.

@KevinOConnor
Copy link
Copy Markdown
Collaborator

Thanks.

FYI, this has been discussed several times before - for example: #905, #1047, #3606.

At a high-level, I have the same feedback that was in the above PRs - the complexity of supporting shift registers in the mcu code seems too high to justify this one very quirky board. In particular, it is hard to justify that complexity when it seems possible to implement the support entirely in the host code.

Cheers,
-Kevin

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

Thank you for your contribution to Klipper. Unfortunately, a reviewer has not assigned themselves to this GitHub Pull Request. All Pull Requests are reviewed before merging, and a reviewer will need to volunteer. Further information is available at: https://www.klipper3d.org/CONTRIBUTING.html

There are some steps that you can take now:

  1. Perform a self-review of your Pull Request by following the steps at: https://www.klipper3d.org/CONTRIBUTING.html#what-to-expect-in-a-review
    If you have completed a self-review, be sure to state the results of that self-review explicitly in the Pull Request comments. A reviewer is more likely to participate if the bulk of a review has already been completed.
  2. Consider opening a topic on the Klipper Discourse server to discuss this work. The Discourse server is a good place to discuss development ideas and to engage users interested in testing. Reviewers are more likely to prioritize Pull Requests with an active community of users.
  3. Consider helping out reviewers by reviewing other Klipper Pull Requests. Taking the time to perform a careful and detailed review of others work is appreciated. Regular contributors are more likely to prioritize the contributions of other regular contributors.

Unfortunately, if a reviewer does not assign themselves to this GitHub Pull Request then it will be automatically closed. If this happens, then it is a good idea to move further discussion to the Klipper Discourse server. Reviewers can reach out on that forum to let you know if they are interested and when they are available.

Best regards,
~ Your friendly GitIssueBot

PS: I'm just an automated script, not a human being.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants