Motion Control (And Legos!)

A synchronized "unlimited"-axis motion-control system (and Lego Drawing Machines)!

This motion-control system is based heavily on (and contributes heavily to) 'commonCode'

The motion-control software I'd developed over the years was limited to two axes... I'd just bumped that up to "unlimited" (well, 256, anyhow) axes and needed some mechanics to test it on. In the old days I might've been able to come up with something fancier than legos, but when I built this I didn't even have a cut-off-wheel for my dremmel tool, and my Nibbler-tool had bit the dust. Never mind the fact that the majority of my stuff is in storage.

Enter Legos. Yep, Good-ol' Technics. And, actually, they're versatile enough that experimenting is a heck of a lot easier than doing stuff with metal.

(These photos taken long after the last time the systems were running, they've been packed away for some time, and have fallen apart quite a bit).

The first step was a 2-axis pulley/cable-driven XY-table; trying to piece-together my memory of how the mechanics worked in an old HP Plotter I'd had years prior. The motors were stationary, and both axes were controlled via pulleys and cables.

When I finally figured out how that was possible, I went through several design-iterations due to surprising amounts of torque caused by offset and stacked pulleys. The first design had so much drag in some directions that the motors actually stalled. After a redesign placing all the pulleys in a single plane drag was almost nil. In fact, the pulleys rode on the cables such that the moving axis barely even made contact with the gliders. It was almost as though it was floating (and moving!) in mid-air. (And now I'm half-tempted to rebuild it such that the axis *does* float on nothing but the cables, just to see it in action).

I managed to extend it to a third-axis (three stationary motors, and a bunch of pulleys and cables). Aside from backlash from the legos, it actually worked quite well. Extending it to four-axes was going to be difficult, though, as I'd started running out of space to build in--nevermind running out of legos--and couldn't really figure out what to do with a fourth-axis in this system. (Motors were attached to the left).

The next step, toward four axes, was inspired by something I'd seen on the web years prior, a two-axis hanging drawing machine. The two axes are controlled by stationary motors at the top corners pulling two cables to varying lengths. The pen, or whatever, is held where these two cables meet, creating a triangle between the two motors and the pen. So, X/Y motion actually requires a bit of trigonometry, in this case.

The motors are DC gearless motors with quadrature encoders ("DC Servo-motors" but *not* RC-Servos). My original 2-axis motion-control system was based on an ATmega8515, with HP/Agilent HCTL-2000 quadrature decoder chips, and the National Semiconductor LMD18200 H-Bridge chip. Its circuit-design was based on that of a friend's, porting his design from an 8051-series uC. The software was/is entirely my own and has come from quite a bit of wheel-reinventing over the years. This circuit/software was ported to the ATmega644 for later projects, and can be seen here as the green PCB. A third axis was added to the same system. The fourth-axis (the brown PCB) was my multi-million-dollar money-making venture... (or yahknow, to be submitted to the open-hardware crowd for CNC machines and whatnot). It's an entirely self-contained system for DC-motors with quadrature encoders, based on the ATtiny861, 'cause that's what I had lying around. The interface is SPI (though could easily be modified to RS-232, I2C, etc. Or even a simple "step" and "direction" TTL interface to match many stepper-motor drivers).

The "single-axis-holder", as I called it, does what it says... if a load is applied to the motor, it counteracts that load with the necessary power to hold its position (within a few encoder-counts). In the case of the drawing-system, you can imagine quite a bit of weirdly-varying loading. As the pen-carriage varies in distance from the motor, so varies the torque on the motor caused by the weight of the carriage. As the pen-carriage is moved upwards, the load increases dramatically; the two axes essentially fight each other to pull it higher. Other odd-loading includes bouncing as the wheels rolled along heavy and highly-wrinkled paper, extension and retraction of the pen-pressure and pen-select cables/weights (described below), cables slipping axially in the driving-pulleys, etc. Of course, the motor-mounted encoders couldn't compensate for keeping the pen-carriage in a perfect position if the cables slipped; at least I was sure that the motors themselves were positioned where I'd intended.

The one-axis-holder is supplied with a +/- change-in-position... Thus, smaller and more frequent changes lead to smooth motion. (I usually send *and verify* each step, which results in about 30,000 steps per second, maximum. With a 512-slot encoder, that's quite a few revolutions-per-second.). It also replies back to the "host" whether it has reached (or been pulled away from) its destination. The ATmega644 was responsible for sending these position-change-commands to the ATtiny861, and did-so in such a way that if any axis was somehow slowed due to loading, it would slow the other axes as well, in order to maintain the desired motion-path. Also, it handled ramping the speeds for each motor/motion.

This system worked surprisingly well, and as another means to test the multi-axis synchronization of my software, I threw in a couple other stationary-motors and pulleys (in addition to the two necessary for positioning). These motors generally moved synchronously with the positioning-motors, but when extended beyond that positioning were used to select one of three pens and apply pressure on the pen against the vertical surface.

Thus, the pen-selection and pressure-application "carriage" had two axes, but contained no electronics and no motors.

As desribed before, the cables/pulleys for Pen-Selection and Pen-Pressure were driven by stationary motors at the top. Weights were attached to the ends of the cables to pull the cable down tight. Pen-related cables/weights were not reassembled for this picture. The two beer-bottles were originally used for this purpose, but their moving with respect to the carriage caused the carriage to tilt a bit. They'd since been repurposed as stationary ballast, to keep the carriage horizontal. The three pens can be seen in the system, red, blue, and black.

Here's a photo of something drawn by the hanging system (from a photo of a friend of mine):

The actual algorithm for converting a grayscale image into something drawable with this system is pretty simple... the software takes an average of, say, ten pixels in a column, determines the darkness. The darkness-level is thrown into a sine-function, such that the pen is essentially always drawing a continuous sine-wave, whose frequency increases with the darkness. E.G. Something like:

for(y=0; y<image-height; y+=10)

{

for(x=0; x<image-width; x++)

{

intensity = 0;

for(yOffset=0; yOffset<10; yOffset++)

intensity += imagePixelValue(x, y+yOffset);

thisPhaseIncrement = (2550-intensity)*PI/2550;

phase += thisPhaseIncrement;

verticalPenPosition = 5*sin(phase)+5;

horizontalPenPosition = x;

}

}

(Heh, is this "Frequency Modulation" as in FM radio?)

Ultimately, I'd intended to do CMY imaging with three pens, but ran out of steam... The actual drawn image looks somewhat different than the processed-image as shown on a computer screen, due to pen-width vs. pixel-width and whatnot... Was a lot of trial-and-error before I could figure out what kinds of images actually draw well. Throwing in three-colors would've been that much more difficult (and that much slower to draw! Each 1ft x 1ft drawing took about 2 hours so as not to rip apart my legos and to deal with momentum of the pen-carriage, beer bottles, etc.).

Some other interesting effects: As the cables were wound-up on the pulleys, the actual diameter of the pulley, as seen by the cable, varied. This effect was actually dramatically visible as a concave "trapezoidal" image, until I added some math to compensate, which worked surprisingly well. Also there were occasions where the system wouldn't wind-up consistently, E.G. the cable might cross-over from one side of the driving-pulley to the other. Hey, we're working with legos, here!

Some "Trapezoidal" and cable-wind-up repeatability experiments. Also interlocking doughnuts (which is quite fun to watch come together, as the squares are drawn somewhat randomly) a friend gave me as an HPGL file to test out the pen-plotters he gave me long long ago (Yes, this system can handle basic HPGL commands, including text). The "trapezoid" outline was supposed to be rectangular, before the effect was compensated-for mathematically:

2019:

I've thought many times of revisiting this system, possibly mounting it on the side of my van and fitting it with white-board pens. A major difficulty in doing that is also a perfect challenge for my motion-control software: balasts and weights won't likely handle well at highway speeds. Instead, maybe, add four more motors(!) to keep the cables tight. Doing-so would also make the system insensitive to gravity, so could work horizontally, etc. Obviously eight motors for a 2.5-ish-axis system is a bit ridiculous, but the point is less about the system and more about the software. Synchronizing those motors would be an interesting challenge, and would also allow for a much faster drawing.

Further still, I've since developed libraries/plugins/"_commonCode" for many other servo-systems including (TODO: links!):

* cheap "hobby motors" with surprising positioning precision (fractional degrees!)

* various (and weird) motor-driver/power-amplifier circuits (Speaker amplifiers! controllers meant to interface to a uC-bus, PWM vs PDM...)

* Accurately Squeezing 768+ distinct steps from a 48-slot encoder-disk removed from a computer mouse "anaQuad"

* Microstepped stepper-control from floppy drives' circuitry

The list goes on (check out my hackaday.io page... 'esot.eric').

So, it might also be interesting to use a different servo-setup for each axis.

One of the many "someday maybes!"

--------------