/*############################################################################
Codigo criado por: MarioParente
Data: 30/06/2023
Detalhes do projeto: v1.1 - Relogio digital RTC Modificado para Attiny
############################################################################*/

//#include <TinyWireM.h>
#include <TinyRTClib.h>
#include <TinyLiquidCrystal_I2C.h>

//#####    Definições    #######
#define Bot_Menu  4
#define Bot_Mudar 1


//#####    Variaveis    #######
char Aux = 0;                       // Auxilia a contagem de tempo para acessar o Munu de configuração
int Menu = 0;                       // Guarda o Menu atual
int Espaco = 0;                     // Guarda o espaço de alteração
int Alterar_1 = 0;                  // Numero a ser alterado
int Alterar_2 = 0;                  // Decinal a ser alterado

int dd = 0;                         // Guarda o valor do dia
int MM = 0;                         // Guarda o valor do mês
int yy = 0;                         // Guarda o valor do ano
int hh = 0;                         // Guarda o valor da hora
int mm = 0;                         // Guarda o valor do minuto
int ss = 0;                         // Guarda o valor do segundo


//#####    Objetos    #######
TinyLiquidCrystal_I2C lcd(0x27,16,2);
RTC_DS1307 rtc;                     //Objeto rtc da classe DS1307
//RTC_DS3231 rtc;                   //Objeto rtc da classe DS3132

//#####    Lista    #######
char Dias[7][12] = {                //Dias da semana
  "Dom ",
  "Seg ",
  "Ter ",
  "Qua ",
  "Qui ",
  "Sex ",
  "Sab "
  }; 

byte Doid_pontos [8] = {            // Caractere especial 1
  0b00000,  0b00000,  0b01000,
  0b00000,  0b00000,  0b01000,
  0b00000,  0b00000,
};

byte Seta[8] = {                   // Caractere especial 2
  0b00100,  0b01110,  0b10101,
  0b00100,  0b00100,  0b00100,
  0b00100,  0b00000
};

void setup () {
 // TinyWireM.begin();                  // Inicia a cominicação
  lcd.init();                           // Inicia a cominicação com LDC
  lcd.createChar(1, Doid_pontos);       // Cria salva o caractere especial na memororia do LDC
  lcd.createChar(2, Seta);              // Cria salva o caractere especial na memororia do LDC
  lcd.setBacklight(HIGH);               // Ativa a luz do LCD
  pinMode(Bot_Menu, INPUT_PULLUP);      // Configuração de botao
  pinMode(Bot_Mudar, INPUT_PULLUP);     // Configuração de botao
  if (! rtc.begin()) {                  // Se o RTC nao for inicializado
  lcd.setCursor(0,0);
    lcd.print("RTC NAO INICIALIZADO");  // Imprime o texto
    while (1);                          // Para de iniciar o restante do codigo
  }
  delay(100);                           // 1/10 de segundo
}

void loop () {
  delay(1000);                          // 1 de segundo
  if(!digitalRead(Bot_Menu)){           // Se o botao mudar de estado
    Aux += 1;                           // Incrementa +1
  }

  else{                                 // se não, volta para 0
    Aux = 0;
  }

  if(Aux == 3){                         // Se o valor for igual a 3
    Menu = 1;                           // Define o valor de menu para 1
  }

  switch (Menu) {                       // Testa o Menu
    case 0:                             // Se o Menu for 0
      Exibir_DataHota();                // Chama a função
    break;                              // Retorna para testar novamente o Menu

    case 1:                             // Se o Menu for 1
      lcd.clear();                      // Limpa o display
      lcd.setCursor(0,0);               // Fixa uma posição no LCD para impressão
      lcd.print("Alteracao!");          // Imprime no LCD
      lcd.setCursor(0,1);               // Fixa uma posição no LCD para impressão
      lcd.print("Data e Hora");         // Imprime no LCD
      delay(200);                       // Aguarda 2/10 Segundos
      Aux = 10;                         // Muda o valor para 10
      Aux_Menu_ajuste();                // Chamada a função de auxilio da atualizacao da data e hora
    break;

    default:                            // Se o Menu for diferente de 0 ou 1 não faz nada
    break;
  }
}

