A Light Machine: Drawing in Lights
When I heard about the project, I knew I wanted to do something that could draw programatically. I had considered doing something with multiple arms that could draw arbitrarily, but implementing full inverse kinematics seemed like a stretch. Instead, I focused on how I could use fewer parts to move in more dimensions and decided that using an LED to draw using light and long exposures would be an interesting task to tackle. I figured it'd be more software heavy as the device would need to know the degree of its rotation and programmatically determine the colors to draw.
Here's what I had in mind:
The first challenge was determining the position of the stepper motor. I observed that the stepper motor moved at a more or less fixed rate, so I took a stopwatch and measured the time it took to rotate 360 degrees. I let it do so a couple times so that I could get a reasonable estimate of the period within tens of milliseconds:
Looked like it was a fairly consistent 1230 milliseconds give or take. I figured I'd work in degrees since there was no need to introduce irrationality, so I created some constants in code to describe the number of degrees traversed each millisecond. Coupled with some well placed calls to millis(), I was able to determine at each step a reasonable approximation of the motor's position. Given that information, I could then figure out what color the LED ought to display. Of course, all of this was better served with a non-blocking loop for the stepper so that the LEDs could change at their own rate.
I made an attachment for the tricolor LED with some cardboard that would hold it in place. Since the project was meant to be used in the dark, the aesthetic of the drawn object was much more important than that of the drawer itself.
Mounting the thing introduced a problem though: the stepper motor had very little torque, so the rotational period was lengthened. Through a bit of trial and error, I determined that the loaded period was roughly 1.75 times the unloaded period and proceeded to add a multiplication in my code to account for this. Since the rest of the code was agnostic to the value of the period or automatically rederived values based on the period constant, this was the only change I had to make to get it working again.
The next problem was that of the wires. The wires were a bit long and prone to tangling, so I created a base to hold the stepper that would allow the wires to curl around. It also had the added bonus of holding the stepper in place relative to the table by the weight of the stepper alone. The base was a huge usability win and allowed the cables to be routed more intelligently.
With that, it was time to turn off the lights and set it running:
I didn't have a camera capable of long exposure, but I was able to take a video and post-process it using Photoshop to simulate a long exposure. To do this, I imported the video as layers, creating one Photoshop layer for every frame. Then, I made all layers visible, turned down their opacity, and set the blending mode to one of the lightening options and tweaked the opacity until the colors showed without saturating the image. A couple contrast adjustments yielded an image that reasonably approximates what a long exposure would have produced, showing a rainbow colored glowing ring that was reasonably close to my initial idea:
Comments