8051 Microcontroller Propeller Clock
8051 Microcontroller Propeller Clock
SHAI SCHECHTER
SUPERVISOR: DR. ERNIE HILL
APRIL 2013
SHAI SCHECHTER
SUPERVISOR: DR. ERNIE HILL
ABSTRACT
This report documents the design, implementation and testing process for a “persistence of vision” display:
a system in which LEDs move rapidly to create the illusion of a much higher resolution display.
The report details the design and build process for the hardware, electronics and software of the system,
and the integration of these subsystems into a finished product. The hardware incorporates a Perspex
structure and high-speed brushless motor; the electronics aspect involved designing and manufacturing a
printed circuit board consisting of 64 RGB LEDs; software was then written to address and control these
LEDs from an Arduino microprocessor. Several programs were written for computing/displaying different
Overall, the project was a success. Minor issues were identified in testing and subsequently fixed: these are
discussed within the report. Potential improvements to the system (namely wireless connectivity and a
SHAI SCHECHTER
SUPERVISOR: DR. ERNIE HILL
ACKNOWLEDGEMENTS
Thank you to Dr. Ernie Hill for supervising the project and for your valuable help, contributions and
guidance throughout.
Thank you to Dave Bowden, Dr. Jim Garside, Jeff Pepper and Ian Stutt for your valuable help during the final
stages of the project, and to Dave Clark for his brilliant handiwork—and in going above and beyond in
Thank you also to Malcolm Bailey, Vincent James and Dr. Ognjen Marjanovic of the School of Electrical and
Electronic Engineering for your valuable help with delving into the unknown world of printed circuit boards.
Finally a huge thank you to all my friends for your encouragement with the project and for making my four
years at uni as fantastic as they were, and to Mum & Aba, Orli & co., Vity and Yali for your incredible
support and encouragement throughout this project, and in everything else I do. I couldn’t ask for more.
TABLE OF CONTENTS
1. Introduction............................................................................................................ 1
1.1. Persistence of Vision.............................................................................................................. 1
1.2. Background Review and Design Considerations...................................................................... 1
↳ Resolution and Colours.................................................................................................... 2
1.3. Risk Assessment..................................................................................................................... 3
2. Project Aims and Objectives (Specification)............................................................ 4
2.1. Practical Uses......................................................................................................................... 5
3. Hardware Design, Implementation and Testing....................................................... 6
3.1. Mechanical / Structural Design............................................................................................... 6
3.2. Motor and Electronic Speed Controller.................................................................................. 10
↳ Testing........................................................................................................................... 11
3.3. Transferring Power into Rotating Body.................................................................................. 11
↳ Testing........................................................................................................................... 12
3.4. Display Microprocessor......................................................................................................... 12
↳ Choice of Microprocessor............................................................................................... 12
↳ Microprocessor Location................................................................................................. 13
3.5. LEDs and LED Drivers............................................................................................................. 13
↳ Dedicated LED Driver ICs................................................................................................ 14
↳ TLC5940 Arduino Library................................................................................................. 14
3.6. Display Circuitry.................................................................................................................... 15
↳ Channel Selection (Demultiplexing)............................................................................... 15
↳ Current Requirements.................................................................................................... 17
↳ Circuit Schematic........................................................................................................... 17
↳ Circuit Board.................................................................................................................. 19
↳ Testing........................................................................................................................... 20
3.7. Image Stabilisation................................................................................................................ 21
3.8. Final Testing......................................................................................................................... 21
4. Software Design, Implementation and Testing....................................................... 23
4.1. Persistence of Vision Display Library..................................................................................... 23
↳ Optimising the Library.................................................................................................... 23
↳ Operating Speeds........................................................................................................... 24
↳ Library Usage................................................................................................................. 25
4.2. Image Conversion and Display.............................................................................................. 25
↳ Image Storage / Memory Capacity.................................................................................. 26
↳ Byte-Packing.................................................................................................................. 26
4.3. Text Display and Font Conversion......................................................................................... 27
↳ Custom Fonts................................................................................................................. 29
↳ Testing and Limitations.................................................................................................. 30
4.4. Double-Buffered Graphic Processing Library.......................................................................... 30
Persistence of vision (POV) refers to a phenomenon whereby the human retina retains an after-image of
anything it sees for a short time (approximately one twenty-fifth of a second). This phenomenon renders a
By taking advantage of this phenomenon, it should be possible to produce an electronic display that
appears to have a significantly higher resolution than its hardware would ordinarily dictate, by physically
and rapidly moving the display hardware in space and modifying the display output based on its current
physical position. If the display hardware is moved fast enough, the eye should perceive the visual output
from the hardware at multiple physical positions simultaneously, giving (for example) the perception of a
two- or three-dimensional display even though the physical hardware consists of just a one-dimensional
“wand” of LEDs. The aim of this project is to design and manufacture such a system.
There are many “persistence of vision displays” in existence, both commercial and non-commercial.
Appendix A shows a number of examples. These persistence of vision displays differ vastly in size, shape
and capabilities1 , but all share the ability to physically move a number of LEDs rapidly in physical space.
The configuration of LEDs, together with the axis of rotation, dictate the shape that the display will be, as
shown in Figures 2 to 4.
Figure 2: 2D oscillating display wand Figure 3: 2D rotating display wand Figure 4: 3D rotating display wand
1 It is, however, worth noting that no evidence could be found online of a three-dimensional POV display showing more than 8
colours. Producing such a system could therefore be an interesting option to explore.
are oscillated from side to side in order to produce a two-dimensional arc display. This would commonly be
used for displaying text, such as a digital clock [1]. In Figure 3, rotation is used rather than oscillation in
order to produce the perception of a circular display. This could be used to display text, images, video or
any other visual media. Figure 4 is an example of a three-dimensional POV display: a one-dimensional array
of LEDs are still used but these are rotated about an axis parallel to, rather than perpendicular to, the LEDs
in order to produce a cylindrical display (alternatively a sphere could be produced by curving the line of
LEDs). A three-dimensional display has the added benefit of being viewable from any direction around the
system.
The resolution of a POV display is partially dictated by the number of LEDs physically present in the system.
However, due to the persistence of vision phenomenon caused by physical movement of the LEDs, the
perceived resolution in the direction(s) of motion is much greater than the actual number of LEDs present.
For example, if a column of 50 LEDs arranged vertically were to be rapidly moved left and right in two-
dimensional space, and the output of these LEDs were changed 100 times between the left-most and right-
most points of movement (and the complete sweep from one side to the other were completed before the
after-image had disappeared from the retina), the effective (perceived) resolution of the display would be
100px by 50px rather than the 1px by 50px resolution that the system hardware would suggest. In other
words, the resolution in any directions of physical movement is dictated by the number of times the LED
Simple POV displays can use single-colour LEDs in order to produce their text, images or other media. This
has the advantage of being significantly easier to wire and program, while limiting the information/media
that can be displayed. At the other end of the spectrum, full-colour (RGB) LEDs are available with three
input channels in order to produce eight colours initially, but millions of colours when utilising techniques
such as pulse-width modulation (discussed in Hardware > LEDs and LED Drivers).
Any system that incorporates moving parts has risks involved, and it is vital to ascertain what these risks
could be in order to mitigate against them. The most obvious risk would be that any part mounted on the
rotating body could become disconnected from the system during acceleration or rotation and come into
• Care will be taken to ensure that all parts are secured tightly to the system.
• Rotation hardware will be tested thoroughly without any load (such as LEDs), before the load is
added and retested.
• The system should be designed so as to not rotate when initially powered on, to prevent accidental
rotation. Software and hardware should both be in place to ensure that some kind of intentional
input is required before the system is permitted to rotate at all.
• The system should accelerate to full speed gradually: it should take several seconds to reach full
speed. Additionally, during initial testing a user input should be required at several points during
acceleration before the system is permitted to accelerate further.
• In addition to all of these preventative measures, a transparent but strong protective screen should
be in place around the system in every direction during testing as a final layer of protection in the
event that any part does become detached from the system.
As well as this obvious risk, the typical risks associated with electrical laboratory work must be considered:
all necessary safety precautions should be taken when working with any high voltages, as well as when
The aim of this project will be to design and implement a “persistence of vision display”, as defined above.
The display will physically consist of a one- or two-dimensional array of LEDs, but these LEDs will be moved
rapidly in physical space in order to produce the illusion of a three-dimensional display when viewed from
any of a number of angles. This movement will be in a rotating, rather than oscillating, fashion, and should
be implemented using a motor. A microprocessor should be used to receive and/or compute images to be
displayed.
Power will need to be transferred into the rotating body in order to light the LEDs: a means to achieve this
will need to be considered. If the microprocessor is not mounted within the rotating portion of the system,
a means for transferring the LED data into the rotating body will also need to be considered. The system
should be capable of rotating safely at 24 revolutions per second (1440 RPM) in order to achieve a smooth
virtual image. The system display should, however, be capable of running independently of this revolution
speed: in other words, the system must have some means of determining its current speed in order that
The display should be capable of displaying text and low-resolution images such as shapes and cartoon
characters: in order to achieve this the perceived display resolution should be a minimum of 32px by 32px.
Ideally the resolution will be greater than this, but this will be dependent on a number of hardware
considerations which will be investigated during the course of the project. If time and software/hardware
considerations permit, the system could be extended in order to display photographs, animations, video,
and/or include interactivity such as basic games that respond to user input.
The system must be able to interface with a PC in order to receive images for display: this would ideally
take place over a wireless link and allow the system to receive images on-the-fly whilst rotating, but at a
minimum could just be achieved by a physical connection to a PC when the display is not moving.
The finished product could be used in the advertising industry, to display company logos, details or
animations in a novel way. Alternatively, the product could be used as an entertainment product in much
the same way as large television displays could be used at various entertainment events. Again, the novelty
of the device would be a key factor here, as well as the potentially reduced cost of the lower number of
LEDs required (although this would likely be offset by the additional hardware required in producing the
physical movement).
The main structure of the system will be manufactured using Perspex as it is both strong and light,
aesthetically pleasing, and the University has facilities to laser-cut the material in-house. The structure
must hold the rotating body firmly in place and allow it to spin with minimal friction: bearings housed
and connected by pulleys and a timing belt to the rotating axle (a 6mm screwed rod). The pulleys are at a
1:3 ratio to increase the torque from the motor. The motor is screwed to the base through elongated screw
holes: these can be used to perfect the distance between motor and axle to ensure sufficient tension of the
timing belt and prevent slipping. The axle is held in place by a bearing at the lower end, and by a
makeshift slip ring (described later in the chapter) at the upper end. A board consisting of the display LEDs
is mounted to this axle (offset several centimetres so as to draw a cylindrical display when the LEDs are
rotated about the axle by the motor). The LEDs are arranged vertically, rather than in an arc, which will
produce a cylindrical rather than spherical display when the motor spins. This is to allow for easier
mounting of the LEDs (and becomes essential if the LEDs are to be mounted on a printed circuit board, as
there was no easy access to flexible circuit boards for this purpose).
Further sketches were drawn to show the design in more details. These sketches also incorporated
The sketches were then used to produce a computerised three-dimensional model of the system (Figure 6).
Because of the availability of two heavy metal rods that could be incorporated into the base of the system,
the design was modified to incorporate these rods and move the motor below the Perspex base.
Theoretically this would have allowed for the entire system to be reduced in size as the motor could be
moved much closer to the axle without interfering with the rotating LEDs. However, since the long timing
belt had already been purchased, it was deemed best to leave the distance between the motor and axle
unmodified.
The 3D model was then converted to a file format suitable for laser-cutting from Perspex sheets (Figures 8
and 9), after which the system could be assembled. Initially the system was built without removing the
protective plastic from the Perspex (Figure 10), in order to ensure everything worked correctly without risk
of scratching the transparent Perspex. Once everything had been put together and deemed to be working,
the system was disassembled in order to remove these protective sheets before reassembly.
It was vitally important to ensure that the rotating body was as balanced as possible. This was achieved by
extending the rear of the rotating body (where the microprocessor could be mounted) away from the axle:
in hindsight the horizontal pieces of Perspex would have been made symmetrical to facilitate this, instead
of one vertical piece of Perspex being much closer to the axle than the other. Nevertheless, by utilising
metal extenders and frequently testing by placing the system on its side and seeing which half of the body
The remainder of this chapter describes the design, implementation and testing of various hardware and
Brushed DC motors are susceptible to increased friction/torque at higher speeds, such as the speed
required for this project. Brushless motors allow for correct behaviour at high speed but are often more
expensive than brushed equivalents, with some brushless motors costing hundreds of pounds. However,
brushless motors are commonly used for toy electronics (boats, helicopter propeller driving, etc) and are
therefore sold very cheaply by shops specialising in this field: a suitable brushless motor was found for just
£9.99 from a web site describing it as “ideal […] on a copter” [9]. The motor was rated at 1000kV (kV is
equivalent to RPM per volt applied with no load), which should be plenty for this project assuming the
rotating body can be kept light and low friction, as several volts can be applied to the motor from the
from an Arduino Uno microprocessor. Once wired up to the motor, bench power supply and Arduino, control
of the motor from the Arduino is accomplished using the standard Arduino Servo library.
Testing
The motor/ESC configuration was tested while at all times adhering to the Risk Assessment documented
earlier in this document: the motor was first rotated with no load applied, before integrating it into the rest
of the system and retesting. At each stage of testing, the ESC was first given its lowest possible input,
before gradually accelerating the motor to the full speed of 1440RPM required by the project. In practice,
testing of many motor speeds identified that the Perspex structure began to vibrate at speeds approaching
700RPM. A decision was therefore made to limit all testing to 660RPM until such time as this balancing
issue was resolved. This would still offer a visible persistence of vision effect, with just a small but rather
One aspect of the mechanical engineering that requires special consideration is the means of supplying
power to LEDs and LED circuitry. Since these components are part of a rotating medium, it is impossible to
supply outside power directly into these components (a straightforward wire pair would of course tangle
rapidly when the body rotates). Instead, a system is required that is able to maintain electrical connectivity
Such devices are available commercially, and are referred to as slip rings. Internally these may rely on
stationary graphite brushes pressing against a revolving ring; liquid mercury to maintain contact between a
stationary outer and a revolving inner portion; or a multitude of other mechanisms. However, these
commercial products are typically designed for use in large, expensive, high power systems and as such are
far too expensive for this project (the cheapest are not much cheaper than £100).
Self-made alternatives were therefore considered. A suggestion which arose early on in the design process
was to extract the carbon brushes from within a brushed DC motor, mount these onto the stationary body
of the system, and use these to press against metal rings around the top or bottom of the rotating axle (or
use the axle itself as the ground connection, requiring just one additional ring for the +5V connection). This
instead of making them from scratch. By mounting the headphone jack to the top of the rotating axle, and
lining it up with a headphone socket mounted in the horizontal Perspex bar across the top of the system,
power is able to be transferred into the rotating body even when it is rotating.
Since the friction between the jack and socket would be too great to allow the rotation speed required,
parts of the socket were removed and replaced by the carbon motor brushes mentioned previously. This
allowed the axle to spin with very little friction, whilst still maintaining contact with the stationary power
supply.
Testing
The “slip ring” was tested by mounted a 9V battery to the rotating body and attaching the anode and
cathode to the two slip ring wires. The voltage across these wires was then measured on an oscilloscope
from the outside of the system to ensure a consistent 9V reading when the motor was spinning. This
proved to be successful: a consistent 9V reading was measured (minor drops were observed during
acceleration, but these were not observed once the motor reached a constant speed).
Choice of Microprocessor
Three different microprocessor families were identified as potentially suitable for this project: the PIC,
Arduino and Raspberry Pi. Research into the pros and cons of each for this sort of project was largely
anecdotal and contradictory; it did, however, appear that the School of Computer Science had far more
experience with (and support for) the Arduino family. In particular, many Arduino Uno microprocessors
were available within the School itself which would allow for a lower total cost for the project if used. The
Arduino Uno has a 16 MHz processor, which should be fast enough to display at least rudimentary images
on the persistence of vision display. While it is true that the Raspberry Pi has greatly improved technical
specifications when compared to the Arduino, many of these enhanced capabilities are entirely unnecessary
for this project. The Raspberry Pi also weighs more than the Arduino Uno (45g [10] compared to 28g [11]),
which is important to note if the µPC is mounted within the rotating portion of the system as mass here
In the interest of keeping the rotating body as light as possible in order to allow for rapid rotation, it would
be sensible to investigate the feasibility of positioning the microprocessor in the base of the system and
passing data through the headphone-jack slip ring described in the previous subsection. Two issues arise,
however:
• Noise added to the signal passing through the slip ring may be unavoidable: a non-smooth power
connection is not a significant issue, especially if smoothed with a capacitor on the inside/receiving
end of the slip ring, but for a digital signal the noise could cause incorrect behaviour
• Multiple control signals will be required between the microprocessor and the LED display, not just a
simple data line. These would all need to be passed through the slip ring, which is simply not
feasible: the slip ring designed earlier allows for three signals including power and ground, and it is
unlikely that an alternative slip ring design allowing for multiple signals could be produced cheaply
and reliably.
For these reasons, the microprocessor will be mounted in the rotating body of the system and receive a 5V
supply through the slip ring in the same manner as the LEDs.
In order to address the red, green and blue channels of 64 RGB LEDs, (3 x 64 =)192 LED driving lines are
required. Connecting these lines directly to the µPC is of course impossible (a typical microprocessor used
in this sort of project provides just a fraction of the 192 digital outputs required here; the Arduino Uno
offers ~15), instead necessitating the inclusion of a serial-in-parallel-out interface into the display system.
In addition, for more than three-bit colour depth (i.e. more than eight distinct output colours), some form
One option would be to use a simple serial-in-parallel-out shift register to address this quantity of LEDs
using just one µPC output line for the data and a second for the clock (or potentially a few data lines in
parallel sharing one clock). This configuration would allow for addressing of all 192 channels from the
Arduino Uno, but the LEDs closer to the µPC would flicker with the data designated for further away, as the
data was shifted through the LED array. This quick flickering would likely lead to an amalgamation of colour
on each LED, perceived as white LEDs throughout and the desired image not being visible at all. For this
reason, hardware would have to be implemented to blank the LEDs while data was being shifted and only
LED. PWM (to achieve >3-bit colour depth) would still be impractical with this configuration: either the data
for each channel would have to be re-shifted for every pulse of the PWM (which would be significantly too
slow for the processor to handle, and result in the LEDs being blanked almost all the time) or alternatively
multiple SIPO shift registers would be required in parallel (one for each bit of each colour channel) resulting
Instead, research was conducted into dedicated LED driver integrated circuits (ICs), which integrate
hardware for serial-in-parallel-out shifting, current limiting, LED blanking, multi-bit PWM, and so on. The
Texas Instruments TLC5940 was chosen as it interfaces well with the Arduino Uno, has a relatively low price,
and offers a multitude of useful features for driving (common-anode RGB) LEDs. Specifically, the IC provides
a 16-channel output, but the IC can be daisy-chained allowing for 12 ICs to provide the 192 output channels
the system requires. The IC also provides 12-bit PWM, which theoretically provides a 36-bit colour depth, or
almost 70 billion different colours (in practice such a huge depth is unnecessary but unavoidable, and in
any case will likely be limited to 24-bit or less by the image files/compressions used). Since the IC is
primarily designed for LED driving, numerous additional features are provided that will be useful for this
project: these include a feedback loop for controlling LED current (reducing the number of current-limiting
resistors required from 192 to just 12) as well as a dot-correction feature allowing for any discrepancy in R/
G/B LED brightness to be corrected in software. The datasheet indicated that the IC would be more than
capable of handling the data transfer rates necessitated by the system’s persistence of vision requirement.
Conveniently, Arduino recommend a GPL-licensed software library for controlling the TLC5940. However, the
library did not appear to be primarily designed for persistence of vision applications (and in particular not
for POV applications with such a high number of output channels), in that it was not optimised to provide
the high data transfer speeds required by this project. To give one example, the library requires each LED
channel output to be set using a separate function call, significantly slowing down the data setup process
for displaying each column of the display. Based on the 16 MHz clock of the Arduino Uno, there are simply
not enough clock cycles available to afford this kind of function call overhead (an entire column of 192
channel outputs must be computed and output in less than a millisecond in order to achieve the data
still adhering to the Requirements Analysis for the project, is to write a custom TLC5940 Arduino library,
from scratch, for high-speed persistence of vision displays. The design, implementation and testing of this
library will be discussed in the following chapter (Software > Persistence of Vision Display Library).
Manually wiring 64 RGB LEDs would be impractical: a printed circuit board (PCB) will therefore be designed
and manufactured instead. Surface-mount components would be used in favour of through-hole technology
where possible in order to keep the rotating body of the system as light as possible, and because RGB LEDs
with a diameter less than 5mm are only available as surface-mount devices. The board will be
manufactured in the School of Electrical and Electronic Engineering at the University, and Altium Designer
will be used to design the circuit schematic and board layout as it is the only software supported for
Depending on the data transmission protocol used between the microprocessor and display circuitry, there
is a possibility that there will only be one pin of the microprocessor on which serial data can be sent2 . To
accommodate this possibility, the display circuitry should be designed to include demultiplexing hardware:
this would allow data to be transmitted down one wire, alongside a channel selection bus (three wires:
SELR, SELG, SELB) to allow the demultiplexer to route the serial clock to the relevant channel (red, green or
blue). This ensures that the serial data for each colour is clocked only into that channel (Figure 11).
By using three distinct selection bits instead of encoding the three possibilities (R/G/B) into just two bits,
the circuit benefits from reduced hardware complexity. The demultiplexing schematic shown in Figure 11
can be implemented using just one IC (a Texas Instruments SN74HCT08 / quad two-input AND gate). By
setting any one of SELR/SELG/SELB to be logic high, only the channel for the corresponding colour will
2 Specifically that if the SPI module of the microprocessor is used, there will be only one pin on which data can be sent. The
decision of which transmission mechanism to use is made in the following chapter (Software).
For full-colour output each of the three selection lines should be set high in turn, and the data clocked in
for that channel whilst its selection line is high. For single colour output (useful when the microprocessor
does not have enough time and/or memory to compute full RGB data), only one set of data must be
clocked through by setting one or more selection lines high and clocking data for all 64 LEDs (allowing a
single colour of red, green, blue, yellow, cyan, magenta or white – or a darker shade of any of these
colours).
In addition to the five signals shown (global data, global data clock and three channel selection bits) and
two power lines (V+ and ground), the following signals are also required:
• VPRG – to select between ‘data transfer’ and ‘dot-correction setup’ modes of the LED driver ICs
• BLANK – to blank the LEDs whilst the next column of LED data is transferred from driver memory to
LED output. Also resets the PWM counter to 0, ready to display the next column
• XLAT – to latch the data from driver memory to LED output during the time that BLANK is set
• GSCLK – clock for pulse-width modulation of the LED output. This will simply be linked to a timer
interrupt pin of the µPC to provide an 8 MHz square wave
This gives a total requirement of 11 input pins to the display circuit board. A standard 12-pin header will
therefore be used.
The absolute maximum current permitted for the LEDs being used is 50mA for red and 25mA for both green
and blue [12]. However, when testing the LEDs it was clear that these values would be far too bright (and
even uncomfortable) for the viewer. Much lower values were therefore tested instead: even as low as 2mA
still offered a fairly bright display and, since the current range supported by the TLC5940 driver IC is
5-120mA, 5mA was chosen as the current per LED channel for the system.
This per-channel current meant that the maximum theoretical3 current consumption for all the LEDs in the
system combined would be (0.005 x 64 x 3 =) 0.96A. The total current rating for the board would therefore
be a little higher than this (to account for the 16 driver ICs and other circuitry). Research online [13][14] and
conversation with the project supervisor indicated that the circuit board tracks handling this amount of
current should be thicker than the 0.25mm signal tracks: a track width of 1mm was instead selected for the
This power can be provided by a bench power supply: the supply has a customisable-voltage output which
will be used for the electronic speed controller and motor, and a second supply fixed at 5V which will be
Circuit Schematic
To simplify schematic circuit design, and to take advantage of the repeating/modular nature of the circuit,
the design was separated into four repeated subsystems (Figure 12), each containing 16 of the LEDs and
provide some degree of spike protection [15]. The resistors for each driver IC are necessary to set the
current provided to each LED; the value of the resistor is calculated using the equation given in the TLC5940
datasheet for setting current (Imax) based on VIREF (fixed at 1.24V) and the resistor value chosen. Based on
7.8kΩ resistors were therefore used, as this was the closest available resistor value.
Circuit Board
After ensuring that the subsystem design and overall schematic were correct, the design was then mapped
to a circuit board layout, and positioning and track routing was performed. Although the TLC5940 IC had a
footprint library available on the Texas Instruments web site, the LEDs themselves did not have any
footprint library available online or from the manufacturer. A library was therefore produced manually using
the tools provided in the software and physical data obtained from the LED datasheet.
The component placement was completed manually in order to ensure that the LEDs were all aligned
vertically, and that there was sufficient space for track routing around the components. Initial routing was
also completed manually to ensure that power to the LEDs was through thicker tracks than the signal lines
in order to (as explained earlier) accommodate the current consumption of the LEDs; the remainder of the
signal routing was then conducted by the built-in software auto-router. The completed board design is
Testing
• The pads for one of the LED driver ICs was missing (due to a mistake by the technicians when
transferring the design to a new file)
• The ICs did not have holes for heat dissipation, as recommended by the datasheet
• The LED pads were a little too short to be surface-mount soldered by hand.
The system needs a means of tracking rotation speed in order to stabilise the displayed image: in order for
the viewer to perceive a static image (rather than the image being drawn at a different position around the
cylinder on each rotation), the software needs a frame of reference: some means of identifying the exact
speed at which the rotating body is rotating. This can be achieved using a Hall effect (magnet) sensor and
magnet. The magnet will be mounted to the static body of the system, and a latching Hall effect sensor
connected to a digital input pin of the Arduino. The sensor (a US1881 CMOS Hall effect latch) latches to a
logic high voltage on encountering a magnetic north pole, and logic low for magnetic south. By placing a
north pole followed by a south pole in the path of the sensor during rotation, and configuring the Arduino
input pin to interrupt on a falling edge, the system is able to recognise when it has passed the specific
This information could be stored and compared to previous interrupt times in order to calculate a rotation
speed. In practice, however, this solution is more complicated than necessary. Instead, by simply resetting
the ‘column index’ variable to zero on each Hall sensor interrupt, the image should stabilise itself since
image position is directly correlated to these column indices: if each indexed column always occupies the
Once the hardware and electronics had been designed and implemented, and individual subsystem testing
had been completed where appropriate, the various parts of the system were integrated and tested as a
whole.
The final display software had not yet been written at this stage, but prototype software from earlier in the
design process had been. This prototype software was therefore used to test the display circuitry: the
software simply lights N LEDs in a given colour (e.g. green), where N is the index of the current column
being displayed i.e. one LED in the first column, two in the second column, and so on. When rotating, this
brightly, followed by smoke being emitted from one of the LED driver ICs. The power supply was
immediately switched off to prevent any further damage. The problem was identified: the LEDs were being
powered from a separate supply than the microprocessor, despite signals being sent from the latter to the
former and no connection being made between the two grounds. This had allowed for mismatches between
the power and signals of the LED drivers, and had sent their outputs into a positive feedback loop that
ended up drawing extremely high current from the power supply. Once the damaged IC had been removed
and a replacement re-soldered, the solution was simple: the system setup was modified to power the
The LED circuitry then worked correctly. However, the LEDs and microprocessor would frequently lose power
for a fraction of a second (enough to reset the microprocessor). This was resolved using a large electrolytic
smoothing capacitor across the power lines once they enter the rotating body.
The POV Display library (pov.h) controls all interfacing between the µPC and the display circuitry. The library
was written specifically for this project as an alternative to the publicly available TLC5940 Arduino library
(for reasons mentioned in Hardware Design > LEDs and LED Drivers, above), and includes code that can:
In order to draw at least 64 RGB columns of the image in less than 42ms (to permit 24 complete rotations
per second), the library must run fast enough to enable a column to be output in (1 / 24 / 64 ≈) 650µs. To
do this, certain manual optimisations must be performed: for example, bit-setting and bit-clearing
preprocessor macros are used instead of calls to predefined Arduino functions (reducing such operations
In addition, the SPI (Serial Peripheral Interface) module of the Arduino can be used to transmit data to the
LED drivers: this module allows byte-data to be transmitted down a serial link with accompanying clock (the
exact configuration used by the TLC5940 LED drivers) at a much faster rate than manually transmitting
through digital output pins. Prototype software was written to measure the performance increase: SPI
allowed a full column of RGB LED data to be transmitted in 342-600µs4 , compared to 4000µs with manual
transmission. Manual transmission would therefore be capable of supporting a theoretical maximum of just
ten columns per rotation (less in practice, due to time needed to compute the column data prior to
4 The discrepancy here is due to there being a number of ways to determine when one SPI byte transfer has been completed before
beginning the successive transfer. Maximal performance (342µs) can only be achieved by issuing the correct number of assembly-
language NOP (no operation) instructions to the processor while waiting for the SPI byte transfer to complete (instead of waiting for
the “SPIF” interrupt flag to be set, indicating a completed transfer). This works reliably because the SPI clock is driven from the
main system clock and number of clock cycles taken is therefore predictable – but results in extremely inelegant (and more difficult
to maintain) code.
computation time, but still allowing the specification of >64 columns to be met).
Operating Speeds
The PWM (pulse-width modulation) controller of the TLC5940 IC requires a continuous clock input to enable
it to compute and output its pulse-width modulated signals to the LEDs. Once 4096 pulses of this clock
signal (known as GSCLK in TLC5940 documentation) have been sent, the entire PWM for one column has
been displayed and the LEDs should be blanked in order for the subsequent column data to be latched to
the LEDs and the process to repeat: in other words, all data for a subsequent column must be clocked to
To have any chance of accomplishing this, the GSCLK signal must come from some Arduino hardware that
does not require interrupting the processor flow of execution, as the processor will otherwise not have
enough time to compute and transmit all the data for a subsequent column to the drivers. Thankfully this is
achievable by configuring the timer interrupts to output to one of the digital output pins on timer overflow,
Since the Arduino Uno has a clock speed of 16MHz, this is clearly the fastest speed at which a GSCLK pulse
can be generated without the use of an additional oscillator. The Arduino does allow this 16MHz system
clock to be output directly to pin 8 (CLKO) by reprogramming one of its fuses, and this could be connected
to the GSCLK input of the driver ICs. However, this would mean that the data for a column must be
computed and transmitted within (4096 / 16MHz =)256µs. Since it has already been established that a full
column of RGB data takes a minimum of 342µs to transmit, this GSCLK rate is clearly too fast.
The next fastest practical speed of 8MHz, however would provide a suitable time of 512µs in which to
compute and transmit RGB data using the Serial Peripheral Interface. This is therefore the speed that will be
used. An 8MHz clock can be output on pin 3 of the Arduino Uno by configuring the Timer0 interrupt to use
no pre-scaler and overflow after just one clock pulse, toggling pin 3 (OC2B) [16, page 159] as the timer
counter alternates between zero and one at 16MHz and therefore producing an 8MHz output.
Using this information it is possible to calculate the number of columns to display on the LEDs per complete
rotation. Since the computation/transmission time allocated for each column is 512µs, 1953.125 columns
rotation is equal to 1953.125 divided by 24, or 81.38 columns per rotation. For simplicity, this will be
Library Usage
The library is designed to be included into an application, and can be initialised by a single call to
within the application in order to implement drawing of each column of the image. This implementation is
what controls the actual image to draw, and could specify the drawing of images, text, or other media as
One use of the system is to display colour images (including low resolution photographs) using the
persistence of vision technique. These images could be simple shapes, drawings (illustrations; cartoon
characters) or even low resolution (80px x 64px) photographs. Using the POV library described above,
1. Store the image data for each channel separately as a two-dimensional array of channel
intensities, organised by column, then pixel (byte) data
2. On each execution of povDraw(uint8_t columnNo), for each colour channel, use the
columnNo parameter as an index to the data array for that colour. Simply iterate through every
byte of the column data transmitting each, in turn, to the SPI.
The significant stage in the process of displaying images on the POV display is therefore not in
transmission, but in the (pre-)compile-time phase of generating these two-dimensional byte arrays. This
was achieved by writing a Java application, povconvert, designed to take a regular image file (PNG, JPEG,
etc) as input, resize it to fit within a 80px by 64px box, and iterate through the raw pixel data of the image
in order to output a C header file containing the byte data for each column of each colour channel. The
This algorithm guarantees that the image fits entirely within the bounding box dimensions. The resized
image is then positioned in the centre of a black canvas and a C header file generated based on the raw
pixel data of the (newly resized) image. The header file can then simply be ‘#include’d into the Arduino
The Arduino Uno has 2KB of RAM [17]. The amount of memory required to store an eight-bit-per-channel
= 64 * 80 * 3 * 8
= 122,880 bits
= 15 KB.
Even if the number of bits per channel were reduced to just two (which would reduce the number of
colours available to just 64) the image would still not fit in RAM.
Fortunately, since the image data does not need to be modified at runtime, it is possible to store the data
in flash memory (where the program code is also held) instead of in RAM. The Arduino Uno has 32KB of this
memory, of which 0.5KB is used by the bootloader [17] and a little more will be used by the program code
and POV library, leaving plenty of available memory for the image data itself (even if the image were stored
at up to 16 bits per channel). Utilising flash memory instead of RAM simply involves use of the PROGMEM
keyword, prog_uint8_t data type, and pgm_read_byte method for reading back the data [18][19].
Byte-Packing
Although the original image files used have eight bits per pixel per channel, and the SPI module of the
Arduino is designed specifically to transmit data as eight-bit words, the LED driver ICs require a 12-bit word
image data four bits to the left to produce a 12-bit intensity value, then packing this 12-bit data back into
eight-bit words for the C array. For example, where a string of eight letters (e.g. AAAAAAAA) represents the
Since the LED drivers accept 12-bit values, this data will be recognised for display on the LEDs as—
AAAAAAAA0000
BBBBBBBB0000
CCCCCCCC0000
DDDDDDDD0000
...
—resulting in the intended pixel intensities being displayed on each LED. This works due to the absence of
any word start/stop bits in the SPI protocol used here: the TLC5940 ICs will simply assume the first twelve
bits received to be the first word, and so on, even if the sender is sending them in eight-bit chunks.
Although the storing of so many zeroes is technically redundant, it allows for increased computation
performance at runtime as the data can be sent to SPI as-is. The potential downside to this is the increased
memory requirement, but it was shown above that the flash memory of the Arduino Uno is large enough to
As well as images, one of the Project Objectives was for the persistence of vision display to be capable of
displaying text. Although this could technically be achieved by uploading an image containing text and
running the image display program discussed previously, a full text displaying engine would certainly be
preferable.
To display text, the system needs to store some kind of letter data: this can be implemented as a look-up
table (array) of individual letters, each of which is itself an array containing column data for the letter. For
Due to the relatively low resolution of the display, anti-aliasing would offer little benefit and can therefore
be disregarded. This means that each pixel has one of just two possible states (on or off) and can therefore
be encoded as one bit; each column of each letter can therefore be packed into a 16-bit integer. For
Columns should be stored from right to left, as the rotating body will be rotating clockwise and therefore
In order to allow display of variable-width characters (the letter I occupying fewer pixels horizontally than
the letter M, for example), a letter-terminating code (0xFFFF) will be added as the final column data of each
letter: when this is encountered, the engine will move to the next letter of the message to display
(technically, the previous letter as messages will be written from right to left due to the LEDs rotating
the POV Display Library and drawing the next column of the current letter of the message to be displayed.
Two pointers are maintained: one to the current letter of the message, and the other to the current column
of that letter. In order to make the display more visually exciting, on moving to the next letter to be
displayed, a new colour is chosen from a look-up table of four different colours (yellow, green, magenta
and blue), although this can easily be changed from within the code.
To further the text display capabilities of the project, a custom font feature was added to the text engine. In
the context of the engine, using a different font simply refers to modifying the look-up table of character
data for each character, to resemble the character in that new font. To assist in generating this font data,
the povconvert Java application used to generate images for display in the system was extended to also
generate font character look-up tables from a given input font. The output was once again a C header file
that could be included into the Arduino C program. The Java converter worked by iterating through the
columns of an image that displayed the string ABCDEFG….[etc] in black on a white background, and
producing a C array of this column data for each character. When one or more adjacent white columns were
encountered (i.e. the boundary between one character and the next) the character termination code was
• If the font had not yet been converted to the POV display-readable format, create a readable font
using povconvert
• Set the FONT_FILE constant to be the path to the font with which to display the message
• Set the MESSAGE_TEXT constant to be the string to display
• Compile and download the Arduino program to the display microprocessor
The output of the system for the word “SPINNING” is shown in Figures 17 (stationary) and 18 (rotating).
Figure 17: Output for the word “SPINNING” when stationary Figure 18: Output for the word “SPINNING” when spinning
Testing of a variety of messages and a variety of fonts all proved successful. However, the results were not
ideal when long message were used (messages that could not fit within the 80 columns of the display) as
the beginning of the message would be absent. Furthermore, only one row of text could be displayed using
this method of displaying text. There limitations both stem from the fact that the computation of how to
display the text was performed on a column by column basis as the data was output to the LEDs. A much
better mechanism would be to calculate exactly where the text should be in advance, store this in a buffer,
and output the column data once this had been calculated. This would allow long messages to scroll
(animate), span multiple lines, etc. This could be incorporated into the graphic processing library described
next.
During the design and implementation stages of the text display engine, it quickly became apparent that
there were inherent limitations to coupling the computation of data with the transmission of that same
data. In order to use the system to its maximum potential, some kind of display buffer was required that
could be used to compute LED data once, and this data would subsequently be fed to the LEDs column by
This mechanism would solve the limitations described in the previous section (Text Display) because the
system would then have knowledge of the entire display canvas when making drawing decisions, rather
than making these decisions in an on-the-fly (column by column from right to left) manner.
The library written to achieve this goal, povGraphics.h, was fairly straightforward. The library provides
an 80px by 64px canvas of 1-bit pixels (implemented as a two-dimensional array, packed into bytes), and
pixels can be set or cleared by calling the POVG_SET_PIXEL and POVG_CLEAR_PIXEL functions
respectively (technically pre-processor macros rather than functions, for efficiency). In addition, higher-level
functions are provided for drawing more complex arrangements of pixels: internally these functions simply
points. The line-drawing algorithm used was a C implementation of Bresenham’s Line Algorithm, an
extremely efficient algorithm utilising only integer addition, subtraction and bit-shifting (all cheap single-
cycle operations on the Atmel AVR processor of the Arduino Uno). A circle-drawing algorithm, using the
same three operations, was also implemented and could be executed by calling povgDrawCircle with
the centre coordinates and radius of the desired circle. Again, this function internally calls
At its simplest level, the library functions would simply be used in a setup function when the system is
first powered on, in order to compute the canvas that will be drawn throughout the time that the system is
running. However, with some additional work it seemed feasible to extend the library to allow for non-static
images (animation) to be displayed, by creating a second canvas (buffer) in memory. The system would
create one “thread” to handle transmission of column data to the LED drivers/LEDs from one canvas (the
“front buffer”) while the remaining idle time of the processor is used to compute a subsequent frame to
display, using the “back buffer”. Once the back buffer has been fully computed and a fixed period of time
has elapsed (determined by the desired frame rate of the animation), pointers to the two buffers can be
swapped in order that the newly computed canvas is now being drawn to the LEDs, while the other buffer
(now the “back buffer”) can be written to during processor idle time.
Test Strategy
The double-buffering system was first tested by hard-coding two distinct canvases (one with alternating
rows of on-pixels and off-pixels, and the other with a rectangle in the centre) and programming the system
to swap between the two buffers every 24 rotations (approximately once per second). Once this was
working, the system was extended to implement some computation rather than hard-coded values: a
horizontal line was drawn in the top-most row of the canvas, and every second this line moved down by
one pixel (returning to the top once the bottom was reached). This test also worked as expected. Similar
tests involving diagonal lines, circles and so on were also conducted, and passed.
Since the two 80px by 64px canvas buffers combined occupy 1.25KB of system, and the Arduino Uno has
just 2KB of RAM [17], it becomes impossible to increase the colour resolution of the graphic processing
system beyond 1-bit per pixel (without reducing the canvas size). The graphics library will therefore only be
trivial to implement an input to the microprocessor to allow for colour changes at runtime (such as a
The animation and vector graphic drawing components of the POV Graphics Library described here provides
everything required for the implementation of an analog clock on the POV display. This can be achieved by
setting the frame rate of the double-buffering to be one second, and on each iteration of the drawing
algorithm the number of elapsed seconds can be incremented (with an overflow at 60 seconds to increment
The clock face can be drawn using the circle drawing function for the clock face, and the hand end-points
(or the hand angle, implicitly) retrieved from a lookup table of end-point values: lookup would be based on
the number of hours, minutes and seconds elapsed and would then be used to draw the hands by calling
povDrawLine from the centre of the clock face to the hand end-point. Only one quadrant of end-point
values (15 values) need be stored: the remaining three quadrants can be calculated be swapping and/or
negating values from the top-right quadrant. A function, getHandEndPointOffset, was written to
implement this process based on a hour/minute/second input value from 0-59. To avoid overcrowding the
clock face, the seconds will be displayed as a single pixel around the outside of the clock face rather than
as a line from the centre. Figure 19 shows the clock program when running.
Currently, the clock program requires the starting time to be hard-coded, as the system has no means of
keeping time when power is removed. However, this could be corrected relatively easy: one method would
be to purchase a radio clock receiver (such as the DCF77), and connect this to the Arduino Uno in order to
ascertain the current time on system startup (and potentially at regular intervals after this).
• The aim of this project will be to design and implement a “persistence of vision display”.
✓ A persistence of vision display was successfully built and implemented.
• The display will physically consist of a one- or two-dimensional array of LEDs, but these LEDs will be
moved rapidly in physical space in order to produce the illusion of a three-dimensional display when
viewed from any of a number of angles.
✓ The system consists of a one-dimensional array of LEDs, moving rapidly in physical space in order to
produce the illusion of a three-dimensional (cylindrical) display.
• This movement will be in a rotating, rather than oscillating, fashion, and should be implemented using a
motor.
✓ The display is rotational.
• Power will need to be transferred into the rotating body in order to light the LEDs: a means to achieve
this will need to be considered.
✓ The DIY “slip ring” consisting of a headphone jack/socket was used to achieve this power transfer.
This worked successfully.
• If the microprocessor is not mounted within the rotating portion of the system, a means for transferring
the LED data into the rotating body will also need to be considered.
[Not applicable – the microprocessor was mounted within the rotating body.]
• The system should be capable of rotating safely at 24 revolutions per second (1440 RPM) in order to
achieve a smooth virtual image.
๏ The system began to look and feel unstable when the motor was accelerated above approximately
10 revolutions per second (600 RPM). This was due to a slight imbalance between the mass/shape
on each side of the axle, and unstable angle connectors between the vertical and horizontal Perspex
of the stationary body.
• The system must have some means of determining its current speed in order that fluctuations in the RPM
do not ruin the perceived effect.
• The display should be capable of displaying text and low-resolution images such as shapes and cartoon
characters.
✓ Text, shapes and cartoon characters can all be displayed on the persistence of vision screen.
• The perceived display resolution should be a minimum of 32px by 32px. Ideally the resolution will be
greater than this […].
✓ The vertical resolution of the system is 64 pixels, and the perceived horizontal resolution of the
system is 80 pixels (easily increasable in software, depending on rotation speed).
• If time and software/hardware considerations permit, the system could be extended in order to display
photographs, animations, video, and/or include interactivity such as basic games that respond to user
input.
๏ Photographs work, but dark photographs are perceived to be poor quality due to the lack of colour
differentiation at dark LED colours. Animation was implemented successfully. Interactivity could be
implemented in future, as could video if the microprocessor were replaced to have more memory,
processor speed, and/or wireless connectivity.
• The system must be able to interface with a PC in order to receive images for display: this would ideally
take place over a wireless link and allow the system to receive images on-the-fly whilst rotating, but at a
minimum could just be achieved by a physical connection to a PC when the display is not moving.
✓ Due to hardware limitations of the µPC, wireless communication was not possible. Images and
programs can, however, be downloaded from a computer using a USB A–B cable when the display is
not rotating.
Additional Programs
As well as the software detailed in this report, additional programs could be written to enhance the
• Implementing basic input to allow for interactive selection of what text to display
• Increasing the frame rate of the animated clock animation to allow for smooth animated vector
graphics, such as scrolling messages or more advanced animations
Mechanical Stability
As noted in the Evaluation, the system became slightly unstable as the motor exceeded 10 revolutions per
second (600 RPM), and would likely have become very unstable (even unsafe) at speeds approaching the
desired 1400 RPM. This was likely due to the weak angle supports used at the top of the system, as well as
a slight imbalance between the mass/shape on the two sides of the axle.
The first of these could be rectified by replacing the weak angle connectors with much stronger Perspex
corner wedges: this was in fact the intention in the original designs, but was never implemented due to the
unavailability of the correct thickness of Perspex. The second issue is slightly more difficult to modify, but
would be achieved by remanufacturing the rotating body to make the central axle equidistant from the PCB
and microprocessor and precisely balancing the vertical positions and masses of these system components.
With these two changes made, it is likely that the system would be significantly more stable at higher
speeds.
The second major enhancement would be to allow wireless transmission of images to the system. This
would allow for increased processing power, as processing could be achieved on an external computer and
the resultant images/frames transmitted to the POV display. Video or interactive games, for example, could
then be easily implemented within the system: all heavy lifting would be performed at the computer level
and the POV system would effectively become a wireless display monitor.
The reason this was not implemented was that the only practical way to achieve wireless communication
with the Arduino Uno is to use the Wireless SD shield, which requires use of the SPI module of the Arduino.
Since the SPI module and pins are already required for transmitting LED data to the LEDs, they were
unavailable for use in wireless communication. A different microprocessor may allow for simultaneous use
of wireless protocols and SPI transmission for LEDs: this would likely allow for the desired wireless system
as discussed (dependent on transmission speeds: a buffer would likely be required, which would require
7.2. Conclusion
Overall, the project was an overwhelming success. As shown in the Evaluation, every aim of the project
specification was met at least partially, with the vast majority being met fully. The finished product is
certainly eye-catching, making it potentially useful for the entertainment and/or advertising industries as
speculated at the beginning of the project. The cost of production was fairly high (estimated at around
GBP50), but this is often the case when working on a single prototype: in practice if making many copies of
the product the cost would be reduced. The project involved the learning of many new skills and
technologies (designing PCBs; mechanical construction; programming microprocessors using C and the
(4) "Awesome POV (Persistence of Vision) COLOR Display!" YouTube. 9 Oct. 2012
<https://www.youtube.com/watch?v=QAGnpKz7zvY>.
(5) "POV Globe using Arduino (ATmega328P) and 72 SMD LEDs." 18 Oct. 2012
<http://code.google.com/p/povglobe/>.
Single-colour LEDs (either red or blue, but not both from the [2]
same LED). Two-dimensional circular perceived display.