-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for multiple MCU chaining via I2C #119
Comments
I like the idea of daisy chaining especially with I2C which uses less wires. However, Klipper is designed to calculate moves ahead of time and transfer this schedule to the controllers. So it will not work in real time out of the box. But this is also the reason why USB jitter does not matter. The host transfers the planned moves ahead of time and the controller outputs those steps exactly at the times they are planned, using queues and time synchronization. It may be possible to add real time commands (may be via some special time value of "now"). And at least some bigger parts of the host software would have to be rewritten. |
I'm not suggesting implementing real-time. The idea was multiple arduinos,
each with it's own schedule, so the existing non real-time behavior can be
maintained.
The price point of the Mechaduino boards is still a bit high for my taste, but it's was a good example of
chainable steppers each with an onboard arduino which could
probably be updated to support the architecture of Klipper.
For the short term, just need to allow different bits of the schedule on
the host to be routed to different SPI/I2C client addresses.
No route = all to one via serial. Route = to one, via some bus.
The arduino code, minus utilizing the alternate bus and adding a byte for
selecting the client address, could likely stay the same.
…On Fri, Jan 12, 2018 at 9:42 AM, Harald ***@***.***> wrote:
I like the idea of daisy chaining especially with I2C which uses less
wires.
(btw. the underlying link url is something on github)
However, Klipper is designed to calculate moves *ahead of time* and
transfer this schedule to the controllers. So it will not work in real time
out of the box.
But this is also the reason why USB jitter does not matter. The host
transfers the planned moves ahead of time and the controller outputs those
steps exactly at the times they are planned, using queues and time
synchronization.
It may be possible to add real time commands (may be via some special time
value of "now").
But I guess there will be several things in the design to be changed. E.g.
things like getting an error if the schedule is missed, which would be the
case for "now".
And at least some bigger parts of the host software would have to be
rewritten.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#119 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ADCSQmeBtJaP2frnxeGv1b_KMbCJMOmWks5tJ29xgaJpZM4RbajD>
.
|
I concluded that from
so, of which advantages of SPI or I2C over USB are you thinking? |
so something like:
|
Instead of a single arduino handling the queue for all axis and generating the pulse trains for all axis, the work can be divided up so each arduino only handles the part of the queue it needs to. Should result in raising the maximum step rate proportionally. I also really like the idea of chaining them. |
you can already delegate each stepper to a different MCU. And it handles only it's own queue, as you said with maximum performance. Only chaining isn't possible (but you can probably use USB hubs). And you cannot use SPI/I2C for that. I am not sure, if a shared bus is a good idea, but it would probably work if the total bandwidth is sufficient. |
for example I recently used:
(note: I use a patch, to use the first mcu as main clock sync instead of needing a nameless [mcu]) |
If you need something controlled in real-time connected it to Rassberry Pi directly, Rassberry Pi have SPI and I2C too, so for example handling LCD-s over SPI will work much better if it is connected directly to Pi. |
Ok, I'm speaking imprecisely. :) Shared bus, not daisy chaining. I suppose you could also do daisy chaining like the Dotstar modules over SPI by acting like a bit shifter. Probably not worth it. I2C is a true shared bus with 127 devices at up to 2Mhz with your average Arduino capable of 1Mhz. SPI is also a shared bus, but each added device consumes another pin on the master so the benefits of chaining decrease a lot. I have sent uncompressed video over it, but the Arduino maxes out at 8Mhz. |
@hg42 Yes, your original addressing scheme looks like it would work. Another layer of abstraction might be clearer but it's your party. |
USB can be much faster (though the Pi is not that fast, on the other end the serial adapter limits the single connection) and hubs and cables are cheap. |
I suppose you are right, but I'll explain my vision. |
@darenschwenke I already had a similar vision of distributed controllers beforehand. You added I2C to the picture which I appreciate. It may not be fast enough, but if not, there could be one bus for XYZ (I eventually need 3xZ = 3...5) and one for the extruders (max. 3 colors + black + white + ... = 1...5++). Lets estimate: I2C=2MHz / serial=250000 is about 8 controllers fully saturated. In my tests a controller had no problem with 3 steppers. |
Confining this enhancement to I2C comes with the added benefit that a master write to channel 0 is received by all slaves simultaneously. Perhaps this could simplify slave synchronization? |
that would be nice (however the sync works very well already). One disadvantage: |
There seem to exist I2C AVR bootloaders, though. |
Thanks for the info, I didn't search for it yet, too man things to do... |
I think I've been unusually lucky with I2C. |
I2C is designed for inter PCB communication. It is not designed to run over wires and doesn't have any like differential signal to protect again EMI. A much better idea would be RS485, chaining can be easy implementing via adding to every packet an 'address' bit. |
RS485 would work, but needs another chip and some passives. At that point I might as well use a nano and USB hub based communication which already works. |
USB isn't so immune to EMI as RS485. One of my prints failed because of EMI breaking down the communication. I would not feel save wiring USB directly to a stepper motor. |
@dragonnn did the print fail on Klipper? Even prints with usual firmware are crc checked. There usually are a sequence number ("N") and a checksum ("*") while printing, depending on the host software. From my experience EMI with 3D printing was always caused by power spikes which resetted some part of the electronics, probably the CPU. This happend on Arduino and SMOOTHIE with different cables. The event was always triggered by switching on a device like a bigger motor or lighting which happened to use the same power strip. Using another mains connection some meters away always worked. This was reproducible (ABAB test). |
@hg42 no this wasn't on Klipper, regular Marlin + Octoprint but CRC doesn't help in USB because what happens - the device disappears form the system and in dmesg you find this: |
I don't think that even klipper can handle an USB disconnect during printing without aborting it. |
would be a nice test :-) (I currently have a broken setup, so anyone else? pull and push the cable) I assume a simple USB transfer error (= bit error = crc error) would be handled by retransmission. I once used USB extensively with cameras (uEye, on Windows) and found that EMI on the signal lines simply caused retransmission. But the power lines are much more sensitive, because they are often used as power of the device. We found that using a separate power supply for the device made it more stable. I also remember my EMI failures (some years ago) made the USB device disappear. I am not sure if it came back without intervention from myself (which would be a reset). Since then I always use a different power cable for the printer and didn't have another failure. My cheap 5m USB cable (amazon basics) from the workstation to the printer often ran along the motor cables but didn't make any problems (using printrun). Any communication problems were reproducible (e.g. Cura), definitely not EMI. |
I don't foresee any issues with using different communication protocols between mcu and host - for example, the PRU already uses a "rpmsg" channel for communication. It will, of course, require the hardware and some minor host and micro-controller code to use that channel. I'm closing this issue as I don't think github issues are a good way to track these types of long-term ideas - I fear they'll linger in an open state forever. |
The architecture of Klipper is split in such a way as to lend itself to using SPI or I2C communication to 'smart' stepper drivers located on or near the individual motors.
These drivers could be purpose built such as the Mechaduino boards, or by using a low cost dedicated Ardunio + stepstick per axis. These devices could then simply be daisy chained which would further extend the capabilities of Klipper to more complicated control scenarios such as robotic control, hexapods, or multiple filament extrusion.
Further dividing the step generation workload among several Arduino's should also allow for higher step rates to be achieved.
At the very least, utilizing SPI/I2C instead of serial would enable an order of magnitude faster hardware based communication between a single host and slave device and without the timing jitter of a USB to serial adapter.
Please consider adopting a long term goal of extending the existing serial interface to support SPI/I2C.
The text was updated successfully, but these errors were encountered: