Introduction: PendoLux

I have always been fascinated by the precision mechanics present in mechanical hard drives and every time I have a broken one I try to find a use for it.
This, together with the fact that I think it's a shame to throw away such a precious piece of technology, made me think of this project.

The main idea of the project is to use the mechanics related to the movement of the magnetic head of an old hard disk to create a display showing the current time (it can be easily changed to display whatever you want).

By replacing the Hard disk magnetic head with a bar of leds and by turning on the leds at the right time it is possible, using the persistence of the human eye, to form an image. For the led bar I used one equipped with the well known LED WS2812B that gives the possibility to control the leds with only one pin (besides the power supply of course).

It should be noted that the flickering that you see in the video is not real. It is is probably due to interference between the scan frequency of my camera and the refresh rate of the display. Even the noise isn't as noticeable as it sounds on the video.

I'd also like to point out that this is my first instructable, please forgive my inexperience.


  • A mechanical hard drive
  • An arduino board (e.g. Arduino pro mini or WAVGAT)
  • Two PMOS, e.g. AO3401 ( or any PMOS that can be driven at logic levels
  • Two NMOS, e.g. AO3406 ( or any NMOS that can be driven at logic levels
  • A real time clock module operating at 5 volt (e.g. RTC Mini module
  • Two 100 Ohm resistors
  • Two 4700 Ohm resistors
  • One capacitor (>220uf, > 10 volt)
  • Two M2.5 screws and nuts

Step 1: Obtaining a Mechanical Hard Disk Drive

First you need to get an old hard drive.

I personally used the one in the picture. Unfortunately the the mechanical part varies a lot from one model to another. So you will have to adapt the design to what you find once opened.

Step 2: Disassemble the Hard Disk

Once found the victim, open it and get rid of the discs, the brushless motor that makes the discs pin (very useful for other projects, for example I created a small grinding wheel with one of these, but that's another story :-)) and the circuit board.

You should come up with something similar to this. Of course at this stage you'll still have the original head (unfortunately I don't have a picture with the original head).

Step 3: Modify the Head

You will then have to remove the head and replace it with a support that hosts the led bar. In my case I 3D-printed the support. The STL file is available here. However, as said before, it is very dependent on the type of hard disk you will find. In mine there was already a hole in the head support, ideal to anchor the printed part with a first screw (diameter : 2.5mm). I then added a second screw to prevent the printed part from rotating.

Step 4: Solder the Led Strip to the Head Contacts

In order to operate, three wires must be connected to the led strip : Vcc (5 volts), GND and a data wire.

One of the most delicate parts of the project is the LED bar connection as the bars is continuously moving and vibrating stressing a lot the connections. For this reason I decided to use the original flat cable that brings the signals to the head. So I removed the integrated circuit present on the head and I connected the cables coming from led bar to three points of the flat circuit connected to the connector that was attached to the electronic board of the hard disk. I hope the pictures clarify this step.

Step 5: ​Remove Any End Stops on the Magnet Holder.

To slightly increase the amplitude of the movement of the head I have removed the end stops on the magnet holder.

Step 6: Add a Spring

In order for the head to return to the central position I added a spring connected to the central body of the hard disk and to the moving part of the head..

I anchored the spring with a small wire to a pre-existing screw. The spring is responsible for a lot of the noise produced. I think there's room for improvement in the return mechanism. Any good idea is more then welcome ;-)

Step 7: Using Magnets As Alternative to the Spring (much Better...)

As an alternative to the spring a better solution is to install a magnet attached to the coil and two magnets on a support attached to the hard disk mounted in such a way as to repel the magnet attached to the coil. See the pictures.

I used small magnets having a diameter of 5 mm and a depth of 3 mm, available on aliexpress (

The magnets on the stand are mounted on two small 2.5mm screws (glued) so you can fine-tune the distance and lock the desired position with the nuts.

This improves a lot the noise and reliability over time. I have included the stl files, the parts are quite small and not very easy to print.

Step 8: The Electronics...

The electronics is pretty simple, we need :

  • A microprocessor board, for example an arduino-pro mini (I used a WAVGAT clone but any other board should work).
  • A driving stage to drive the hard disk coil without overloading the microprocessor. The stage is composed of two push-pull pairs formed respectively by a PMOS and an NMOS. There are no particular requirements as the currents involved are quite low. The only important thing is that the MOS switches to logical levels. In particular I used the AO3401 and AO3406 MOS in SOT23 that I had at hand.It is advisable to add a small resistance (for example 100 ohms) in series to the gate to avoid resonant effects and a pull-down resistor (e.g. 4.7K) to guarantee a low status when the microprocessor ports are still not configured. I have also included a picture of the mounted parts, an easy way of mounting SOT23 MOSs.
  • A way to keep track of the the time (I used a real time clock RTC tiny module, connected to the processor through I2C lines)
  • Obviously a strip led WS2812B
  • A generous electrolytic capacitor (>220uf) on the 5 volt line.

The block diagram should be quite clear enough.

Step 9: The Software

I'm certainly better at hardware than software so I apologize in advance for my poor coding style.

Lately I abandoned the arduino development system for platformIO that I find much more powerful. In any case the code should run without problems also on the arduino development system.

Please note that the file platformio.c is only needed if you use platformIO and, in this case, it should be renamed to platformio.ini. I had to rename it to .c because, for unknown reasons, it was not possible to upload a .ini file.


To generate the control signals for the coil I used the TIMER1 of the micro, programmed at a frequency of 32 Hz. In the code you will see that it starts at 75 Hz reaching slowly 32 Hz for implementing a smooth start. Each time the interrupt occurs the coils' signals are inverted thus generating the waveform at 16 Hz of the first figure, where the two channels represent the nodes of the coil.

TIMER2 is responsible for the column timing. It is programmed for operating at 2 KHz (period = 0.5us). Thus in a period of 62.5 us (1/16 Hz) we have 125 columns (=62.5/0.5). Timer 2 is initialized at "92" when timer 1 switches. This 92 ensures that the column count is not such that column is 0 in the middle of the scan. The column is then incremented at each TIMER2 interrupt, when the column reach 124 (max number of columns -1) it restarts from 0. So you can basically change the number of columns by varying the timing of TIMER2 and the 124 while the center phase is dependent from the 92.

All these "magic numbers" are hardware dependent and should be tuned to your specific hard disk and spring (depending from the span, the resonant frequency of the szstem and so on) but this explanation should give you a good starting point. Trial and error works fine :-)

Outputting data

The displaying is done in two passes, a first pass, let's say from left to right, and a second pass from right to left.

In the first pass displaying starts at column MINCOLUMN and stops at column MAXCOLUMN (see the #define in the source file).

In the second pass it starts at column MINCOLUMN+DELTA_RETURN and stops at column MAXCOLUMN+DELTA_RETURN.

When TIMER2 triggers, it sets a flag: newcolumn.

In the main loop, newcolumn is tested, when it is true, it is reset and, if the column range correspond to the range where we want to show something, the array RGB is filled correspondingly (by the functions copyString, copyLetters, copySeparators) and another flag : newdata is set.

In the Timer 2 interrupt service routine, when newdata is true it is reset and the RGB array is forwarded to the Led pin by the function RGB_update_7. In this way the output data are synchronous to the movement and not dependent from the calculation you do for deciding which led to turn on.

I couldn't use a standard library (as fastled or neopixel) for driving the WS2812B because the intensive use of interrupt is not compatible with such libraries. Instead I used an unorthodox "direct driving technique" using the method explained by Kevin Darrah in this video, thank you Kevin !

In the second figure you can see the coil waveform and the data packet to the led, synchronous to the TIMER2.

The third figure illustrates a detail of the data driving the led.

Generating data

Data are generated starting from the time values read from the RTC via the I2C bus. Time is updated every 500ms. The big array Number includes the representation (5*7) of each number. According to the current column, the column of the number, depending from the current time, is copied to the array RGB. I think that the source file is quiet self-explanatory here.


When I started the project I thought to display the whole time in one pass. Unfortunately the angle available is quite narrow so I had to display only a section of the time and shift periodically to the left and to the right the displayed time (see the video).

The variable xoffset contains the shift value and is alternatively incremented or decremented according to the status of the flag offsetincreasing.

Step 10: Final Comments and Possible Improvements

The power consumption is about 2 Watts (400 ma at 5 Volt).

The project is not finished yet, the implementation of the electronic part is still on a breadboard and I would still like to solve small problems.

The ticking noise is more evident with the spring, almost solved with the magnets.

A simple way to cope with the noise could be to turn the clock on only once in a while, like every ten minutes for few seconds and then switch it off.

It would also be nice to cut the support part of the hard disk (see the picture) so that the LED bar has nothing behind it. I would like also to build a case and mount it vertically resulting in the number written in transparency.

Step 11: The Operating PendoLux

Lighting Challenge

Participated in the
Lighting Challenge