#ifndef virtuabotixRTC_H                                                                                 //|
#define virtuabotixRTC_H                                                                                 //|
                                                                                                         //|
#include <stddef.h>                                                                                      //|
  #include <string.h>                                                                                    //|
                                                                                                         //|
#if defined(ARDUINO) && ARDUINO >= 100                                                                   //|
  #include "Arduino.h"                                                                                   //|
  #else                                                                                                  //|
    #include "WProgram.h"                                                                                //|
    #include <pins_arduino.h>                                                                            //|
#endif                                                                                                   //|
                                                                                                         //|
//=======================================================================================================//|
//                                                                                                       //|
//                                          Include Guards Break                                         //|
//                                                                                                       //|
//=======================================================================================================//|


//=======================================================================================================//|
//                                                                                                       //|
//                                   Defines Required for Library Begin                                  //|
//                                                                                                       //|
//=======================================================================================================//|
                                                                                                         //|
#define DS1302_ENABLE            0x8E                                                                    //|
#define DS1302_TRICKLE           0x90                                                                    //|
                                                                                                         //|
//=======================================================================================================//|
//                                                                                                       //|
//                                     Defines Required for Library End                                  //|
//                                                                                                       //|
//=======================================================================================================//|


//=======================================================================================================//|
//                                                                                                       //|
//			             virtuabotixRTC Class Declaration Begin                              //|
//                                                                                                       //|
//=======================================================================================================//|
//                                                                                                       //|
//  virtuabotixRTC - Creates the Real Time Clock object, and contains all of the functions that are      //|
//                   required for setting, and tracking the time, as well as converting that time into   //|
//                   the current UNIX Time.                                                              //|
//                                                                                                       //|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//|
                                                                                                         //|
class virtuabotixRTC  {                                                                                  //|
  public:                                                                                                //|
//+++++++++++++++++++++++++++++++++++++++++++++ Class Constructor +++++++++++++++++++++++++++++++++++++++//|  
    virtuabotixRTC(uint8_t inSCLK, uint8_t inIO, uint8_t inC_E);                                                     //|
                                                                                                         //|
//++++++++++++++++++++++++++++++++++++++++++++++ Class Functions ++++++++++++++++++++++++++++++++++++++++//|  
    void initRTC(uint8_t CLK, uint8_t IO, uint8_t ENABLE);     // Sets the pins and enable them          //|
    void DS1302_clock_burst_read( uint8_t *p);                 // Reads clock data, and sets pinmode     //|
    void DS1302_clock_burst_write( uint8_t *p);                // Writes clcok data, and sets pinmode    //|
    uint8_t DS1302_read(int address);                          // Reads a byte from DS1302, sets pinmode //|
    void DS1302_write( int address, uint8_t data);             // Writes a byte to DS1302, sets pinmode  //|
    void _DS1302_start( void);                                 // Function to help setup start condition //|
    void _DS1302_stop(void);                                   // Function to help stop the communication//|
    uint8_t _DS1302_toggleread( void);                         // Function to help read byte with bit    //|
    void _DS1302_togglewrite( uint8_t data, uint8_t release);  // Function to help wrtie byte with bit   //|
    void setDS1302Time(uint8_t seconds, uint8_t minutes,       // This function sets the time on the     //|
                       uint8_t hours, uint8_t dayofweek,       // DS1302                                 //|
                       uint8_t dayofmonth, uint8_t month,                                                //|
                       int year);                                                                        //|
    void updateTime();                                         // This function simply updates the time  //|
                                                                                                         //|
//++++++++++++++++++++++++++++++++++++++++++++++ Class variables ++++++++++++++++++++++++++++++++++++++++//|
    uint8_t SCLK;                                                                                        //|
    uint8_t IO;                                                                                          //|
    uint8_t C_E;                                                                                         //|
    uint8_t seconds;                                                                                     //|
    uint8_t minutes;                                                                                     //|
    uint8_t hours;                                                                                       //|
    uint8_t dayofweek;                                                                                   //|
    uint8_t dayofmonth;                                                                                  //|
    uint8_t month;                                                                                       //|
    int year;                                                                                            //|
};                                                                                                       //|
                                                                                                         //|
//=======================================================================================================//|
//                                                                                                       //|
//                                  virtuabotixRTC Class Declaration End                                 //|
//                                                                                                       //|
//=======================================================================================================//|
                                                                                                         //|
#endif                                                         // versalinoRTC_H                         //|
                                                                                                         //|
//=======================================================================================================//|
//                                                                                                       //|
//                                          Include Guards End                                           //|
//                                                                                                       //|
//=======================================================================================================//|



//#include <virtuabotixRTC.h> //Libreria
//#include <virtuabotixRTC.h> //Libreria
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// CLK -> 6, DAT -> 7, RST -> 8 Para DS1302

