Introduction: Spherical POV

In this project , the concept of persistence of vision (POV) is used to generate a a pattern over a spherical surface using a circular strip of LEDS.The apparatus consists of 15 LEDs in a circular pattern rotating at a high rpm so as to form a persistence in human mind.

Step 1: MATERIALS REQUIRED :

  1. Arduino Nano
  2. 2 Shift Registers (74HC595N)
  3. 15 LED's
  4. 9 V Battery
  5. Protoboard
  6. DC Motor
  7. Lipo Battery
  8. Rotatory Encoder

Step 2: CONNECTIONS

  • CONNECTION FOR SHIFT REGISTERS

  1. (QB) LED 2 +
  2. (QC) LED 3 +
  3. (QD) LED 4 +
  4. (QE) LED 5 +
  5. (QF) LED 6 +
  6. (QG) LED 7 +
  7. (QH) LED 8 +
  8. (GND) GND
  9. (QH*) -
  10. (SRCLR*) 5V
  11. (SRCLK) Digital 3
  12. (RCLK) Digital 4
  13. (OE*) GND
  14. (SER) Digital 2
  15. (QA) LED 1 +
  16. (VCC) 5V

  • Ground for all the LED's should be common and connected to the common ground of arduino and shift register
  • Similar connections can be done for 2nd shift register.

Step 3: CODE :

int datapin = 3;  int clockpin = 6;
int latchpin = 5;
byte data2 = 0;
int datapin2 = 10; 
int clockpin2 = 12;
int latchpin2 = 11;
int encoder_pin = 2;
volatile byte pulses;
long int newt=0 ,oldt=0;
long int interval;
int count = 0;  bool a[15][60]={
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}  ;             
   
   
void setup() {
  Serial.begin(9600);
  pinMode(datapin, OUTPUT);
  pinMode(clockpin, OUTPUT);  
  pinMode(latchpin, OUTPUT);
  pinMode(datapin2, OUTPUT);
  pinMode(clockpin2, OUTPUT);  
  pinMode(latchpin2, OUTPUT);
  attachInterrupt(0, counter, FALLING);
  pulses = 0;
    for(int index = 0; index <= 7; index++)
      {
        bitWrite(data1,index,0);
        shiftOut(datapin, clockpin, MSBFIRST, data1);
        digitalWrite(latchpin, 1);
        digitalWrite(latchpin, 0);
      }
    for(int index = 0; index < 7; index++)
      {
       bitWrite(data2,index,0);
      shiftOut(datapin2, clockpin2, MSBFIRST, data2);
      digitalWrite(latchpin2, 1);
      digitalWrite(latchpin2, 0);
      }
}void counter()
{
   //Update count
   pulses++;
   oldt=newt;
   newt=micros();
   interval=(newt-oldt)/2;
   count=0;
}
void loop() {          
  pulses=pulses%60;
  attachInterrupt(0, counter, FALLING);
  for(int index = 0; index <= 7; index++)
  {
    if (micros()<(newt+interval)){
        bitWrite(data1,index,a[index][60-pulses]);
        shiftOut(datapin, clockpin, MSBFIRST, data1);
        digitalWrite(latchpin, 1);
        digitalWrite(latchpin, 0);}
//        delayMicroseconds(1);
      else{  bitWrite(data1,index,LOW);
        shiftOut(datapin, clockpin, MSBFIRST, data1);
        digitalWrite(latchpin, 1);
        digitalWrite(latchpin, 0);       
     }
   }
   for(int index = 0; index < 7; index++)
   {
      if (micros()<(newt+interval)){
         bitWrite(data2,index,a[index+8][60-pulses]);
         shiftOut(datapin2, clockpin2, MSBFIRST, data2);
         digitalWrite(latchpin2, 1);
         digitalWrite(latchpin2, 0);}
       else{  bitWrite(data2,index,LOW);
         shiftOut(datapin2, clockpin2, MSBFIRST, data2);
         digitalWrite(latchpin2, 1);
         digitalWrite(latchpin2, 0);
      }
   }
   if(micros()>=(newt+interval))
    {
      if(count==0)
      {pulses++;count++;}
      for(int index = 0; index <= 7; index++)
      {
          bitWrite(data1,index,a[index][60-pulses]);
          shiftOut(datapin, clockpin, MSBFIRST, data1);
          digitalWrite(latchpin, 1);
          digitalWrite(latchpin, 0);
          }
      for(int index = 0; index < 7; index++)
      {
          bitWrite(data2,index,a[index+8][60-pulses]);
          shiftOut(datapin2, clockpin2, MSBFIRST, data2);
          digitalWrite(latchpin2, 1);
          digitalWrite(latchpin2, 0);
       }
    }
      Serial.println(pulses);
}

Step 4: POSSIBLE IMPROVEMENTS:

  • Motor with inbuild encoder to be used to increase the accuracy.
  • Mass must be accurately balanced with appropriate support .
  • SMDs can be used instead of leds .