POV (Persistence Of Vision) Display using Arduino nano
- Prachet.S.Hire
- Oct 21, 2017
- 5 min read

pic1-Image showing my YouTube channels name "Only Using Transistor Circuits (OUTC)"
a.Introduction:-
"POV display " as the name suggests, that its a display which uses the phenomena of persistence of vision (POV). The array of 8 leds rotate at high speed giving your eyes illusion that you are seeing a continuous flying message. By the way ,we all must have experienced POV in our childhood by looking at the randomly flying insects under street lamp and their extended tail due to POV. POV works because of the way image is processed in our brain our visual cortex holds the image for few milliseconds and that's the exact reason why we can see movie, animation or waveform on CRO, cause the rate is 30 or above 30 frames per second. So make sure that motor you are using is not less than 1000 RPM other wise you will end up seeing flickering.
pic 2:-Image of project

b. Construction and circuit description:- Circuit diagram:-

The above shown circuit controls the 8 leds . It is achived with the help of arduino nano and shift register 74595. Also the shiftout function in arduino IDE helps a lot to shift hexadecimal data in shift register at high speeds which helps to control and multiplex devices like 7 seg display or in my case, POV display. To learn about shift out click on this link.
https://www.arduino.cc/en/Tutorial/ShiftOut
Also if you are exited about shift register and want to know more about it watch this video by Kevin Darrha. https://www.youtube.com/watch?v=6fVbJbNPrEU
The project uses A1302 hall effect sensor (HES ) which sense magnetic field and gives logic low output till the magnetic feild is present in its vicinity. The output of HES is given to I/O pin D5 of arduino nano. While the project is running the LOW trigger pulse at D5 acts as a kick which starts the data shifting process.
Finally once the circuit is made you need to balance and fix the whole thing along with the 9V battery on a rigid and light rectangular slab with a hole in center for motor shaft , I have used a wooden scale for this purpose. After that fix the motor and keep the magnet fixed so that every time while rotating, HES cuts the magnetic field.
c. Working
Before writing program for it we must first study the operation and which all factors affect the characters look on a POV display. This will give us idea about different ways we can program this POV display.
Following are three factors affecting width of the characters on POV display:- 1. Angular rotation 2.Speed/direction of rotation 3. Delay time between two data bytes.
Angular rotation:- Apart from that it uses principle of POV this display is different from normal rectangular displays because the horizontal scanning is not parallel to the X-axis rather it is perpendicular to tangent of the circular path traced by rotation of motor. Below given figures shows us the difference between ,normal and POV display.
fig 1 Normal display

fig-2 POV display

This type of angular rotation causes changes in the characters are displayed on it because the led near to center cover shortest distance whereas the last led has to cover more distance for the same angular rotation. This effect shrink the down part of the character ,observe the first image you will notice the shrink. This creates a cool unique look but is also a default which can be overcome by writing a special program.
Speed/direction of rotation:- For a given delay time ,the faster the motor rotates the more stretched the character on display looks. also greater rotational speed means more resolution and more persistence of vision. The resolution increases because you have to reduce the delay and send more data bytes for same character to compensate for the increase in speed. Thus the resolution of the POV display also depends on its speed. Changing the direction of motor from clockwise to anticlockwise will invert the character and display its mirror image so this must be kept in mind while turning on the motor . We can even put a diode in series with motor to avoid reverse current.
Delay time between two data bytes:- The moment there is low pulse at pin D5, the data byte shifting starts at a rate given by 1/delay. In the program we set the delay low such that the data shifting rate matches the rotation speed and a character which makes sense is displayed on it. setting a low delay will squeeze the character while setting a high delay will stretch the character.
d.Displaying your custom character.
This program I have written to display message "HAPPY " then "DIWALI" you can display anything you want ,all you have to do is change the HEX numbers in the array at starting of the code.
Steps to get the the HEX numbers :-
1.Get a pen and paper then draw 8*10 matrix on it. 2.Draw your character on that 8*10 matrix 3. Now the squares covered by your character are all 1s and rest are all 0's. 4.Finally convert each individual column into hexadecimal equivalent. By considering top bit as MSB. This will give you ten HEX codes. 5.Add six more HEX codes of data 0x00 for the spacing between characters. Refer the below given program. 6.Count the total no of HEX codes in your message and enter that number in for loop's condition statement.
Now you got the 16 different HEX codes for your character. Now you are ready to display your character or message on POV Display.
For messages you need more than one array .
If you are someone with good knowledge of software and can write a code to generate hex codes automatically just by drawing the character then it would be great help. It will save time and make this device more user friendly.
e. Arduino sketch for "HAPPY DIWALI"
int latchPin = 3; // start of program int clockPin = 4; int dataPin = 2; int sensorpin=5; int a=0; int c=0; int lbutst=0; int butst=0; int b4[]={0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, 0x3E,0x50,0x90,0x90,0x90,0x90,0x90,0x90,0x50,0x3E,0x00,0x00,0x00,0x00,0x00,0x00, 0xFE,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 0xFE,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x50,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x40,0x20,0x10,0x0E,0x0E,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00}; int b5[]={0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,0x00,0x00,0x00,0x00, 0x82,0x82,0x82,0x82,0xFE,0xFE,0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00,0x00,0x00, 0xF8,0x04,0x02,0x02,0xFC,0xFC,0x02,0x02,0x04,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0x3E,0x50,0x90,0x90,0x90,0x90,0x90,0x90,0x50,0x3E,0x00,0x00,0x00,0x00,0x00,0x00, 0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00, 0x82,0x82,0x82,0x82,0xFE,0xFE,0x82,0x82,0x82,0x82,0x00,0x00,0x00,0x00,0x00,0x00};
void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(sensorpin,INPUT); }
void loop() { butst=digitalRead(sensorpin); if(butst != lbutst){ if(butst==LOW){ c++; } } lbutst=butst; if(butst==LOW){ if(c<50){ for (int a = 0; a <80; a++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, b4[a]); digitalWrite(latchPin, HIGH); delayMicroseconds(300); } } if(c>50){ if(c<100){ for (int a = 0; a <96; a++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, b5[a]); digitalWrite(latchPin, HIGH); delayMicroseconds(300); } } } if(c>100){ c=0; } } } // end of program
f. Demo video
Comments