If you've ever rode the Link Light Rail in Seattle to the airport, you may have glanced out of the window while traveling through a tunnel and seen playing cards illuminated on the walls. These images are not made from two dimensional screens. Each display is just a row of lights that changes rapidly as the train drives by, giving the illusion of a two-dimensional picture.
The University Street station also has rows of lights blinking on the walls on the mezzanine floor. I always point out the artwork whenever I walk through the station with someone. At first glance the displays just appear to be red lines, but if you move your eyes rapidly from side to side, there are images hidden in how the lights blink.
That was the inspiration for the Pendulum Clock.
Hint: Stare at the cord; don't follow the pendulum with your eyes.
You might not see it at first, but it is showing an analog clock face that reads 2:40. Usually it takes a couple swings to see the picture. Once you see it, it becomes very easy to read the time.
The Pendulum Clock has a row of 64 white LEDs that change based on the position of the pendulum. I've used it to display an analog clock face, but it can be used to display any 2D image. The motion of the clock is not powered; you have to manually push the pendulum to one side to start it moving.
It's powered by a simple Arduino Uno, a DS1307 RTC for keeping time, a MAX7219 LED controller, and a bad ass rotary encoder. The case is a Hammond box, which fit all of the components with just the right amount of room. The face is a 4"x24" piece of basswood.
Finished product
I knew I wanted to display a 2D image using a 1D set of LEDs. I had a few different designs laid out: a rotating set of LEDs driven by a motor, or a row of LEDs that would move laterally. I finally decided on the pendulum because motor-driven displays have been done before, and I wanted to make something new.
There were a couple challenges here that thankfully were easy to overcome. At first I looked at NeoPixels for the line of LEDs. This probably wouldn't work because NeoPixels introduce a small delay as the pixel is propagated down the line. I didn't know if the MAX7219 controller would be fast enough to drive the LEDs; if there was too much of a delay, the image would be skewed or mangled. I started with the MAX7219. I also bought some shift registers just in case; the shift registers would be fast enough but would require more connections.
First I created the LED display. Prefabricated 8x8 LED matrices were easy to find, but I could not find 1x64 matrices that used the digit/segment wiring scheme that the MAX7219 expects. With the MAX7219 powering a numeric display, a set of LEDs in one digit share a common cathode, and the Nth segment of every digit share a common anode. For the 8x8 matrix, each row shares a common cathode and each column shares a common anode. For my 1x64 matrix, every 8 LEDs share a cathode, while every N%8 LED shares a common anode.
To create the rows, I purchased three Breadboard-style PCBs from Adafruit and cut them in half down the center. I soldered an LED to every two rows. The rails running down the board would be used for cathodes. I cut the rails at every 16th row and soldered the cathodes to the rails.
Connected the first few anodes
All of the anodes connected and Kragled to the wooden clock face
After all of the LEDs were strung together, I used some more magnet wire to connect the digits and segments to the MAX7219 breakout. I hooked up an Arduino, found some 8x8 example code, and got a pixel to bounce back and forth on the display. Sweet!
Now I needed a way to find the position of the pendulum. If I had used a stepper motor, this would have been trivial. I was thinking of breaking IR beams at the top of the swing, and interpolating the position through the middle. This would become less reliable as the pendulum slowed down. I discovered that a rotary encoder would be perfect for this.
Mounting the rotary encoder to the enclosure.
The encoder, Arduino and RTC mounted in the enclosure.
While the spec says the maximum load is 3N, the encoder seems to support the pendulum just fine with no noticeable resistance. The encoder came with a plastic nut that allowed me to attach a bolt for the clock face.
It's a tight fit, but it works!
You'll notice that the clock draws a perfect circle. In the arduino sketch, I have routines that draw the clock face and clock hands on the cartesian plane. Every time a pixel is set on the cartesian plane, it is transformed to polar coordinates and stored in a 2D array. As the pendulum rotates, the encoder triggers interrupts on the Arduino and updates a counter. The loop() routine updates the display based on the counter position, which is one dimension in the array. When the pendulum stops moving, the array is refreshed with the latest time, and the home position is recalibrated.
Anyway, I hope you enjoyed this project! Drop me a message if you'd like any more information.
this is amazing. thanks for the post, i may try to build one on my own. My expertise in building things of this nature is minimal, but your instructions are very clear. i may ask you questions along the way once i have time to devote to this (which may not be for a few months).
ReplyDeletecheers.