Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Nome do Projeto: Relogio_Versatil
- Nome do Aquivo: Relogio_Versatil.ino
- link:
- Dependencias: N/A
- MCU: ATmega
- Board: Arduino Uno/Mega/Mini
- Compilador N/A
- IDE: Arduino IDE 1.0.6
- Hardware: Arduino UNO/MEGA/Mini
- Escrito por: Rui Viana
- Modificado por: N/A
- Data: dd/mm/2015
- Uso: Didático
- Desenhos N/A
- Copyright @ N/A
- Este programa é software livre;
- e é distribuído na esperança que possa ser útil, mas SEM QUALQUER GARANTIA;
- mesmo sem a garantia implícita de COMERCIALIZAÇÃO ou ADEQUAÇÃO A UM DETERMINADO FIM.
- REVISIONS: (latest entry first)
- 14/11/2016 - Relogio_Versatil.ino - First release
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Descrição:
- Este código foi escrito para ser usado com ou sem RTC e com opção de LCD stantard ou I2C.
- Ele determina se tem ou não RTC conectado.
- Caso tenha ele usa a hora e a data do RTC, e a data e hora estão sempre atualizadas,
- se não, esta data e hora deverão ser ajustadas, e elas se perdem valor ao dar reset ou
- desligar o arduino.
- Ele é um relogio e um despertador
- O ajuste de cada item é feito deslocando o cursor do LCD com os botões direita e esquerda
- para selecionar o item e mais e menos para incrmentar e decrementar o item.
- As movimentações seguem assim: rel = relogio alm = despertador
- |-----------------<<--------------------------------<<-------------------------|
- |--> Hora rel.--> Minuto rel.--> Segundo rel.--> Dia rel--> Mes rel.--> |
- Ano rel.--> reset alarme--> Hora alm.--> Minuto alm.--> Segundo alm.--> |
- Dia alm--> Mes rel.--> Ano rel.------------------------------------------------|
- Voce pode ver a posição pelo cursor abaixo do item.
- Tem também um despertador (alarme) que pode ser programado.
- O Alarme compara dia hora minuto e segundos para disparar.
- Ao disparar, fica assim até ser resetado.
- A posição reset alarme, reseta o despertador.
- Caso o cursor não esteja em rest alarme, o despertado fica sendo acionado por 20 segundos.
- Se resetar o alarme e retirar o cursor desta posição, e estiver dentro dos 20 segundos, ele dispara novamente,
- */
- #include <LiquidCrystal.h> // Biblioteca LCD standard
- //#include <LiquidCrystal_I2C.h> // Biblioteca LCD I2C
- #include <DS3231.h> // Biblioteca RTC I2C
- #include <Wire.h> // Biblioteca I2C
- #include "TimerOne.h" // Biblioteca Timer1
- /*
- #define Esquerda 3 // Move cursor para esquerda
- #define Direita 4 // Move cursor para direita
- #define Menos 5 // Decrementa
- #define Mais 6 // Incrementa
- */
- int MenuIdx = 0; // Controla posicao do cursor
- int Conta = 0; // Valor de incremento ou decremento
- byte Crs = 0; // Posicao do cursor
- byte Lnh = 0; // Linha do cursor
- unsigned long Agora = 0; // Variavel para acumular valores calculados do relogio
- unsigned long Programado = 0; // Variavel para acumular valores calculados do alarme
- LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
- //LiquidCrystal lcd(13, 12, 11, 10, 9, 8); // LCD normal
- //LiquidCrystal_I2C lcd(0x38, 2, 1, 0, 7, 6, 5, 4, 3, POSITIVE); // Set the LCD I2C
- int Tempo[14]; // Matriz para guardar valores
- byte Ref = 0; // Indexador de relogio e alarme
- byte Flag_RTC = 0; // Flag para identificar se tem RTC
- DS3231 rtc(SDA, SCL); // Pinos do RTC e instancia
- Time Now; // Variavel formato tempo
- byte Button = 0;
- int AnalogButton = 0;
- //----------------------------------------
- void setup()
- {
- Serial.begin(9600); // Inicia Serial
- Wire.begin(); // inicia o I2C bus
- Wire.beginTransmission(0x68); // Identifica enderecos no bus I2C (O RTC DS3231 o endereco é 0x68)
- byte error = Wire.endTransmission(); // Verifica se tem RTC
- // Serial.println(error);
- // pinMode(Direita, INPUT_PULLUP); // Definicao do ports como saida e entrada em pushpull
- // pinMode(Esquerda, INPUT_PULLUP);
- // pinMode(Mais, INPUT_PULLUP);
- // pinMode(Menos, INPUT_PULLUP);
- pinMode(13, OUTPUT);
- rtc.begin(); // Inicia RTC
- if (error != 0) // Se nao tem RTC
- {
- Timer1.initialize(1000000); // Inicia timer1, e define o periodo de 1 seg
- Timer1.attachInterrupt(TempoSemRTC); // Attacha interrupt e define rotina callback() como rotina de timer1 overflow
- Tempo[2] = 14; // Dia
- Tempo[1] = 11; // Mes
- Tempo[0] = 2016; // Ano
- Tempo[6] = 29; // Segundo
- Tempo[5] = 29; // Minuto
- Tempo[4] = 12; // Hora
- Flag_RTC = 0; // Informa que nao tem RTC
- }
- else Flag_RTC = 1; // Se tem RTC Informa que tem RTC
- lcd.begin(16, 2); // Inicialisa LCD
- lcd.setCursor(10, 1); // Posiciona cursor em 10 linha 1
- lcd.print("Clock "); // Print
- Tempo[9] = 14; // Dia atual para alarme
- Tempo[8] = 11; // Mes atual para alarme
- Tempo[7] = 2016; // Ano atual para alarme
- Tempo[13] = 03; // Segundo atual para alarme
- Tempo[12] = 49; // Minuto atual para alarme
- Tempo[11] = 11; // Hora atual para alarme
- }
- //----------------------------------------
- void loop()
- {
- Display(); // Rotina relogio
- AnalogButton = analogRead (0);
- Botao(); // Rotina controle dos botoes
- delay(100); // Latencia do LCD
- }
- //----------------------------------------
- void Alarme() // Funcao para operar os disparos do alarme
- {
- if (Agora >= Programado) // Se passou do horario programado
- {
- if (MenuIdx != 6) // Se menuindex for diferente de 6 permite acionar alarme
- {
- if ((Agora - Programado) < 20) // Liga durante 20 segundos
- {
- digitalWrite(13, HIGH); // Liga LED 13
- lcd.setCursor(12, 0); // Posiciona cursor em linha 0 posicao 10
- lcd.print("@"); // Mostra alarme ligado
- }
- }
- }
- if (MenuIdx == 6) // Se cursor fora do LCD
- {
- digitalWrite(13, LOW);; // Desliga LED 13
- lcd.setCursor(12, 0); // Posiciona cursor em linha 0 posicao 10
- lcd.print(" "); // Apaga alarme ligado
- }
- }
- //----------------------------------------
- void Botao()
- {
- Serial.println(AnalogButton);
- if (AnalogButton < 60) Button = 1; // Right
- else if (AnalogButton < 200) Button = 2; // Up
- else if (AnalogButton < 400) Button = 3; // Down
- else if (AnalogButton < 600) Button = 0; // Left
- else if (AnalogButton >= 600) Button = 5;
- Serial.println(Button);
- if (Button == 0) // Se botao para direita foi pressionado
- {
- MenuIdx++; // Desloca cursor LCD pra esquerda
- Seleciona(); // Mostra se e clock ou alarme
- delay(30);
- }
- if (MenuIdx > 12) // Se indexador maior que maximo
- {
- MenuIdx = 0; // Volta para o minimo
- Seleciona(); // Mostra se e clock ou alarme
- }
- if (Button == 1) // Se botao para esquerda foi pressionado
- {
- MenuIdx--; // Desloca cursor LCD para ditreita
- Seleciona(); // Mostra se e Clock ou Alarme
- delay(30);
- }
- if (MenuIdx < 0) // Se indexador menor que minimo
- {
- MenuIdx = 12; // Vai para o maximo
- Seleciona(); // Mostra se e clock ou alarme
- }
- if (MenuIdx < 3) // Se relogio hora min seg
- {
- Crs = MenuIdx * 3; // Calcula posicao do cursor LCD
- Lnh = 1; // Define linha do cursor
- }
- if ((MenuIdx > 2) & (MenuIdx < 6)) // Se relogio dia mes ano
- {
- Crs = (MenuIdx - 3) * 3; // Calcula posicao do cursor LCD
- Lnh = 0; // Define linha do cursor
- }
- if ((MenuIdx > 6 ) & (MenuIdx < 10)) // Se alarme hora min seg
- {
- Crs = (MenuIdx - 7) * 3; // Calcula posicao do cursor LCD
- Lnh = 1; // Define linha do cursor
- }
- if ((MenuIdx > 9) & (MenuIdx < 13)) // Se alarme dia mes ano
- {
- Crs = (MenuIdx - 10) * 3; // Calcula posicao do cursor LCD
- Lnh = 0; // Define linha do cursor
- }
- if (MenuIdx == 6) // Se menuindex = 6 posiciona em selecione alarme
- {
- Crs = 12; // Posicao de indicador e silenciador de alarme
- Lnh = 0; //
- }
- if (Button == 2) // Se botao mais foi pressionado
- {
- Conta = 1; // Incrementa
- Ajuste(); // Chama rotina de display atualizado
- delay(30);
- }
- if (Button == 3) // Se botao menos foi pressionado
- {
- Conta = -1; // Decrementa
- Ajuste(); // Chama rotina de display atualizado
- delay(30);
- }
- }
- //----------------------------------------
- void Display() // Funcao para mostra relogio e alarme
- {
- if (Flag_RTC == 1) //Se tem RTC
- {
- Now = rtc.getTime(); // Busca horario no RTC
- Tempo[0] = Now.year; // Salva na matriz tempo
- Tempo[1] = Now.mon;
- Tempo[2] = Now.date;
- Tempo[3] = Now.dow;
- Tempo[4] = Now.hour;
- Tempo[5] = Now.min;
- Tempo[6] = Now.sec;
- }
- Agora = (Tempo[2] * 24L * 3600L) + (Tempo[4] * 3600L) + (Tempo[5] * 60L) + Tempo[6]; // Calcula valor de agora de dia hora min e seg
- Programado = (Tempo[9] * 24L * 3600L) + (Tempo[11] * 3600L) + (Tempo[12] * 60L) + Tempo[13]; // Calcula valor de alarme de dia hora min e seg
- Alarme(); // Chama funcao de controle de alarme
- lcd.setCursor(0, 0); // Cursor em pos 0 lin 0 do LCD
- Serial.print(Tempo[Ref + 2]); // Print dia
- Print(Tempo[Ref + 2]); // Print dia relogio ou alarme apos formatar 2 digitos
- lcd.print("/"); // Print /
- Serial.print("/"); // Print /
- Serial.print(Tempo[Ref + 1]); // Print mes
- Print(Tempo[Ref + 1]); // Print mes relogio ou alarme apos formatar 2 digitos
- lcd.print("/"); // Print /
- Serial.print("/"); // Print /
- Print(Tempo[Ref + 0]); // Print ano relogio ou alarme apos formatar 2 digitos
- Serial.print(Tempo[Ref + 0]); // Print ano
- Serial.print(" "); // Print espaco
- lcd.setCursor(0, 1);
- Print(Tempo[Ref + 4]); // Print hora relogio ou alarme apos formatar 2 digitos
- Serial.print(Tempo[Ref + 4]); // Print hora
- lcd.print(":"); // Print :
- Serial.print(":"); // Print :
- Print(Tempo[Ref + 5]); // Print minuto relogio ou alarme apos formatar 2 digitos
- Serial.print(Tempo[Ref + 5]); // Print minuto
- lcd.print(":"); // Print :
- Serial.print(":"); // Print :
- Print(Tempo[Ref + 6]); // Print segundo relogio ou alarme apos formatar 2 digitos
- Serial.println(Tempo[Ref + 6]); // Print segundo
- lcd.setCursor(Crs, Lnh); // Posciona cursor
- lcd.cursor(); // Liga cursor
- }
- //----------------------------------------
- void Ajuste() // funcao para ajustar relogio e alarme
- {
- if ((MenuIdx == 2) | (MenuIdx == 9)) //minutos // Seleciona ajuste de segundo
- {
- Tempo[Ref + 6] = Tempo[Ref + 6] + Conta; // Incrementa ou decrementa
- if (Tempo[Ref + 6] > 59) Tempo[Ref + 6] = 0; // Se for maior que 59 vai pra 0
- if (Tempo[Ref + 6] < 0) Tempo[Ref + 6] = 59; // Se for menor que 0 vai pra 59
- }
- if ((MenuIdx == 1) | (MenuIdx == 8)) //minutos // Seleciona ajuste de minuto
- {
- Tempo[Ref + 5] = Tempo[Ref + 5] + Conta; // Incrementa ou decrementa
- if (Tempo[Ref + 5] > 59) Tempo[Ref + 5] = 0; // Se for maior que 59 vai pra 0
- if (Tempo[Ref + 5] < 0) Tempo[Ref + 5] = 59; // Se for menor que 0 vai pra 59
- }
- if ((MenuIdx == 0) | (MenuIdx == 7)) //horas // Seleciona ajuste de hora
- {
- Tempo[Ref + 4] = Tempo[Ref + 4] + Conta; // Incrementa ou decrementa
- if (Tempo[Ref + 4] > 23) Tempo[Ref + 4] = 0; // Se for maior que 23 vai pra 0
- if (Tempo[Ref + 4] < 0) Tempo[Ref + 4] = 23; // Se for menor que 0 vai pra 23
- }
- if ((MenuIdx == 3) | (MenuIdx == 10)) //dia // Seleciona ajuste de dia
- {
- Tempo[Ref + 2] = Tempo[Ref + 2] + Conta; // Incrementa ou decrementa
- if (Tempo[Ref + 2] > 31) Tempo[Ref + 2] = 1; // Se for maior que 31 vai pra 1
- if (Tempo[Ref + 2] < 1) Tempo[Ref + 2] = 31; // Se for menor que 1 vai pra 31
- }
- if ((MenuIdx == 4) | (MenuIdx == 11)) //mes // Seleciona ajuste de mes
- {
- Tempo[Ref + 1] = Tempo[Ref + 1] + Conta; // Incrementa ou decrementa
- if (Tempo[Ref + 1] > 12) Tempo[Ref + 1] = 1; // Se for maior que 12 vai pra 1
- if (Tempo[Ref + 1] < 1) Tempo[Ref + 1] = 12; // Se for menor que 1 vai pra 12
- }
- if ((MenuIdx == 5) | (MenuIdx == 12)) //ano // Seleciona ajuste de ano
- {
- Tempo[Ref + 0] = Tempo[Ref + 0] + Conta; // Incrementa ou decrementa
- }
- rtc.setDate(Tempo[2], Tempo[1], Tempo[0]); // Atualiza data
- rtc.setTime(Tempo[4], Tempo[5], Tempo[6]); // Atualiza horario
- }
- //----------------------------------------
- void Seleciona() // Funcao para determinar ajuste e display
- {
- if (MenuIdx < 7) // Se menuindex for menor que 7 funcao display relogio
- {
- lcd.setCursor(10, 1); // Posiciona cursor em linha 1 posicao 10
- lcd.print("Clock "); // Informa que e relogio
- Ref = 0; // Somador para indexar matriz = 0
- }
- else // Se menuindex for maior que 7 funcao display alarme
- {
- lcd.setCursor(10, 1); // Posiciona cursor em linha 1 posicao 10
- lcd.print("Alarme"); // Informa que e alarme
- Ref = 7; // Somador para indexar matriz = 7
- }
- }
- //----------------------------------------
- void Print(int number) // Funcao para ajustar os digitos para 00,01,02,...
- {
- lcd.print(number / 10); // Imprime o digito mais significativo
- lcd.print(number % 10); // Imprime o digito menos significativo
- }
- //----------------------------------------
- void TempoSemRTC() //Funcao calculo da hora e data sem RTC
- {
- Tempo[6] = Tempo[6] + 1; // Incrementa segundo
- if (Tempo[6] > 59) // Se segundo maior que 59
- {
- Tempo[6] = 0; // Zera segundo e
- Tempo[5] = Tempo[5] + 1; // Incrementa minuto
- }
- if (Tempo[5] > 59) // Se minuto maior que 59
- {
- Tempo[5] = 0; // Zera minuto e
- Tempo[4] = Tempo[4] + 1; // Incrementa hora
- }
- if (Tempo[4] > 23) // Se hora maior que 23
- {
- Tempo[4] = 0; // Zera hora e
- Tempo[2] = Tempo[2] + 1; // Incrementa dia
- }
- 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
- {
- if (Tempo[2] > 31) // Se dia maior que 31
- {
- Tempo[2] = 1; // Muda dia para 1 e
- Tempo[1] = Tempo[1] + 1; // Incrementa mes
- }
- }
- if (Tempo[1] == 4 | Tempo[1] == 6 | Tempo[1] == 9 | Tempo[1] == 9) // Se Abr Jun Set ou Nov
- {
- if (Tempo[2] > 30) // Se segundo mes que 30
- {
- Tempo[2] = 1; // Muda dia para 1 e
- Tempo[1] = Tempo[1] + 1; // Incrementa mes
- }
- }
- if (Tempo[1] == 2 ) // Se fevereiro
- {
- if (Tempo[0] % 4 == 0) // Se ano bisexto
- {
- if (Tempo[2] > 29) // Se mes maior que 29
- {
- Tempo[2] = 1; // Muda dia para 1 e
- Tempo[1] = Tempo[1] + 1; // Incrementa mes
- }
- }
- else if (Tempo[2] > 28) // Se nao bisexto e se segundo maior que 28
- {
- Tempo[2] = 1; // Muda dia para 1 e
- Tempo[1] = Tempo[1] + 1; // Incrementa mes
- }
- }
- if (Tempo[1] > 12) // Se mes maior que 12
- {
- Tempo[1] = 1; // Muda mes para 1 e
- Tempo[0] = Tempo[0] + 1; // Incrementa ano
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement