The Raspberry Pi Punnet


The Magic Wand

This is a revamp of a project I first did back in 1989. The July 1989 issue of The Micro User to be precise.

Back then I believe it was the first time such a thing had ever been published, but nowadays it is a common project.

The problem with being first is that what you call it, might not end up being what everyone else calls it.

It was christened "Magic Wand" by the sub editor of the magazine. Nowadays this sort of thing is referred to as a POV or persistence of vision project.

Nevertheless it is simple to make and fun so I though it was a good candidate to adapt for the Pi.

Incidentally, not only did I make the cover photo that month, but also the Fractal graphics article was mine as well.

The concept is simple, a column of LEDs flash out a message displaying one column at a time in a rapid sequence. You then move the LEDs so that each column lights up in a slightly different physical location. Then the persistence of vision that the eye possesses makes it look like there are LEDs in each position where they were like up. In other words waggle some LEDs on a stick and see words appear in mid air.

The concept can take many forms, perhaps the most impressive is where the whole unit is spun on a bicycle wheel but here I just want to show how to make the simplest version and let you explore the many possibilities of this effect.

My original circuit had 5mm LEDs arranged in a column, now you can get the LEDs closer together and get a more solid looking display if you use surface mounting LEDs. These come in many sizes but an 0806 or 0605 package will fit nicely on adjacent tracks of veroboard. As well as being many different colours to choose from there are also many different styles. I chose an LED with a diffuser built in to spread the light over the whole area of the package, and not just have a point source. I thought this might be better for photography. However, I don't think you can go wrong with what ever sort you choose.

You can drive the LEDs direct from the Raspberry Pi without any buffers as you only need a few mA of current. I connected the LEDs directly to my breakout board (link) which incorporate a 330R series resistor with the outputs. If you do not have this then fit a resistor on the board, a surface mount resistor would make things small and neat, but it is not essential. You might wonder about the pin assignment of the GPIO pins to the LEDs, these were simply to use the GPIOs on one side of the Raspberry Pi's GPIO connector, in the order they appear on the Breakout board. This meant you got a straightforward wiring to the cable from these pins. The actual order does not matter, as we are going to have to sort them out into the neat column in software anyway.

With the LEDs and a switch on a stick you need to connect them up with wires. A miniature multi core cable would be good but you need 10 conductors and I didn't have such a beast. What I did have was some ribbon cable, so I cut down a length and split off 10 connectors worth. I use about 2 meters, and laid it flat along the length of the stick. Hot melt glue to the back made it stick along the length. However, I noticed the tendency for it to peal off at the end, so I wrapped a small length of self amalgamating tape around the holding end. This looks like insulating tape but it is much better. It is not sticky at all but has the property of being able to bond to itself. The trick in applying it is to stretch it as you wrap it round. As it contracts it will bond to itself and after few hours it will be just one piece of rubber. They use it in the Army a lot. A quick Google search for self "amalgamating tape" will bring up lots of hits.

Back to the Punnet

The other major component of this project is some sort of motion detecting switch. This is so you can synchronises the movement of the wand and the flashing of the LEDs. My original project used a mercury switch, the mercury would slosh to one end when the wand was swung in one direction, and slosh to the other when reversed. Thus the switch would be closed in one direction and open in the other. You could then use this arrangement to start the LEDs flashing when you saw the direction change. Well in the intervening years mercury has got a bad name and has been banned in many places. For example under the RoSH legislation it is illegal to sell products that contain it. However, this only applies to certain product categories and presently, military, medical and industrial equipment forming part of a building's infra structure, are all categories that are exempt. This means that you can still get mercury tilt switches as components. You can still build them into devices like this wand, however what you can't do, is then go on and sell the wand as a product. So I would recommend using a mercury switch for this project if you can get hold of one. Just be very careful when disposing of it and take it to a proper recycling centre. RS components still have them for just over a pound each. (Note to U.S. readers RS is a UK distributor of components and is not Radio Shack.)

There are alternatives and perhaps the simplest is the ball switch. Here, a ball baring is placed in a tube and it is used to bridge a pair of contact when it is at one end of the tube. There is also an optical variant where the ball breaks an IR beam of light. These will work although they are more noisy and perhaps will ware out quicker. Finally you can use the very modern solid state accelerometers to act as a synchronising switch, but these are much more expensive and require more electronics to drive them.

Having built the hardware then we need some software to make it go. The original project wrote the message onto the screen and then used the peek commands in BASIC to read the pixels off the screen to get the data for the wand to use. While I am sure such an approach can be made to work on the Raspberry Pi, I thought it was simpler just to search the web for a dot matrix font to use. This then will give the capability of using any normal string to define your message. It can also be extended from simple alpha numeric characters to simple 8 X 8 block graphics. The idea is to have a buffer in the form of an array that contains the bit pattern of the display at any instant. That bit pattern will be scrambled a bit due to the relationship between the LEDs and the bits controlling the LEDs in the GPIO's register address. Let me say at the outset that this appears much more complicated than it really is. The whole thing is written in C using no libraries at all.

You can see from the diagram that for example the top LED, is defined from the top bit in the pattern byte and this LED is controlled by GPIO 8, because that is how I wired it up. Similarly the other LEDs are defined by bits in the pattern and controlled by the appropriate GPIO pin.

Basic Concept



This might seem at first a bit of a complex nightmare to do anything with, however, it is quite easy to cope with using a look up table or array. The array simply defines the GPIO bit position for each bit in the required pattern.

So defining a mapping matrix is simply:-

char mapping[] = {14, 15, 18, 24, 25, 7, 23, 8};

So simply the first element in the mapping array mapping[0] is the GPIO position controlling the bottom LED, that is GPIO bit 14. A simple loop will then generate the GPIO register bit pattern or value for any input pattern byte:-

gpio =0;

for(i=0; i<8; i++){

if((pattern & (1 << i) ) !=0 ) gpio |= 1 << mapping[i];


Where the variable 'pattern' is the byte containing the required pattern of LEDs, and gpio is the variable to write to the pins.

You might not be familiar with some of the C operations here << means shift to the right a number of times. So that 1 << 8 will actually generate a number 0x100. The & is the bit wise and operation and is used to probe the individual bits in a byte.

So the software will build up an array of bit patterns (numbers) to send to the LEDs in turn. These are then fired at the hardware at a regular rate to produce the flashing pattern we need. This is synchronised to your swing by looking when the motion switch changes direction. This then triggers one scan through the display array. It is best to introduce a small delay from the change in the switch before starting the display to allow the stick to come up to speed.

Now reliable delays are not a strong point of a multitasking environment like Linux. Fortunately the BCM2835 chip has an ARM peripheral that can help. It is a free running counter, that means it keeps on going while the operating system steals some time off you. So when you want a delay you simply make a note of the value in the counter at the start and don't return until the counter has advanced to a value corresponding tot he delay you want. The only snag is that time might be being stolen off you just when the counter is about to expire, in which case the delay will be longer than you wanted, but most of the time it will be fine. I set up the prescalar to this counter so that it increments at a 1MHz rate giving me micro second resolution. There are other tricks you can pull like altering the priority of the task and using interrupts, but the results I obtained were good enough not to bother with these techniques. However, I found that the words were distorted when the screen saver kicked in. You can see in the image below, here the switching of the columns gets delayed to smear out the letters. Under normal operation the program spends most of its time sitting in a delay loop, interrupts here are not noticed. I must say that it looks much better in real life than it does in these photographs.

Also, I think you get better results if you just produce the scan on one swing and not both. This is because the position of the letters in the air is more consistent and does not change with forward and reverse swing.

Defining the message is simple, if it is all text then a string will suffice, if it is a mixture of text and graphics then you need to either use the ASCII numbers or a mixture of numbers and single characters delimited by a single quote. There are examples of both in the code. The graphics are defined in the upper half of the ASCII set by numbers greater than 127. There are 33 graphics characters defined in the graphics file, it is a simple matter to extend this.

Well their are all sorts of changes you can ring on this, the first is to use different colours of LED, or extend the numbers of LEDs in the column. With one GPIO needed as an input then you can extend this to use a column of 16 LEDs without resorting to any extra hardware. Getting even more LEDs is quite simple if you use cascaded shift registers. Then you can use multicoloured LEDs and the ultimate is to use RGB LEDs with brightness control on each LED. You are not confined to using a stick or manual motion, there are bicycle wheels as mentioned before and all number of custom arrangements.

While the software here Wand only allows one message at a time, it would be simple to extend this and have multiple messages selected by external switches on some spare GPIO pins. It is a simple matter to go from this to producing scrolling text and even animations by having a different message output on each swing.

Don't get in a spin, enjoy.