void Exibir_DataHota(){                  // Função de exibição da data e hora no LCD
  DateTime agora = rtc.now();            // Faz a leitura de dados de data e hora do modulo RTC 
  dd = (agora.day());                    // Guarda o valor do dia
  MM = (agora.month());                  // Guarda o valor do Mes
  yy = (agora.year());                   // Guarda o valor do Ano
  hh = (agora.hour());                   // Guarda o valor do hora
  mm = (agora.minute());                 // Guarda o valor do minuto
  ss = (agora.second());                 // Guarda o valor do segundo

  lcd.setCursor(1,0);                    // Fixa uma posição no LCD para impressão
  lcd.print(Dias[agora.dayOfWeek()]);    // Imprime dia da semana
  lcd.print(dd/10);                      // Imprime o segundo digito
  lcd.print(dd%10);                      // Imprime o primeiro digito
  lcd.print("/");                        // Imprime uma "/"
  lcd.print(MM/10);                      // Imprime o segundo digito
  lcd.print(MM%10);                      // Imprime o primeiro digito
  lcd.print("/");                        // Imprime uma "/"
  lcd.print(yy);                         // Imprime ano com 4 digitos
  lcd.setCursor(1,1);                    // Fixa uma posição no LCD para impressão
  lcd.print("Hora\x01 ");                // Imprime a palavra "HORA" depois o caractere especial "Doid_pontos" e um espaço
  lcd.print(hh/10);                      // Imprime o segundo digito
  lcd.print(hh%10);                      // Imprime o primeiro digito
  lcd.print("\x01");                     // Imprime o caractere especial "Doid_pontos"
  lcd.print(mm/10);                      // Imprime o segundo digito
  lcd.print(mm%10);                      // Imprime o primeiro digito
  lcd.print("\x01");                     // Imprime o caractere especial "Doid_pontos"
  lcd.print(ss/10);                      // Imprime o segundo digito
  lcd.print(ss%10);                      // Imprime o primeiro digito
}

void Aux_Menu_ajuste(){                  // Função Auxiliar de ajusta de data
  while(digitalRead(Bot_Menu)==LOW){     // Aguarda o botao ser despressionando
    delay(200);                          // Aguarda 2/10 Segundos
  }
  lcd.clear();                           // Limpa o display
  DateTime agora = rtc.now();            // Faz a leitura de dados de data e hora do modulo RTC 
  dd = (agora.day());                    // Guarda o valor do dia
  MM = (agora.month());                  // Guarda o valor do Mes
  yy = ((agora.year())%1000);            // Guarda apenas os 2 ultimos digitos do ano.
  hh = (agora.hour());                   // Guarda o valor do hora
  mm = (agora.minute());                 // Guarda o valor do minuto
  Menu_Ajuste();                         // Chamada a função de atualizar a data e hora
}