virtuabotixRTC myRTC(6, 7, 8);
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Caracteres customizados para crear numeros grandes.
uint8_t DEFINICION_CARACTERES[8][8] = {
  { //Esquina superior izquierda
    B00111,
    B01111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { // Cuadro entero
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { ///Esquina inferior izquierda
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B01111,
    B00111
  },
  { //Esquina superior derecha
    B11100,
    B11110,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { //Esquina inferior dereccha
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11110,
    B11100
  },
  { //Punto bajo
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { //Punto alto
    B11111,
    B11111,
    B11111,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000
  },
  {// punto fino
    B00000,
    B00000,
    B00000,
    B00000,
    B11100,
    B11100,
    B11100,
    B11100
  }
};

const char DEFINICION_NUMEROS[10][4][4] = {
  { // Definición del 0
    {  0,  1,  1,  3 },
    {  1, 32, 32,  1 },
    {  1, 32, 32,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 1
    {  0,  1,  1, 32 },
    { 32,  1,  1, 32 },
    { 32,  1,  1, 32 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 2
    {  0,  1,  1,  3 },
    {  5,  5,  5,  1 },
    {  1,  6,  6,  6 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 3
    {  0,  1,  1,  3 },
    { 32,  5,  5,  1 },
    { 32,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 4
    {  0, 32, 32,  3 },
    {  1,  5,  5,  1 },
    {  6,  6,  6,  1 },
    { 32, 32, 32,  4 }
  },
  { // Definición del 5
    {  0,  1,  1,  3 },
    {  1,  5,  5,  5 },
    {  6,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 6
    {  0,  1,  1,  3 },
    {  1,  5,  5,  5 },
    {  1,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 7
    {  0,  1,  1,  3 },
    { 32, 32, 32,  1 },
    { 32, 32, 32,  1 },
    { 32, 32, 32,  4 }
  },
  { // Definición del 8
    {  0,  1,  1,  3 },
    {  1,  5,  5,  1 },
    {  1,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 9
    {  0,  1,  1,  3 },
    {  1,  5,  5,  1 },
    {  6,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
};

// Función que muestra un dígito a partir de la columna indicada
void mostrarDigito(int digito, int columna) {
  for (int fila = 0; fila < 4; fila++) {
    lcd.setCursor(columna, fila);
    for (int caracter = 0; caracter < 4; caracter++) {
      lcd.print(DEFINICION_NUMEROS[digito][fila][caracter]);
    }
  }
}

void setup() {
  Serial.begin(9600);   // Activa serial
  lcd.init();           // Inicia lcd
  lcd.backlight();      // Enciende retroiluminacion
  lcd.clear();

  // Creamos los nuevos caracteres
  for (int i = 0; i < 8; i++) {
    lcd.createChar(i, DEFINICION_CARACTERES[i]);
  }
}

// Las variable las inicializamos a -1 para asegurarnos que al inicio "detecta un cambio" y "refresca" el valor mostrándolo
int anteriorHora = -1;                  // Para saber cuando cambia la hora y "refrescarla"
int anteriorMinuto = -1;                // Para saber cuando cambia el minuto y "refrescarlo"
int anteriorSegundo = -1;               // Para saber cuando cambia el segundo y saber cuándo se han de mostrar los dos puntos

unsigned long instanteAnterior = 0;     // Para controlar cuando han pasado 500 milisegundos desde que se mostraron los dos puntos
bool esperandoOcultarDosPuntos = false; // Para saber cuando se está esperando a ocultar los dos puntos

void loop() {
  myRTC.updateTime();   // Esta función actualiza las variables para obtener resultados actuales
  if (anteriorHora != myRTC.hours) {    // Si cambia el valor de la hora la muestra
    anteriorHora = myRTC.hours;
    mostrarDigito((myRTC.hours / 10) % 10, 0);
    mostrarDigito(myRTC.hours % 10, 5);
  }
  if (anteriorMinuto != myRTC.minutes) {  // Si cambia el valor de los minutos los muestra
    anteriorMinuto = myRTC.minutes;
    mostrarDigito((myRTC.minutes / 10) % 10, 11);
    mostrarDigito(myRTC.minutes % 10, 16);
  }
  if (anteriorSegundo != myRTC.seconds) { // Si cambia el valor de los segundos, muestra los dos puntos
    anteriorSegundo = myRTC.seconds;
    lcd.setCursor(10, 1);
    lcd.print((char)7);
    lcd.setCursor(10, 2);
    lcd.print((char)7);
    instanteAnterior = millis();          // Guardamos el instante actual para saber cuándo transcurren 500 milisegundos
    esperandoOcultarDosPuntos = true;     // Indicamos que se está esperando a ocultar los dos puntos
  }
  if ((esperandoOcultarDosPuntos == true) && ((millis() - instanteAnterior) >= 500)) {  // Si se está esperando ocultar los dos puntos y han pasado medio segundo
    esperandoOcultarDosPuntos = false;
    lcd.setCursor(10, 1);
    lcd.print(' ');
    lcd.setCursor(10, 2);
    lcd.print(' ');
  }
}
GND5VSDASCLSQWRTCDS1307+