Intro: (POV) Persistence of Vision Globe
!Update! I have added an excel program that makes it much easier to draw and code new images!
A simple persistence of vision globe. PLAY VIDEO
This is a project I've had in mind for quite some time and the "Make It Glow" contest was just the motivation I needed to inspire me to pull out an old 5 LED POV display and take it to the next level, using shift registers. If you enjoy this instructable please consider voting for it.
A quick intro to POV or persistence of vision: Any AC voltage light is actually blinking on and off at a frequency of 60hz or 60 times per second. Our brains perceive this as constant light. It is this concept which we will be taking advantage of, in order to create a spherical image using a single row of LEDs. For this project , I decided 24 LEDs sequenced using three 8-bit shift registers would provide the minimum resolution needed for the globe.
Step 1: Materials
Here's what I used.
- (1) Arduino Uno (for prototyping)
- (1) Bareduino (for permanent board optional) VIRTUABOTIX LINK
- (3) HC595N Shift Registers
- (24) Blue LEDs
- (24) 220 ohm resisters
- (1) breadboard
- (1) battery holder and battery
- (1) 10" diameter ring (wide enough to hold LEDs and the lighter the better)
- (1) pieced of threaded rod (I used 5/16")
- (1) Motor (I used one from an old Dirt Devil)
- (1) Motor Coupler
- (1) 120V Disconnect (Light Switch)
- (1) Fan Speed Controller
Step 2: Building the Ring
I used a piece of 1/8" thick x 1/2" wide aluminum flat bar for my ring and 5/16" all thread for the center mast, because I had them laying around, but I think this could be made on a 3D printer complete with PCB mounts and be much lighter. I built this ring for a previous build using 5 LEDs each powered off a separate DO of the Arduino.
There is nothing special about the diameter of the ring. Mine is approx. 10" round, just because the flat bar I had was 3' long to begin with. I rolled it on a 3 in 1 shear/brake/roll from Harbor Freight, but you could also form the ring around a disk cut from plywood and have good results. For that matter, I see no reason the ring couldn't be made from wood. I just prefer metl working.
I drilled holes for the LEDs at approx 5/16" on center. This spacing filled in all but 1" on the top and bottom on one side of the ring. You will need to bolt a bracket in the center of the ring to provide a mounting surface for the breadboards.
Step 3: Making the Circuit
This was my first attempt at using shift registers, so I started researching on Arduino's site and found an extremely useful example, which I modified to suite my needs. You can find the tutorial at Arduino ShiftOut I settled on the "Code Sample 2.3 - Dual Defined Arrays" as my base code, more on that later.
If you follow through the tutorial you will learn how to send bits of information, one by one, in serial from your Arduino to the shift registers. This arrangement allows you to control all 24 LEDs on this project with only 3 pins on the Arduino. We will be using the serial in, parallel out capability of the 74HC595 to load 24 bits of information or 3 Bytes into the shift registers and then shifting the data out in parallel to the LEDs.
Since the first bit of data we load will wind up in the last register spot, we'll attached LED1 or the most southern LED to QO of the first Shift Register. Follow the schematic from the ShiftOut example and attached the third shift register to the second, in the same manner as the second is attached to the first.
I recommend running the sample code along the way, first with just one register then with two. The sample code sequences the lights such that it is easy to see if anything is miss wired. I was able to simply add a Byte3 to the "Code Sample 2.3 - Dual Defined Arrays" and a third array which I called Blue. You can see this in the ShiftOutArrayByte3R1 code uploaded to this step.
Step 4: Putting It All Together
Now that were confident the circuit works we need to get everything mounted to the ring. I suggest mounting your Arduino/Bareduino on one side and your Shift Register Board opposite the Arduino. This will help with evening out the weight, but you will most likely need to move some thing around until you get a stable rotation. I used the 9 Volt Battery on the side I needed to add weight to. I used zip ties to attach the boards and the Battery to the center Mast. This way I could make adjustments to get the ring balanced.
Now to solder all of the LEDs. Since we're controlling the positive voltage of the LEDs, we can connect all of the cathode leads together with a single un-insulated wire and plug that into our ground. Then we need to solder a resistor to the Anode lead of each LED and then attached a wire from the resistor to corresponding shift register output pin. I left in the Blink All function in the setup loop as an easy way to tell if you have an LED out.
Step 5: Drawing the Globe
!!Update!! Now you can draw using the excel program, which converts the image to hexidecimal for you. The code for your Red, Blue, and Green arrays can be copied and pasted into the Arduino sketch. Simply fill in a 1 where you want the LED to be ON and the cell will change to blue automatically! The Excel program is uploaded to this step. Thanks to the Rave Shades instructable for posting the Rave Shades Animator, which was modified for this project.
Okay. Now to get artistic. I chose a globe because I thought it would be a cool way to make a 360 degree spherical display using POV, but I'll try to show in this and the next step how you can create any image you can draw in a 24x70 dot resolution.
First I found a suitable world map image to use as a guide. Then I found an app on Google Play called "Mosaic Builder" that was perfect my needs. As you can see in the last picture on this step I was able to create a low res version of the world map pic on my 24x70 template. FYI the 24 comes from the 3 Bytes of data and therefore 24 LEDs tall and the 70 comes from dividing the circumference of my ring by 5/16" to make the horizontal spacing match closely to the vertical spacing of the LEDs. The 70 dots wide will vary based on the size of your ring, but is not critical. It's especially not critical since we are not using any type of sensor, such as an infra red LED to sense a complete rotation and reset the loop. This is something I may consider in the future, but for now as long as we have speed control on the motor the sensor is unnecessary.
Once you have a drawing you're happy with you can convert the image into hexidecimal code by Byte, in the next step.
Step 6: The Code
!Update! Just draw in your image using 1s to represent ON, which will automatically color the pixel blue. When your image is ready press the "Copy All Arrays" button and paste over the existing arrays in the Arduino sketch! I have uploaded a new sketch to this step.
As mentioned previously, I used the "Code Sample 2.3 - Dual Defined Arrays" from the Arduino ShiftOut example as my base. As you'll notice in this code the author comments that he isn't sure if Arduino can handle direct binary values, so Hexidecimal values were used instead. Note: I never changed the binary comments next to the Hex values, I only changed the Hex values to fit my world map image.
Now this was only my second time seeing Hex and I was pretty clueless. I found the attached Hexidecimal-Binary conversion chart, which helped immensely. This chart can be used to convert the binary value of each column or (Byte) to a hex value. For example if you look at the last picture on this step you can see how the world map image was broke into thirds from top to bottom and each column consists of 3 Bytes, where white or off = 0 and Blue or On = 1. At the bottom of each column the Byte has been converted to a Hexidecimal value ranging between 00 & FF which is the equivalent to a decimal value range of 0-255 or a binary range of 00000000 to 11111111.
The attached code has the Globe image loaded, but can be modified for an image of your own.
Step 7: Testing
Before I moved on with building a base and motor mount I thought I would test and tweak the circuit. I simply chucked the rig into a cordless drill, turned everything on and pulled the trigger. I had to adjust the delay to 1 ms and my first attempt put Russia south of Australia. I also learned the image displays up side down, from what I expected, which was an easy fix to simply turn the whole ring over. The attached video is of my final successful test. Now its time for a base with a permanent motor and speed controller.
Step 8: Finishing Up!
I wired in the light switch as a disconnect for my motor and then wired the fan speed controller between the disconnect and the motor. This gives me a way to shut the power off quickly and have reasonably good control of the motor speed. Now I needed a way to connect the motor to the globe. The shaft on the motor was 17/64" and the all thread I used for the globe is 5/16". A 5/16" coupler might have been just the trick, but sadly I only had 3/8" couplers which were useless. Instead, I found a piece of 1/2" aluminum round stock and cut a 2" long piece and drilled a 17/64" hole through the center. This hole size was suitable for tapping a 5/16-18 thread halfway through the round stock. I also drilled and tapped a small hole through the side to thread in a set screw for the motor shaft then I threaded in the globe and used a jam nut to secure. The Dirt Devil motor spins fast enough to blow apart the hole assembly, so I needed to adjust the speed as far down as possible. At this speed the motor won't actually start spinning, making running the rig a little tricky. What I have to do is hold the globe from spinning and slowly raise the speed until the motor kicks on, then I can back the speed down and release the globe. Finally with some delicate fine tunning I can get a great slow spinning effect.