Digital Clock



DIGITAL CLOCK

ABSTRACT
In this activity I’ve made a digital clock with Arduino, a RTC module and a module of four 7 segment display.
Arduino UNO with the RTC and the diplay module
COMPONENTS 
1 x Arduino board
1 x USB cable
1 x RTC module
1 x four 7-segments display module
17 x Wires

DEVELOPMENT
The Real Time Counter is connected to Arduino by the bus I2C. This issue is very easy with the library “Wire.h” that provide the Arduino IDE. At the beginning of the program, the code gets the date from this module and is printed on the serial monitor. Then, in the loop function, the uC asks to the RTC what hour is. The hour is  in seconds, minutes and hours. This information is displayed with the 7-segment module.
I2C RTC DS1307 Real Time Clock Module and 4X LED Display Digital Tube Module for Arduino buy on Deal Extreme

The hour, minutes and seconds is obtained from the RTC with integer variables in the lines:
hora=now.hour();
minuto=now.minute();
segundo=now.second();
One display can only show one digit, however, the numbers can have two digit. It is necessary to split these numbers in single digits. The following lines solve this problem.
 //For showing the hour and the minutes. For instance:19:50
  int numeros[]={hora/10,hora-10*(hora/10),minuto/10,minuto-10*(minuto/10)};
  //For showing the minutes and seconds
  //int numeros[]={minuto/10,minuto-10*(minuto/10),segundo/10,segundo-10*(segundo/10)};
For example, if hora=9 and minuto=43, numeros[] will be:

numeros[0]=hora/10=9/10=0
numeros[1]=hora-10*(hora/10)=9-10*(9/10)=9-10*(0)=9-0=9
numeros[2]=minuto/10=43/10=4
numeros[3]=minuto-10*(minuto/10)=43-10*(43/10)=43-10*(4)=43-40=3
Finally, the displays will show the digits: 0,9,4,3

The module of 7-segment displays is connected to Arduino using one wire to 5 volts and twelve wires to the digital outputs. Four of them are for switching on/off each displays. The other eight outputs are used for controlling the seven segments and the dot. All the leds are shared by the displays and must be 'multiplexed' with D1-4 for controlling the switching on of each display of 7 segments. 
Name of the leds in the displays of 7 segment
The wires are connected to Arduino in this order:
#define D4     13
#define D3     12
#define D2     11
#define D1     10
#define LED_a  9
#define LED_b  8
#define LED_c  7
#define LED_d  6
#define LED_e  5
#define LED_f  4
#define LED_g  3
#define LED_dp 2

RESULTS 
In the following video it is displayed the code of the Appendix 1. Here you can see a digital clock that only shows the minutes and seconds. 


I've added another code in the Appendix 2 that scrolls a number of four digits in both directions. Also, there are others functions that show a number permanently or blink a number of four digits. In the next video you are going to see the scroll to the right and to the left of two numbers of four digits.



REFERENCES



APPENDIX 1
Arduino main code:
#include <Wire.h>
#include <RTC.h>

#define D4     13
#define D3     12
#define D2     11
#define D1     10
#define LED_a  9
#define LED_b  8
#define LED_c  7
#define LED_d  6
#define LED_e  5
#define LED_f  4
#define LED_g  3
#define LED_dp 2

boolean seven_seg_digits[10][8] = {{1,1,1,1,1,1,0,0},  // = 0
                                   {0,1,1,0,0,0,0,0},  // = 1
                                   {1,1,0,1,1,0,1,0},  // = 2
                                   {1,1,1,1,0,0,1,0},  // = 3
                                   {0,1,1,0,0,1,1,0},  // = 4
                                   {1,0,1,1,0,1,1,0},  // = 5
                                   {1,0,1,1,1,1,1,0},  // = 6
                                   {1,1,1,0,0,0,0,0},  // = 7
                                   {1,1,1,1,1,1,1,0},  // = 8
                                   {1,1,1,0,0,1,1,0},  // = 9
                                 };   

// RTC class based on the DS1307 chip connected via I2C and the Wire library
RTC_DS1307 RTC;

//Simple general-purpose date/time class
DateTime now;

//Initializing the variables
char Date[15],Hour[15];
int hora,minuto,segundo;

void setup()
{
  Serial.begin(9600); // Set serial out for debugging
  pinMode(2, OUTPUT);//LED_dp 
  pinMode(3, OUTPUT);//LED_g
  pinMode(4, OUTPUT);//LED_f
  pinMode(5, OUTPUT);//LED_e
  pinMode(6, OUTPUT);//LED_d
  pinMode(7, OUTPUT);//LED_c
  pinMode(8, OUTPUT);//LED_b
  pinMode(9, OUTPUT);//LED_a
  pinMode(10, OUTPUT);//D1
  pinMode(11, OUTPUT);//D2
  pinMode(12, OUTPUT);//D3
  pinMode(13, OUTPUT);//D4

  //Clear the four display
  digitalWrite(D1,HIGH);//D1 OFF
  digitalWrite(D2,HIGH);//D2 OFF
  digitalWrite(D3,HIGH);//D3 OFF
  digitalWrite(D4,HIGH);//D4 OFF
 
  RTCInit();//Initializes the RTC module
  delay(1000);
}

void loop()
{
  now = RTC.now();//Reading the current date and the hour
  hora=now.hour();
  minuto=now.minute();
  segundo=now.second();
  sprintf(Hour,"Hour= %d:%d:%d",hora,minuto,segundo);
  Serial.println(Hour);
 
  //For showing the hour and the minutes. ej:19:50
  //int numeros[]={hora/10,hora-10*(hora/10),minuto/10,minuto-10*(minuto/10)};
  //For showing the minutes and seconds
  int numeros[]={minuto/10,minuto-10*(minuto/10),segundo/10,segundo-10*(segundo/10)};
 
  for(int i=0;i<4;i++)
  {
    digitalWrite(10+i,LOW);
    for (byte segCount = 0; segCount < 8; ++segCount)
    {
       digitalWrite(9-segCount,!seven_seg_digits[numeros[i]][segCount]);
       if(i==1) digitalWrite(LED_dp,LOW);//The second dot bright
    }
    delay(5);
    digitalWrite(10+i,HIGH);
  }
}

void RTCInit(void)
{
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));
  delay(10);//A moment for the uC breathes a little
  now = RTC.now();
  //Prepararing a string of characters for debugging
  sprintf(Date,"Date:%d/%d/%d",now.day(),now.month(),now.year()-2000);//Format:3/10/12
  Serial.println(Date);
  Serial.println();
}

APPENDIX 2

Arduino 7-segment example code:
#include <Wire.h>
#include <RTC.h>

#define D4     13
#define D3     12
#define D2     11
#define D1     10
#define LED_a  9
#define LED_b  8
#define LED_c  7
#define LED_d  6
#define LED_e  5
#define LED_f  4
#define LED_g  3
#define LED_dp 2
#define LEDred 1
#define BUZZER 0

boolean seven_seg_digits[10][8] = {{1,1,1,1,1,1,0,0},  // = 0
                                   {0,1,1,0,0,0,0,0},  // = 1
                                   {1,1,0,1,1,0,1,0},  // = 2
                                   {1,1,1,1,0,0,1,0},  // = 3
                                   {0,1,1,0,0,1,1,0},  // = 4
                                   {1,0,1,1,0,1,1,0},  // = 5
                                   {1,0,1,1,1,1,1,0},  // = 6
                                   {1,1,1,0,0,0,0,0},  // = 7
                                   {1,1,1,1,1,1,1,0},  // = 8
                                   {1,1,1,0,0,1,1,0},  // = 9
                                 };                     
 
void setup()
{
  Serial.begin(9600);//Initilizes serial port
  pinMode(0, OUTPUT);//Buzzer 
  pinMode(1, OUTPUT);//Red led
  pinMode(2, OUTPUT);//LED_dp 
  pinMode(3, OUTPUT);//LED_g
  pinMode(4, OUTPUT);//LED_f
  pinMode(5, OUTPUT);//LED_e
  pinMode(6, OUTPUT);//LED_d
  pinMode(7, OUTPUT);//LED_c
  pinMode(8, OUTPUT);//LED_b
  pinMode(9, OUTPUT);//LED_a
  pinMode(10, OUTPUT);//D1
  pinMode(11, OUTPUT);//D2
  pinMode(12, OUTPUT);//D3
  pinMode(13, OUTPUT);//D4

  //Clear the four display
  digitalWrite(D1,HIGH);//D1 OFF
  digitalWrite(D2,HIGH);//D2 OFF
  digitalWrite(D3,HIGH);//D3 OFF
  digitalWrite(D4,HIGH);//D4 OFF
 
  delay(1000);
}

void loop()
{
  //DisplayNumber(2734,5,0);//Display a permanent number with 5 ms of delay
  //delay(1000);//If the second variable is near to zero, the number will be static
  //DisplayNumber(3451,200,0);//Display a permanent number with 200 ms of delay
  //delay(1000);
  //DisplayNumber(1512,200,1);//The same as before but move the numbers to the right
  //delay(1000);             
  LeftScroll(1234,200);//Scroll left
  //delay(1000);
  //RightScroll(8654,200);//Scroll right
  //delay(1000);
  //blinkNumber(4721,100);//
}

int * extractDigit(int numero)
{
  int millares=numero/1000;
  int centenas=(numero-1000*millares)/100;
  int decenas=(numero-1000*millares-100*centenas)/10;
  int unidades=(numero-1000*millares-100*centenas-10*decenas);
  static int digitos[4]={millares,centenas,decenas,unidades};
  //‘static’ es la puta clave para pasar el array
  return digitos;
}

void sevenSegWrite(byte digit)
{
  for (byte segCount = 0; segCount < 8; ++segCount)
  {
     digitalWrite(9-segCount,!seven_seg_digits[digit][segCount]);
  }
}

void DisplayNumber(int numero,int scrollSpeed,int direccion)
{
  int millares=numero/1000;
  int centenas=(numero-1000*millares)/100;
  int decenas=(numero-1000*millares-100*centenas)/10;
  int unidades=(numero-1000*millares-100*centenas-10*decenas);
  int numeros[]={millares,centenas,decenas,unidades};
  if(direccion==1)//left to right
  {
    for(int i=0;i<4;i++)
    {
      digitalWrite(10+i,LOW);
      sevenSegWrite(numeros[i]);
      delay(scrollSpeed);
      digitalWrite(10+i,HIGH);
    }
  }
  else //right to left
  {
    for(int i=3;i>=0;i--)
    {
      digitalWrite(10+i,LOW);
      sevenSegWrite(numeros[i]);
      delay(scrollSpeed);
      digitalWrite(10+i,HIGH);
    }
  }
}

void LeftScroll(int numero,int scrollSpeed)
{
  int *numeros;
  numeros= extractDigit(numero);
  delay(6000);
  for(int i=3;i>=0;i--)
  {
    digitalWrite(10+i,LOW);
    sevenSegWrite(*(numeros+i));
    delay(scrollSpeed);
    digitalWrite(10+i,HIGH);
  }
}

void RightScroll(int numero,int scrollSpeed)
{
  int * numeros = extractDigit(numero);
  for(int i=0;i<4;i++)
  {
    digitalWrite(10+i,LOW);
    sevenSegWrite(*(numeros+i));
    delay(scrollSpeed);
    digitalWrite(10+i,HIGH);
  }
}


void blinkNumber(int numero,int blinkSpeed)
{
  int * numeros = extractDigit(numero);
  for(int i=0;i<4;i++)
  {
    digitalWrite(10+i,LOW);
    sevenSegWrite(*(numeros+i));
    delay(2);
    digitalWrite(10+i,HIGH);
  }
  delay(blinkSpeed);
  for(int i=0;i<4;i++)
  {
    digitalWrite(10+i,LOW);
    sevenSegWrite(*(numeros+i));
    delay(2);
    digitalWrite(10+i,HIGH);
  }
}