English
Español
PCBWAY PCB service

PCBWAY PCB service

PCBONLINE PCB service






Analog POV clock - code


Download the .zip file below. Unzip it and open it in Arduino IDE. Compile and upload.










/* Electronoobs POV dsiplay (Persistance of vision)
 * Subscribe: http://www.youtube.com/c/ELECTRONOOBS
 * Tutorial: http://www.electronoobs.com/eng_arduino_tut21.php */

//Variables for real time count
unsigned long Real_time_millis = 0;
unsigned long Previous_real_time_millis = 0;
float SEC;
float MIN= 45;
float HOUR = 2;
float dots_marker = 0; //Variable used for the 4 red dots

//POV clock cariables
unsigned long currentMillis, elapsed_loop_counter, previousMillis;
unsigned long counter_1, current_count;

//Interruption varaibles to count rotation speed
//We create 4 variables to store the previous value of the input signal (if LOW or HIGH)
byte last_IN_state;               //Here we store the previous state on digital pin 13
float one_rot_time=0;             //Here we store the full rotation time
float time_per_deg=0;             //Here we store the time it takes to make one degree rotation



void setup() {
  PCICR |= (1 << PCIE0);    //enable PCMSK0 scan  
  PCMSK0 |= (1 << PCINT5);  //Enable pin state interruption on pin D13

  //Output pins register configuration
  /* D2 = Blue LED
   * D3 = Red 1 LED
   * D4 = Red 2 LED
   * D5 = Green 1 LED
   * D6 = Green 2 LED
   * D7 = Green 3 LED
   * D8 = Green 4 LED
   * D9 = Green 5 LED
   * D10 = Green 6 LED
   * D11 = Green 7 LED
   * D12 = Green 8 LED
   */
  DDRD |= B11111100;      //2 to 7 as output  
  DDRB |= B00011111;      //8 to 12 as output
  DDRB &= B11011111;      //13 input
  PORTD &= B00000011;     //2 to 7 LOW
  PORTB &= B11100000;     //8 to 12 LOW
}



void loop() {

  //Here we calculate seconds, minutes and hours
  Real_time_millis = millis();  
  
  if(Real_time_millis - Previous_real_time_millis >= 1000){
    Previous_real_time_millis += 1000;
    
    SEC=SEC+1;
    if(SEC > 59)
    {
      SEC=0;
      MIN=MIN+1;
    }
  
    if(MIN > 59)
    {
      MIN = 0;
      HOUR = HOUR+1;
    }
  }//End of real time count

  //Here is our loop counter. elapsed_loop_counter will reset each loop and count the loop time
  //When we reach the amount of time desired we turn ond or off the LEDs
  currentMillis = micros();
  elapsed_loop_counter = currentMillis - previousMillis;

  

 //Print the 4 red dots
  if(elapsed_loop_counter >=  time_per_deg*(dots_marker) &&  elapsed_loop_counter <  time_per_deg*(dots_marker+3)    )
  {
    PORTD |= B00011000; //3,4 HIGH
  }

  if(elapsed_loop_counter >= time_per_deg*(dots_marker+3))
  {
    PORTD &= B11100111;               //3, 4 LOW, the two red LEDs
    dots_marker = dots_marker + 90;
    if(dots_marker >= 360)
    {
      dots_marker = 0;
    }
  }





  //Print the second line
  if(elapsed_loop_counter >=  time_per_deg*(SEC*6) &&  elapsed_loop_counter <  time_per_deg*((SEC*6)+2)    )
  {
    PORTB |= B00011111; //8, 9, 10, 11 and 12 as HIGH
    PORTD |= B11100000; //2 (blue), 5, 6 and 7 as HIGH
  }

  if(elapsed_loop_counter >= time_per_deg*((SEC*6)+2))
  {
    PORTB &= B11100000;
    PORTD &= B00011111; 
  }




   //Print the minute line
  if(elapsed_loop_counter >=  time_per_deg*(MIN*6) &&  elapsed_loop_counter <  time_per_deg*((MIN*6)+1)    )
  {
    PORTB |= B00011111; //8, 9, 10, 11 and 12 as HIGH
    PORTD |= B11000000; //2 (blue), 5, 6 and 7 as HIGH
  }

  if(elapsed_loop_counter >= time_per_deg*((MIN*6)+1))
  {
    PORTB &= B11110000;
    PORTD &= B00111111; 
  }



   //Print the hour line
  if(elapsed_loop_counter >=  time_per_deg*(HOUR*30) &&  elapsed_loop_counter <  time_per_deg*(   (HOUR*30)  +1)   )
  {
    PORTB |= B00011111; //8, 9, 10, 11 and 12 as HIGH
    PORTD |= B00000000; //2 (blue), 5, 6 and 7 as HIGH
  }

  if(elapsed_loop_counter >= time_per_deg*(  (HOUR*30)   +1))
  {
    PORTB &= B11100000;
    PORTD &= B11111111; 
  } 
  
}











ISR(PCINT0_vect){
//First we take the current count value in micro seconds using the micros() function
  
  current_count = micros();
  ///////////////////////////////////////
  if(PINB & B00100000){                              //We make an AND with the pin state register, We verify if pin 13 is HIGH???
    if(last_IN_state == 0){                          //If the last state was 0, then we have a state change...
      last_IN_state = 1;                             //Store the current state into the last state for the next loop
      counter_1 = current_count;                     //Set counter_1 to current value.
    }
  }
  else if(last_IN_state == 1){                       //If pin 13 is LOW and the last state was HIGH then we have a state change      
    last_IN_state = 0;                               //Store the current state into the last state for the next loop
    one_rot_time = current_count - counter_1;        //We make the time difference. one_rot_time 1 is current_count - counter_1.
    time_per_deg = one_rot_time/360.0;
    previousMillis = micros();
   
   }




}