void Menu_Ajuste(){
 
  lcd.setCursor(0,0);
  lcd.print("Alterar ");                 // Imprime a palavra "Alterar e um espaço"
  lcd.print(dd/10);                      // Imprime o segundo digitoa
  lcd.print(dd%10);                      // Imprime o primeiro digito
  lcd.print('/');                        // Imprime uma "/"
  lcd.print(MM/10);                      // Imprime o segundo digito
  lcd.print(MM%10);                      // Imprime o primeiro digito
  lcd.print('/');                        // Imprime uma "/"
  lcd.print(yy);                         // Imprime ano

  while(Aux >=9){
    switch (Aux) {                       // Testa o Aux
      case 10:                           // Se o Aux for 10 altera o 1ª digito Dia
        Alterar_2 = dd/10;               // Extrai o 2 digito do dia
        Alterar_1 = dd%10;               // Extrai o 1 digito do dia
        Espaco = 8;                      // Quantidade de caracteres
        lcd.setCursor(Espaco,0);         // Fixa uma posição no LCD para impressão
        lcd.print(Alterar_2);
        Espaco = 9;
        lcd.setCursor(Espaco,0);
        lcd.print(Alterar_1);   
        lcd.setCursor(0,1);
        lcd.print("Dia");        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 10){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_1);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_1 ++ >= 9){
              Alterar_1 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
              while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 11;            
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
          }
        }
      break;

      case 11:
        Espaco = 8;      
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 11){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_2);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_2 ++ >= 3){
              Alterar_2 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 12;            
            Alterar_2 = (Alterar_2*10) + Alterar_1;
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);           
            if(Alterar_2 > 31 || Alterar_2 == 0){                        //Degub de erro no dia             
              lcd.setCursor(0,1);
              lcd.print("Erro encontrado!");                       //Imprime mensagem de erro
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("Verificar Dia!   ");                      //Os 2 espaço ao final e para limpar a mensagem anterior
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("                ");                       //Limpa a linha inferior do LCD
              Aux = 10;
            }
            else{
              dd = Alterar_2;
            }
          }          
        }        
      break;

      case 12:
        Alterar_2 = MM/10;
        Alterar_1 = MM%10;
        Espaco = 11;
        lcd.setCursor(Espaco,0);
        lcd.print(Alterar_2);
        Espaco = 12;
        lcd.setCursor(Espaco,0);
        lcd.print(Alterar_1);       
        lcd.setCursor(0,1);
        lcd.print("Mes");        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_1 = MM%10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 12){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_1);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_1 ++ >= 9){
              Alterar_1 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 13;            
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
          }
        }        
      break;

      case 13:                    // 
        Espaco = 11;
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_2 = MM/10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 13){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_2);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_2 ++ >= 1){
              Alterar_2 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 14;            
            Alterar_2 = (Alterar_2*10) + Alterar_1;
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
            if(Alterar_2>12||Alterar_2==0){                         //Degub de erro no dia              
              lcd.setCursor(0,1);
              lcd.print("Erro encontrado!");                       //Imprime mensagem de erro
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("Verificar Mes!   ");                      //Os 2 espaço ao final e para limpar a mensagem anterior
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("                ");                       //Limpa a linha inferior do LCD
              Aux = 12;
            }
            else{
              MM = Alterar_2;
            }
          }          
        }
      break;

      case 14:                    // 
        Espaco = 15;       
        lcd.setCursor(0,1);
        lcd.print("Ano");        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_1 = yy%10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 14){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_1);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_1 ++ >= 9){
              Alterar_1 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 15;            
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
          }
        }        
      break;

      case 15:                    // 
        Espaco = 14;        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_2 = yy/10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 15){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_2);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_2 ++ >= 9){
              Alterar_2 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 16;           
            yy = (Alterar_2*10)+Alterar_1;
            lcd.clear();
            delay(200);           
          }
        }
      break;

      case 16:                    // 
        Alterar_2 = hh/10;
        Alterar_1 = hh%10;       
        lcd.setCursor(0,0);
        lcd.print("Alterar ");
        lcd.print(hh/10);                         //Imprime hora
        lcd.print(hh%10);
        lcd.print('\x01');                     // Imprime o caractere especial "Doid_pontos"
        lcd.print(mm/10);                       //Imprime minuto
        lcd.print(mm%10);
        Espaco = 9;
        lcd.setCursor(0,1);
        lcd.print("Hora");        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 16){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_1);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_1 ++ >= 9){
              Alterar_1 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 17;          
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);           
          }
        }
      break;

      case 17:                    // 
        Espaco = 8;        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_2 = hh/10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 17){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_2);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_2 ++ >= 2){
              Alterar_2 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 18;
            Alterar_2 = (Alterar_2*10)+Alterar_1;
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);           
            if(Alterar_2>23){                                      //Degub de erro no dia              
              lcd.setCursor(0,1);
              lcd.print("Erro encontrado!");                       //Imprime mensagem de erro
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("Verificar Hora! ");                      //Os 2 espaço ao final e para limpar a mensagem anterior
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("                ");                       //Limpa a linha inferior do LCD
              Aux = 10;              
            }
            else{
              hh = Alterar_2;
            }
          }
        }
      break;

      case 18:                    // 
        Espaco = 12;
        lcd.setCursor(0,1);
        lcd.print("Minuto");        
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_1 = mm%10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 18){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_1);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_1 ++ >= 9){
              Alterar_1 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 19;         
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
          }
        }        
      break;

      case 19:                    // Caso 40 Swict 2 - 2ª digito minut
        Espaco = 11;       
        lcd.setCursor(Espaco,1);
        lcd.print("\x02");
        Alterar_2 = mm/10;
        while(digitalRead(Bot_Menu)==LOW){
          delay(100);  //Não faz nada
        }
        while(Aux == 19){
          lcd.setCursor(Espaco,0);
          lcd.print(Alterar_2);
          if (!digitalRead(Bot_Mudar)){
            delay(200);           
            if (Alterar_2 ++ >= 5){
              Alterar_2 = 0;
            }
          }
          if (!digitalRead(Bot_Menu)){
            while(digitalRead(Bot_Menu)==LOW){
                delay(100);  //Não faz nada
              }
            Aux = 20;           
            Alterar_2 = (Alterar_2*10)+ Alterar_1;
            lcd.setCursor(Espaco,1);
            lcd.print(" ");
            delay(200);            
            if(mm>60){                                              //Degub de erro no minuto              
              lcd.setCursor(0,1);
              lcd.print("Erro encontrado!");                       //Imprime mensagem de erro
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("Verificar Minuto");                      //Os 2 espaço ao final e para limpar a mensagem anterior
              delay(1500);
              lcd.setCursor(0,1);
              lcd.print("                ");                       //Limpa a linha inferior do LCD
              Aux = 110;
              Aux_Menu_ajuste();
            }
            else{
              mm = Alterar_2;
            }
          }
        }
      break;

      case 20:                    // Finalizado        
        lcd.setCursor(0,1);
        lcd.print("Data Configurada");
        rtc.adjust(DateTime(yy+2000, MM, dd, hh, mm, 00));     //Envia data para o RTC
        delay(1500);
        lcd.clear();
        Aux = 0;
        Menu = 0;
      break;
    } 
  }
}


ATTINY8520PU
GND5VSDASCLSQWRTCDS1307+