RuiViana

Relogio_Versatil_HSf

Nov 19th, 2016
179
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.    Nome do Projeto:  Relogio_Versatil
  3.    Nome do Aquivo:   Relogio_Versatil.ino
  4.    link:
  5.    Dependencias:     N/A
  6.    MCU:              ATmega
  7.    Board:            Arduino Uno/Mega/Mini
  8.    Compilador        N/A
  9.    IDE:              Arduino IDE 1.0.6
  10.    Hardware:         Arduino UNO/MEGA/Mini
  11.    Escrito por:      Rui Viana
  12.    Modificado por:   N/A
  13.    Data:             dd/mm/2015
  14.    Uso:              Didático
  15.    Desenhos          N/A
  16.    Copyright @       N/A
  17.  
  18.    Este programa é software livre;
  19.    e é distribuído na esperança que possa ser útil, mas SEM QUALQUER GARANTIA;
  20.    mesmo sem a garantia implícita de COMERCIALIZAÇÃO ou ADEQUAÇÃO A UM DETERMINADO FIM.
  21.  
  22.    REVISIONS: (latest entry first)
  23.    14/11/2016   -   Relogio_Versatil.ino - First release
  24.  
  25.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26.    Descrição:
  27.  
  28.    Este código foi escrito para ser usado com ou sem RTC e com opção de LCD stantard ou I2C.
  29.    Ele determina se tem ou não RTC conectado.
  30.    Caso tenha ele usa a hora e a data do RTC, e a data e hora estão sempre atualizadas,
  31.    se não, esta data e hora deverão ser ajustadas, e elas se perdem valor ao dar reset ou
  32.    desligar o arduino.
  33.    Ele é um relogio e um despertador
  34.    O ajuste de cada item é feito deslocando o cursor do LCD com os botões direita e esquerda
  35.    para selecionar o item e mais e menos para incrmentar e decrementar o item.
  36.    As movimentações seguem assim:  rel =  relogio  alm = despertador
  37.    |-----------------<<--------------------------------<<-------------------------|
  38.    |--> Hora rel.--> Minuto rel.--> Segundo rel.--> Dia rel--> Mes rel.-->        |
  39.    Ano rel.--> reset alarme--> Hora alm.--> Minuto alm.--> Segundo alm.-->        |
  40.    Dia alm--> Mes rel.--> Ano rel.------------------------------------------------|
  41.    Voce pode ver a posição pelo cursor abaixo do item.
  42.  
  43.    Tem também um despertador (alarme) que pode ser programado.
  44.    O Alarme compara dia hora minuto e segundos para disparar.
  45.    Ao disparar, fica assim até ser resetado.
  46.    A posição reset alarme, reseta o despertador.
  47.    Caso o cursor não esteja em rest alarme, o despertado fica sendo acionado por 20 segundos.
  48.    Se resetar o alarme e retirar o cursor desta posição, e estiver dentro dos 20 segundos, ele dispara novamente,
  49. */
  50.  
  51. #include <LiquidCrystal.h>                                            // Biblioteca LCD standard
  52. //#include <LiquidCrystal_I2C.h>                                          // Biblioteca LCD I2C
  53. #include <DS3231.h>                                                     // Biblioteca RTC I2C
  54. #include <Wire.h>                                                       // Biblioteca I2C
  55. #include "TimerOne.h"                                                   // Biblioteca Timer1
  56. /*
  57.   #define Esquerda 3                                                      // Move cursor para esquerda
  58.   #define Direita 4                                                       // Move cursor para direita
  59.   #define Menos 5                                                         // Decrementa
  60.   #define Mais 6                                                          // Incrementa
  61. */
  62. int MenuIdx = 0;                                                        // Controla posicao do cursor
  63. int Conta = 0;                                                          // Valor de incremento ou decremento
  64. byte Crs = 0;                                                           // Posicao do cursor
  65. byte Lnh = 0;                                                           // Linha do cursor
  66. unsigned long Agora = 0;                                                // Variavel para acumular valores calculados do relogio
  67. unsigned long Programado = 0;                                           // Variavel para acumular valores calculados do alarme
  68. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  69. //LiquidCrystal lcd(13, 12, 11, 10, 9, 8);                              // LCD normal
  70. //LiquidCrystal_I2C lcd(0x38,  2, 1, 0, 7, 6, 5, 4, 3, POSITIVE);         // Set the LCD I2C
  71. int Tempo[14];                                                          // Matriz para guardar valores
  72. byte Ref = 0;                                                           // Indexador de relogio e alarme
  73. byte Flag_RTC = 0;                                                      // Flag para identificar se tem RTC
  74. DS3231 rtc(SDA, SCL);                                                   // Pinos do RTC e instancia
  75. Time Now;                                                               // Variavel formato tempo
  76. byte Button = 0;
  77. int AnalogButton = 0;
  78. //----------------------------------------
  79. void setup()
  80. {
  81.   Serial.begin(9600);                                                   // Inicia Serial
  82.   Wire.begin();                                                         // inicia o I2C bus
  83.   Wire.beginTransmission(0x68);                                         // Identifica enderecos no bus I2C (O RTC DS3231 o endereco é 0x68)
  84.   byte error = Wire.endTransmission();                                  // Verifica se tem RTC
  85.   //  Serial.println(error);
  86.  
  87.   //  pinMode(Direita,  INPUT_PULLUP);                                      // Definicao do ports como saida e entrada em pushpull
  88.   //  pinMode(Esquerda, INPUT_PULLUP);
  89.   //  pinMode(Mais,     INPUT_PULLUP);
  90.   //  pinMode(Menos,    INPUT_PULLUP);
  91.   pinMode(13,    OUTPUT);
  92.  
  93.   rtc.begin();                                                          // Inicia RTC
  94.  
  95.   if (error != 0)                                                       // Se nao tem RTC
  96.   {
  97.     Timer1.initialize(1000000);                                         // Inicia timer1, e define o periodo de 1 seg
  98.     Timer1.attachInterrupt(TempoSemRTC);                                // Attacha interrupt e define rotina callback() como rotina de timer1 overflow
  99.  
  100.     Tempo[2] = 14;                                                      // Dia
  101.     Tempo[1] = 11;                                                      // Mes
  102.     Tempo[0] = 2016;                                                    // Ano
  103.     Tempo[6] = 29;                                                      // Segundo
  104.     Tempo[5] = 29;                                                      // Minuto
  105.     Tempo[4] = 12;                                                      // Hora
  106.     Flag_RTC = 0;                                                       // Informa que nao tem RTC
  107.   }
  108.  
  109.   else   Flag_RTC = 1;                                                  // Se tem RTC Informa que tem RTC
  110.  
  111.   lcd.begin(16, 2);                                                     // Inicialisa LCD
  112.   lcd.setCursor(10, 1);                                                 // Posiciona cursor em 10 linha 1
  113.   lcd.print("Clock ");                                                  // Print
  114.   Tempo[9] = 14;                                                        // Dia atual para alarme
  115.   Tempo[8] = 11;                                                        // Mes atual para alarme
  116.   Tempo[7] = 2016;                                                      // Ano atual para alarme
  117.   Tempo[13] = 03;                                                       // Segundo atual para alarme
  118.   Tempo[12] = 49;                                                       // Minuto atual para alarme
  119.   Tempo[11] = 11;                                                       // Hora atual para alarme
  120. }
  121. //----------------------------------------
  122. void loop()
  123. {
  124.   Display();                                                            // Rotina relogio
  125.   AnalogButton = analogRead (0);
  126.   Botao();                                                              // Rotina controle dos botoes
  127.   delay(100);                                                           // Latencia do LCD
  128. }
  129. //----------------------------------------
  130. void Alarme()                                                           // Funcao para operar os disparos do alarme
  131. {
  132.   if (Agora >= Programado)                                              // Se passou do horario programado
  133.   {
  134.     if (MenuIdx != 6)                                                   // Se menuindex for diferente de 6 permite acionar alarme
  135.     {
  136.       if ((Agora - Programado) < 20)                                    // Liga durante 20 segundos
  137.       {
  138.         digitalWrite(13, HIGH);                                         // Liga LED 13
  139.         lcd.setCursor(12, 0);                                           // Posiciona cursor em linha 0 posicao 10
  140.         lcd.print("@");                                                 // Mostra alarme ligado
  141.       }
  142.     }
  143.   }
  144.   if  (MenuIdx == 6)                                                    // Se cursor fora do LCD
  145.   {
  146.     digitalWrite(13, LOW);;                                             // Desliga LED 13
  147.     lcd.setCursor(12, 0);                                               // Posiciona cursor em linha 0 posicao 10
  148.     lcd.print(" ");                                                     // Apaga alarme ligado
  149.   }
  150. }
  151. //----------------------------------------
  152. void Botao()
  153. {
  154.   Serial.println(AnalogButton);
  155.   if (AnalogButton < 60) Button = 1;                                    // Right
  156.   else if (AnalogButton < 200) Button = 2;                              // Up
  157.   else if (AnalogButton < 400) Button = 3;                              // Down
  158.   else if (AnalogButton < 600) Button = 0;                              // Left
  159.   else if (AnalogButton >= 600) Button = 5;                              
  160.   Serial.println(Button);
  161.    
  162.   if (Button == 0)                                                      // Se botao para direita foi pressionado
  163.   {
  164.     MenuIdx++;                                                          // Desloca cursor LCD pra esquerda
  165.     Seleciona();                                                        // Mostra se e clock ou alarme
  166.     delay(30);
  167.   }
  168.   if (MenuIdx > 12)                                                     // Se indexador maior que maximo
  169.   {
  170.     MenuIdx = 0;                                                        // Volta para o minimo
  171.     Seleciona();                                                        // Mostra se e clock ou alarme
  172.   }
  173.  
  174.   if (Button == 1)                                           // Se botao para esquerda foi pressionado
  175.   {
  176.     MenuIdx--;                                                        // Desloca cursor LCD para ditreita
  177.     Seleciona();                                                        // Mostra se e Clock ou Alarme
  178.     delay(30);
  179.   }
  180.   if (MenuIdx < 0)                                                      // Se indexador menor que minimo
  181.   {
  182.     MenuIdx = 12;                                                       // Vai para o maximo
  183.     Seleciona();                                                        // Mostra se e clock ou alarme
  184.   }
  185.   if (MenuIdx < 3)                                                      // Se relogio hora min seg
  186.   {
  187.     Crs = MenuIdx * 3;                                                  // Calcula posicao do cursor LCD
  188.     Lnh = 1;                                                            // Define linha do cursor
  189.   }
  190.   if ((MenuIdx > 2) & (MenuIdx < 6))                                    // Se relogio dia mes ano
  191.   {
  192.     Crs = (MenuIdx - 3) * 3;                                            // Calcula posicao do cursor LCD
  193.     Lnh = 0;                                                            // Define linha do cursor
  194.   }
  195.  
  196.   if ((MenuIdx > 6 ) & (MenuIdx < 10))                                  // Se alarme hora min seg
  197.   {
  198.     Crs = (MenuIdx - 7) * 3;                                            // Calcula posicao do cursor LCD
  199.     Lnh = 1;                                                            // Define linha do cursor
  200.   }
  201.   if ((MenuIdx > 9) & (MenuIdx < 13))                                   // Se alarme dia mes ano
  202.   {
  203.     Crs = (MenuIdx - 10) * 3;                                           // Calcula posicao do cursor LCD
  204.     Lnh = 0;                                                            // Define linha do cursor
  205.   }
  206.  
  207.   if (MenuIdx == 6)                                                     // Se menuindex = 6 posiciona em selecione alarme
  208.   {
  209.     Crs = 12;                                                           //  Posicao de indicador e silenciador de alarme
  210.     Lnh = 0;                                                            //
  211.   }
  212.   if (Button == 2)                                               // Se botao mais foi pressionado
  213.   {
  214.     Conta = 1;                                                        // Incrementa
  215.     Ajuste();                                                         // Chama rotina de display atualizado
  216.     delay(30);
  217.   }
  218.   if (Button == 3)                                              // Se botao menos foi pressionado
  219.   {
  220.     Conta = -1;                                                       // Decrementa
  221.     Ajuste();                                                         // Chama rotina de display atualizado
  222.     delay(30);
  223.   }
  224. }
  225. //----------------------------------------
  226. void Display()                                                          // Funcao para mostra relogio e alarme
  227. {
  228.   if (Flag_RTC == 1)                                                    //Se tem RTC
  229.   {
  230.     Now = rtc.getTime();                                                // Busca horario no RTC
  231.  
  232.     Tempo[0] = Now.year;                                                // Salva na matriz tempo
  233.     Tempo[1] = Now.mon;
  234.     Tempo[2] = Now.date;
  235.     Tempo[3] = Now.dow;
  236.     Tempo[4] = Now.hour;
  237.     Tempo[5] = Now.min;
  238.     Tempo[6] = Now.sec;
  239.   }
  240.  
  241.   Agora      = (Tempo[2] * 24L * 3600L) + (Tempo[4]  * 3600L) + (Tempo[5]  * 60L) + Tempo[6];       // Calcula valor de agora de dia hora min e seg
  242.   Programado = (Tempo[9] * 24L * 3600L) + (Tempo[11] * 3600L) + (Tempo[12] * 60L) + Tempo[13];      // Calcula valor de alarme de dia hora min e seg
  243.   Alarme();                                                             // Chama funcao de controle de alarme
  244.  
  245.   lcd.setCursor(0, 0);                                                  // Cursor em pos 0 lin 0 do LCD
  246.   Serial.print(Tempo[Ref + 2]);                                         // Print dia
  247.   Print(Tempo[Ref + 2]);                                                // Print dia relogio ou alarme apos formatar 2 digitos
  248.   lcd.print("/");                                                       // Print /
  249.   Serial.print("/");                                                    // Print /
  250.   Serial.print(Tempo[Ref + 1]);                                         // Print mes
  251.   Print(Tempo[Ref + 1]);                                                // Print mes relogio ou alarme apos formatar 2 digitos
  252.   lcd.print("/");                                                       // Print /
  253.   Serial.print("/");                                                    // Print /
  254.   Print(Tempo[Ref + 0]);                                                // Print ano relogio ou alarme apos formatar 2 digitos
  255.   Serial.print(Tempo[Ref + 0]);                                         // Print ano
  256.   Serial.print(" ");                                                    // Print espaco
  257.  
  258.   lcd.setCursor(0, 1);
  259.   Print(Tempo[Ref + 4]);                                                // Print hora relogio ou alarme apos formatar 2 digitos
  260.   Serial.print(Tempo[Ref + 4]);                                         // Print hora
  261.   lcd.print(":");                                                       // Print :
  262.   Serial.print(":");                                                    // Print :
  263.   Print(Tempo[Ref + 5]);                                                // Print minuto relogio ou alarme apos formatar 2 digitos
  264.   Serial.print(Tempo[Ref + 5]);                                         // Print minuto
  265.   lcd.print(":");                                                       // Print :
  266.   Serial.print(":");                                                    // Print :
  267.   Print(Tempo[Ref + 6]);                                                // Print segundo relogio ou alarme apos formatar 2 digitos
  268.   Serial.println(Tempo[Ref + 6]);                                       // Print segundo
  269.   lcd.setCursor(Crs, Lnh);                                              // Posciona cursor
  270.   lcd.cursor();                                                         // Liga cursor
  271. }
  272. //----------------------------------------
  273. void Ajuste()                                                           // funcao para ajustar relogio e alarme
  274. {
  275.   if ((MenuIdx == 2) | (MenuIdx == 9)) //minutos                        // Seleciona ajuste de segundo
  276.   {
  277.     Tempo[Ref + 6] = Tempo[Ref + 6] + Conta;                            // Incrementa ou decrementa
  278.     if (Tempo[Ref + 6] > 59) Tempo[Ref + 6] = 0;                        // Se for  maior que 59 vai pra 0
  279.     if (Tempo[Ref + 6] < 0) Tempo[Ref + 6] = 59;                        // Se for  menor que 0 vai pra 59
  280.   }
  281.   if ((MenuIdx == 1) | (MenuIdx == 8)) //minutos                        // Seleciona ajuste de minuto
  282.   {
  283.     Tempo[Ref + 5] = Tempo[Ref + 5] + Conta;                            // Incrementa ou decrementa
  284.     if (Tempo[Ref + 5] > 59) Tempo[Ref + 5] = 0;                        // Se for  maior que 59 vai pra 0
  285.     if (Tempo[Ref + 5] < 0) Tempo[Ref + 5] = 59;                        // Se for  menor que 0 vai pra 59
  286.   }
  287.   if ((MenuIdx == 0) | (MenuIdx == 7))  //horas                         // Seleciona ajuste de hora
  288.   {
  289.     Tempo[Ref + 4] = Tempo[Ref + 4] + Conta;                            // Incrementa ou decrementa
  290.     if (Tempo[Ref + 4] > 23) Tempo[Ref + 4] = 0;                        // Se for  maior que 23 vai pra 0
  291.     if (Tempo[Ref + 4] < 0) Tempo[Ref + 4] = 23;                        // Se for  menor que 0 vai pra 23
  292.   }
  293.   if ((MenuIdx == 3) | (MenuIdx == 10))  //dia                          // Seleciona ajuste de dia
  294.   {
  295.     Tempo[Ref + 2] = Tempo[Ref + 2] + Conta;                            // Incrementa ou decrementa
  296.     if (Tempo[Ref + 2] > 31) Tempo[Ref + 2] = 1;                        // Se for  maior que 31 vai pra 1
  297.     if (Tempo[Ref + 2] < 1) Tempo[Ref + 2] = 31;                        // Se for  menor que 1 vai pra 31
  298.   }
  299.   if ((MenuIdx == 4) | (MenuIdx == 11))  //mes                          // Seleciona ajuste de mes
  300.   {
  301.     Tempo[Ref + 1] = Tempo[Ref + 1] + Conta;                            // Incrementa ou decrementa
  302.     if (Tempo[Ref + 1] > 12) Tempo[Ref + 1] = 1;                        // Se for  maior que 12 vai pra 1
  303.     if (Tempo[Ref + 1] < 1) Tempo[Ref + 1] = 12;                        // Se for  menor que 1 vai pra 12
  304.   }
  305.   if ((MenuIdx == 5) | (MenuIdx == 12))  //ano                          // Seleciona ajuste de ano
  306.   {
  307.     Tempo[Ref + 0] = Tempo[Ref + 0] + Conta;                            // Incrementa ou decrementa
  308.   }
  309.   rtc.setDate(Tempo[2], Tempo[1], Tempo[0]);                            // Atualiza data
  310.   rtc.setTime(Tempo[4], Tempo[5], Tempo[6]);                            // Atualiza horario
  311. }
  312. //----------------------------------------
  313. void Seleciona()                                                        // Funcao para determinar ajuste e display
  314. {
  315.   if (MenuIdx < 7)                                                      // Se menuindex for menor que 7 funcao display relogio
  316.   {
  317.     lcd.setCursor(10, 1);                                               // Posiciona cursor em linha 1 posicao 10
  318.     lcd.print("Clock ");                                                // Informa que e relogio
  319.     Ref = 0;                                                            // Somador para indexar matriz = 0
  320.   }
  321.   else                                                                  // Se menuindex for maior que 7 funcao display alarme
  322.   {
  323.     lcd.setCursor(10, 1);                                               // Posiciona cursor em linha 1 posicao 10
  324.     lcd.print("Alarme");                                                // Informa que e alarme
  325.     Ref = 7;                                                            // Somador para indexar matriz = 7
  326.   }
  327. }
  328. //----------------------------------------
  329. void Print(int number)                                                  // Funcao para ajustar os digitos para 00,01,02,...
  330. {
  331.   lcd.print(number / 10);                                               // Imprime o digito mais significativo
  332.   lcd.print(number % 10);                                               // Imprime o digito menos significativo
  333. }
  334. //----------------------------------------
  335. void TempoSemRTC()                                                      //Funcao calculo da hora e data sem RTC
  336. {
  337.   Tempo[6] = Tempo[6] + 1;                                              // Incrementa segundo
  338.   if (Tempo[6] > 59)                                                    // Se segundo maior que 59
  339.   {
  340.     Tempo[6] = 0;                                                       // Zera segundo e
  341.     Tempo[5] = Tempo[5] + 1;                                            // Incrementa minuto
  342.   }
  343.  
  344.   if (Tempo[5] > 59)                                                    // Se minuto maior que 59
  345.   {
  346.     Tempo[5] = 0;                                                       // Zera minuto e
  347.     Tempo[4] = Tempo[4] + 1;                                            // Incrementa hora
  348.   }
  349.  
  350.   if (Tempo[4] > 23)                                                    // Se hora maior que 23
  351.   {
  352.     Tempo[4] = 0;                                                       // Zera hora e
  353.     Tempo[2] = Tempo[2] + 1;                                            // Incrementa dia
  354.   }
  355.  
  356.   if (Tempo[1] == 1 | Tempo[1] == 3 | Tempo[1] == 5 | Tempo[1] == 7 | Tempo[1] == 8 | Tempo[1] == 10 | Tempo[1] == 12)  // Se Jan Mar Mai Jul Ago Out ou Dez
  357.   {
  358.     if (Tempo[2] > 31)                                                  // Se dia maior que 31
  359.     {
  360.       Tempo[2] = 1;                                                     // Muda dia para 1 e
  361.       Tempo[1] = Tempo[1] + 1;                                          // Incrementa mes
  362.     }
  363.   }
  364.  
  365.   if (Tempo[1] == 4 | Tempo[1] == 6 | Tempo[1] == 9 | Tempo[1] == 9)    // Se Abr Jun Set ou Nov
  366.   {
  367.     if (Tempo[2] > 30)                                                  // Se segundo mes que 30
  368.     {
  369.       Tempo[2] = 1;                                                     // Muda dia para 1 e
  370.       Tempo[1] = Tempo[1] + 1;                                          // Incrementa mes
  371.     }
  372.   }
  373.  
  374.   if (Tempo[1] == 2 )                                                   // Se fevereiro
  375.   {
  376.     if (Tempo[0] % 4 == 0)                                              // Se ano bisexto
  377.     {
  378.       if (Tempo[2] > 29)                                                // Se mes maior que 29
  379.       {
  380.         Tempo[2] = 1;                                                   // Muda dia para 1 e
  381.         Tempo[1] = Tempo[1] + 1;                                        // Incrementa mes
  382.       }
  383.     }
  384.     else if (Tempo[2] > 28)                                             // Se nao bisexto e se segundo maior que 28
  385.     {
  386.       Tempo[2] = 1;                                                     // Muda dia para 1 e
  387.       Tempo[1] = Tempo[1] + 1;                                          // Incrementa mes
  388.     }
  389.   }
  390.  
  391.   if (Tempo[1] > 12)                                                    // Se mes maior que 12
  392.   {
  393.     Tempo[1] = 1;                                                       // Muda mes para 1 e
  394.     Tempo[0] = Tempo[0] + 1;                                            // Incrementa ano
  395.   }
  396. }
RAW Paste Data