So, I went back to the original Frankenprinter carriage, the one that I'd gotten from the H-P printer.
Along the way, I'd picked up some more gears. And to my surprise, I found something that I thought would work to provide higher precision to the Frankenprinter. That meant removing the stepper motor I'd put into it, the one with a brass pinion, to which I'd glued a washer so that it'd act as a flange to prevent the belt from slipping off). In a kids-don't-try-this-at-home maneuver, I found that a razor blade lightly tapped between the pinion and washer did the trick.
To my surprise and delight, I was successful in cobbling together a motor and gears with the right pitch size and diameter, and mounted that upside-down to drive the Frankenprinter carriage! Here's a picture with the new motor in place.
It turns out that I didn't have anything to mount the motor to, but haven't need to do that yet. Its pinion is now connected to the double white nylon gear, and the smaller part of the double gear connects to the belt. I am able to get away with just using cellophane tape to hold the motor in place at that end! With that in place, I was down to about an 11x multiple in resolution between the high-res scanner and the somewhat-high-res Frankenprinter.
So then I was faced with the technical challenge: how do you move two stepper motors at once to draw a straight(ish) line, while also handling different resolutions and acceleration factors for each?
Dual motor control
As it turns out, the work I'd done up to this point was all feeding into how the two-axis system would work. So let's get into the basics of two-axis control.
I didn't want to follow the path of the Frankenstein Laser Engraver. For that system, they re-flashed their Arduino to use GRBL so that the system could understand gCode. And while that's great, I only had the one Arduino, and didn't want to run the risk of being without it for other project purposes. That said, I did order up a second Arduino Uno R3 in case I wanted to go down that path.
That left me with rolling my own solution for X-Y motor control. The starting point was to imagine the simple case: 45-degree line, square pixels. In that world, you step once with each motor, and delay the appropriate time such that you don't go over the max pulses per second for either motor. Better, you do some kind of intelligent step delays such that acceleration is possible.
I knew that the scanner had much higher resolution than the printer carriage, so I wasn't dealing with the simple case. Most of the time, the X movements would have much higher step counts than the Y axis.
So instead, consider the opposite extreme case, 1000 steps in X, and only one step in Y. To handle that, I figured no matter what, I'd have to step 1000 times along X. It's when I hit the 500th step along X that I transition the Y axis by one step, so it's a rounding function.
In general, you have a system where you have a major axis running m steps, and a minor axis running n steps. No matter what, you have to step m times. If m and n are the same, then you step the same number of times along the minor axis. But generally that's not the case. So, instead you step each time along m, and check where the pen should be each time using a ratio. So if "i" is the number of steps traveled along the major axis and you're trying to move m steps, and j is the number you've travelled along the y axis and you're trying to move n steps along y, then you end up with something like this:
step along major axis
i = i+1
newj = round(i/m * n)
if newj != j, then step along minor axis
keep going until i = m and j = n
Because I am using shift registers for the motors, I also can send a single latch shift command to both, and get both axes to move in a single shot. So, supposedly if I could see this under a microscope, you would not see a step function of x and y movements. Rather, you'd see linear motion along x, and periodically a 45-degree line for both x and y.
There are other complexities to this: having to handle different directions and having to swap around all the variables when y is major and x is minor, but the concept remains the same.
To test the code, I set up a "testxy" input command that would move both carriages along a 45 degree line to print a diamond. Initial tests had no pen involved, but eventually I bodged together a pen, so here's what it looked like. It would draw the diamond pattern, then move off by a little bit, and then you could draw another one next to it for comparison.
testxy output - diamond pattern, offset 10x, 30y each iteration |
"What's all that other mess?", you might ask. Well first we have to understand the science behind my super-fancy pen carriage. It's a block of wood with a hole drilled through it, just big enough to grip onto the pen. The rubber bands hold it to the printer carriage, but loosely. If there's not enough rigidity to the system, the pen bends this way or that, and you end up with curvy lines.
Also, you might notice this piece on the image:
That's showing up because I did not have a flat surface underneath the drawing area. There are holes in the metal bed of the 4180, and so you're seeing the pen dipping down into the hole here. It is kind of cool, though. Reminds me of old vector graphics drawings of 3-dimensional functions.
The tape dispenser acted as a convenient weight to lift the pen a bit higher, but that put strain on the motor and belt. The main thing I was trying to do was to get the pen to the right height. Too much force on the pen meant that the pen tip would dig into the paper, and then that leverage would be enough to bend the rubber band... It was just bad. So eventually I ditched the weight, clamped the block of wood to the pen carriage, and adjusted the pen height by moving it a bit up or down within the hole in the block of wood.
Clamped pen carriage assembly. (Spoiler: this shows the star and circle operations described in later posts.) |
No comments:
Post a Comment