Friday, 31 December 2010

Frequency limit

I currently do my infill on Mendel at 36mm/s. The machine can go faster but the extruder flow rate maxes out at about 40mm/s when extruding ABS at 0.6mm, so 36 is a good safety margin for reliability and quality.

Although the speed is limited there is no real limit on how fast it can change direction. Suppose you make something 2.4mm wide with 0.5mm filament. E.g. a Mendel spring: -

Each wall will be 0.6mm wide leaving a 1.2mm gap in the middle. That gets filled with a zigzag infill where the head moves to within 0.3mm of each wall, so the head moves about 0.6mm on each stroke. At 36mm/s that makes 30 complete oscillations every second. 30Hz is a pretty high frequency for a mechanical system!

What actually happens is my y-axis starts to resonate. Over a few cycles the amplitude of the oscillation builds up and the infill overshoots the outline leaving a serrated edge.

The torque of a stepper motor is zero at rest and increases as it is displaced, so in that respect it behaves like a spring. That springiness together with the inertia of the rotor gives a resonance at hundreds of Hertz, known as mid band resonance. When the load is rigidly coupled, as in this case, the mass of the load brings the resonant frequency down.

As I don't get any missed steps I think the springiness might actually be in the belt rather than the motor. Timing belts have metal cables in them so that they don't stretch, but that makes them stiff, so they don't like to bend round a tight radius. That means the belt has some springiness being pulled round the pulley. A bigger pulley would be better but that would reduce the effective stiffness of the motor, so might actually make things worse. A lighter bed would be good but I haven't found a way to ensure it is flat without going to 6mm tooling plate.

I fixed the problem in software by slowing down the infill that has a high frequency content. I examine each infill path, one axis at a time, and convert it into a list of lengths between changes in direction. I then find the shortest wavelength over three cycles (less than three cycles is not long enough for the resonance to build up). I do this for X and Y directions and save the shortest of the two wavelengths. When I extrude the path I work out the frequency from the pre-calculated wavelength and the desired speed. I then compare that with a limit for each machine and reduce the speed if the frequency limit would be exceeded. I could have a separate frequency limit for each axis but I don't like the idea that the orientation of an object affects how it builds, so I pick the worst axis when deciding the limit.

I set the frequency limit to 20 Hz on my Mendel and 16 Hz on HydraRaptor. HydraRaptor does not show the overshoot problem, but it makes horrible growling noises and shakes the house. The machines make more interesting noises now because each infill run that hits the limit is extruded at an arbitrary lower speed. The overshoot is completely cured.

The builds are a bit slower and in some cases a long infill path will be slowed down by a short section that is high frequency, often a section between a hole and the outline. A more complicated solution would be to isolate the high frequency section and extrude the rest of the path at full speed.


  1. It sounds like you're doing this by modifying gcode while executing it, but this would make a great skeinforge plugin.

  2. I read all the gcode before I start printing and convert it into a Python data structure. From then on there is no gcode involved.

    It could be a done as an SF plug-in but would only work on machines with stepper extruders.

    I prefer to keep slicing and machine control as two separate programs and g-code is both a very poor way to represent slices and also a very poor format for sending to a machine.

  3. I don't particularly disagree, but with your toolchain closed source, doing it in gcode is the only way anyone else will be able to try it.

  4. Ya it would be awesome if we could at least see your code so someone could turn it into something everyone can use. But if its just sitting on your hard drive then its doing very little good to the community.

  5. @beak90 - Im sure at some point in the future nophead will release some of his own software back into the community. Lets be fair Nophead does contribute a lot already....why not wait for a more polished python program whilst he is "on a mission" with code updates. TBH I would happily pay for such a thing if it helped my cause!!

  6. @printbot3d fair enough. But he has been at it for a long time so some kind of information on the software side would help the community a lot.

  7. Most of us use SF and G-code or some other open source slicer...Nophead has developed his own code to work in conjunction with SF but he does not use G-code to control his printers so you would no doubt need his technology on the electronics too.

  8. nophead--i wrote a much less sophisticated algorithm to accomplish the same thing, but without actually pulling out my physics book. yours likely performs better. if i understood it a bit more, I'd be eager to program it into Sprinter or Marlin.

    sprinter computes a theoretic move time for each move. I ask, how long does each axis need to be stationary before it's allowed to move again (IF and ONLY if there is a direction change)? this value is certainly a factor move speed, weight, bed rigidity, etc, but acts as a quick and sloppy way to keep me from skipping steps!

    With that value, i ask, how long did it take the last move to run? if the previous move took LESS time than my minimum wait time, i pause the extruder for difference between these two values. Simple, right?

    I feel like this issue is pretty important. someone tried to put your logic into Marlin, but looks like didn't finish! Doesn't compile :(

  9. If you simply stop and wait I think that will lead to blobs. I slow the whole run of infill down. That can lead to a slow layer if a small bit of infill in a thin gap is connected to a larger area. I plan to do a binary chop to find the bit that needs to be slow and separate it from the rest. Unlike Marlin, I always extrude each filament run at a constant speed.

    The other difference is that I look for multiple fast changes in direction because resonance takes some time to build up.

    These things are much easier to do in the host in a high level language than they are in firmware.

  10. Hi nophead:

    i understand your point.

    However, we are also talking about delays in millisecond scale. hypothetical: if your 'oozerate' is 10mm/1min, volumetrically (real word?) we're we'd drip 0.006 cubic mm of goop during a delay, assuming .35mm nozzle/100 ms delay/no density change or swell. That's a blob I can deal with! also, i feel like this is step-skip prevention and hardware protection, not just print quality improvement. in that regard, i felt it should be part of f/w, vs. sw.

    regardless, for the sake of print quality, I'm still with ya. Look forward to seeing some videos sometime of it in action!

    Thanks for sharing your findings!

  11. If you stop without reversing the initial ooze rate is the same as the extrusion speed and decays relatively slowly.

    If you are getting missed steps is would seem your acceleration is too high for the torque of your motors.

    There is no reason why any of this needs to be in firmware. Gcode interpretation, path planning, acceleration, etc. are much easier to do on the host.

  12. Sounds pretty smart.

    Just one thing I could suggest, is that if you know that your print will make lots of small movements, why not increase the nmber of internal shell walls, as doing that should make the movement smoother?

  13. This is only for the infill zig-zags. More shells will increase the likelihood of short infill lines. The part shown does not work very well with two shells. The inner shell breaks into several loops and leaves big gaps.

    I tend not to use multiple shells with Skeinforge because it doesn't work properly. When there isn't room for the extra shell it just leaves a gap instead of falling back to filling it with infill. The same when the extra shell means there isn't room for any infill inside it. In that case it should also lose the extra shell and use infill.

  14. Why not just reduce acceleration of y axis?

  15. Because that reduces the print quality as my extruder flow rate is constant, so slow acceleration leads to too much plastic at the line ends. It would also slow down all prints, whereas it is only short zigzags that cause resonance.

  16. Ahh, perfect! Now I understand why I have this blobs at the beginning of my lines. So I have to increase acceleration again and reduce frequence. Thanks.

  17. Just read your blog here about minimum bed weight.
    I use a heated print bed that is pretty light. glass on .25" thick aluminum skinned, aluminum honeycomb core composite panel. I use a fiberglass and aluminum honeycomb panel as the lower panel on the prusa-mendel. I have worked in aerospace for decades and unique scrap is sometimes available.