I wanted to do something special for this year’s office xmas party. Several people were playing with LEDs and it got me thinking about different ways to display an image. I quite liked the idea of a retro look and feel using electromechanical elements, but didn’t want to just replicate one of the more popular methods like flip discs. I thought about ways in which a colour could be revealed and eventually came up with a way using rotation to move one piece in front of another.
A complete pixel (printed in white) without the outer casing is shown here. The rotation from the motor is transmitted via the nails, which allow for the rest of the mechanism to slide, to the pixel element. This is attached to the guide via a screw thread which causes the pixel to move forwards and backwards as it is rotated. The vanes at the front of the pixel insert move in between vanes in the case which hide the pixel insert when the pixel is off and reveal it when it is rotated to the on position.
Note that the pixel can occupy intermediate positions for a partial showing of the coloured element. This allows for a sort of halftoned effect for displaying greyscale images.
By far the longest phase of the project was physically manufacturing the components. Each pixel consists of seven 3D printed components, one servo motor and two nails. That comes to 448 3D printed components, 64 servo motors and 128 nails when scaled up to an 8x8 grid.
I printed the large components (outer case, the guide at the back of the case, and the pixel insert) on an Original Prusa i3 MK2S, and the four small components (motor bracket, servo arm adapter, and the two parts of the nail mechanism) on a Creality CR-10. This came to over two weeks of solid 3D printing time, not counting false starts, failed prints and spares.
Many of the pieces needed a small bit of manual finishing to ensure that they fitted together accurately and that the screw threads operated smoothly. Apart from the motor, which is screwed in to the bracket, and the nails which are self explanatory, everything is a push fit.
The motor arm is fitted as close as possible to horizontally while the motor is receiving a 1500us pulse.
It turned out that the easiest way to put this all together was to fit all of the parts together except the case, and then insert the whole assembly carefully into the case. The cases themselves slot together to make the shape of the grid, although it’s not quite strong enough to support itself without some flexing so I used a couple of monitor stands as external support.
I was expecting to have to design some electronics to drive 64 servos, but then I found the Pololu Mini Maestro 24 which is capable of directly controlling 24 servos, and can be daisy-chained. I used three of these boards, and connected one of them via USB to a Raspberry Pi. Wiring up the 64 servos took some time, but not nearly as much time as hand-finishing the 3D printed parts, screwing in motors, banging in nails and pushing those all together.
Some of the parts are a bit fragile, so it was useful to have spares.
The whole thing is powered by three powerful 5 volt power supplies, each capable of supplying 26 amps. I chose these because they should be able to handle the stall current of all 24 servos on one controller board without shutting down and restarting. That said, I’m pretty sure the PCB traces on the servo control boards wouldn’t be able to handle that kind of current for long. The average current is considerably lower, so I don’t expect any thermal issues in practice.
There’s no point in building all of this hardware without something to drive it. I found a Python library for talking to the Maestro family of boards, so decided to write the software in Python. There’s not an awful lot to it - I used PIL to open image files, converted them to greyscale and read out the pixels to drive into the servo motors. There’s a mapping between grid location, servo controller and output number, along with optional calibration which I didn’t have time to use, but will make the display look even better when it’s done properly.
The software just runs through a list of images (which can be run from a script to create a loop), and if any of the images are animations (such as animated gifs) then it will display each frame sequentially with a short delay. Animation loops aren’t implemented so far. Note that the display is capable of greyscale, not just on or off.
No display of this kind would be complete without a scrolltext. So I wrote another script to generate a scrolltext as an 8x8 animated gif. I used this BBC Micro font for a suitably retro feel.
The 3D printing finally finished just hours before the party, so after the final bits of assembly I packed up the device and transported it to the office.
This is what it looks like in operation:
And this is what you see if you look behind it while it’s running: