Introduction: Arduino Tutorial - Alarm Clock - EEPROM

About: This is a channel for Homemakers and DIY where you will find useful tutorials about Arduino and IOT systems, some Gardening techniques and Woodworking projects.

Bem vindos a mais um tutorial sobre Arduino, neste tutorial iremos mostra-vos como utilizar a memóriaEEPROM de um Arduino através de uma montagem com a função de um relógio despertador, este irá indicar 2 tipos de hora através de um pequeno LCD, neste caso será a hora do relógio e a hora do alarme.

A hora do relógio será fornecida por uma pequena placa RTC "ReaL Time Clock", já a hora do alarme será programada e gravada na memória EEPROM, agora sempre que estás 2 horas sejam coincidentes é activado por sua vez um pequeno "Buzzer" que produzirá um sinal sonoro.

Alem de ser explicado o funcionamento da memória EEPROM inserida no Arduino, também será recordado o funcionamento do LCD1602 e da placa RTC DS1307, tendo estes já utilizados e explicados em outros tutoriais.

Arduino Tutorial - Clock - LCD

https://www.instructables.com/id/Arduino-Tutorial-Clock-LCD/

Arduino Tutorial - LDC - Menu

https://www.instructables.com/id/Arduino-Tutorial-LDC-Menu/

Caso queiram saber mais sobre a RTC DS1307, o LCD1602 ou o "Buzzer" vejam as suas datasheet (Ver ficheiros abaixo), para saber mais sobre o Arduino UNO visitem a página oficial do Arduino em https://store.arduino.cc/arduino-uno-rev3.

Step 1: Montagem

Nesta montagem é utilizada uma "Breadboard" onde realizamos as ligações eléctricas entre os vários componentes, entre os quais um LCD1602 onde é visualizada a informação do relógio e do alarme, uma placa RTC DS1307 que fornece essa informação ao Arduino, também são utilizados 3 botões e as suas respectivas resistências, sendo estes responsáveis pelo acerto do relógio e a navegação a selecção de edição da hora do relógio ou de alarme e por fim um pequeno "Buzzer"que produz um aviso sonoro sempre que a hora do relógio for igual à hora do alarme.

Material necessário:

  • 1x Arduino UNO;
  • 1x Cabo USB;
  • 1x Breadboard;
  • 1x LCD1602;
  • 1x Resistência 220Ω;
  • 1x Potenciómetro 10KΩ;
  • 1x RTC DS1307;
  • 3x Botões (Push Button);
  • 3x Resistências 1KΩ;
  • 1x Buzzer Module.

Instalação do LCD 1602:

Como se pode observar na imagem da montagem completa não utilizamos todos os pinos do LCD, pois cada pino tem uma função especifica, assim para explicar mais facilmente o funcionamento do LCD, os pinos foram agrupados em em 3 grupos, o grupo dos Pinos de Alimentação, o de Pinos de Comunicação e o de Pinos de Informação (Ver legenda acima).

Pinos de Alimentação:

  • Gnd;
  • Vcc;
  • V0;
  • LED - ou A (Anodo);
  • LED + ou K (Catodo).

As alimentações do LCD são realizadas através do pino GND e pelo pino VCC, tendo este ultimo que ter uma tensão de cerca de 5V.

No pino V0 será possível ajustar o contraste dos caracteres através de um potenciómetro de 10KΩ, que estará montado de forma a funcionar como um divisor de tensão alterando assim a tensão entre 0 e 5V (Ver imagem acima).

Os pinos A e K que alimentam a luz de fundo do LCD, sendo constituída por LED, são também ligados aos pinos GND e 5V do Arduino UNO, no entanto, devemos ligar em série uma resistência de 220Ω, para que o brilho não seja demasiado intenso, podendo danificar os LED internos do LCD.

Pinos de Comunicação:

  • RS (Register Select);
  • R/W (Read / Write);
  • E (Enable).

Nos pinos de comunicação apenas teremos que colocar o pino R/W ligado a GND para que seja permitido escrever no LCD e assim aparecer os caracteres, caso contrario podemos estar a ler o dados guardados na memoria interna do LCD ficando este em branco.

Pinos de Informação:

  • D0;
  • D1;
  • D2;
  • D3;
  • D4;
  • D5;
  • D6;
  • D7.

Nesta montagem apenas utilizamos apenas 4 dos 8 possíveis pinos de informação, mas para isso será necessário utilizar no código a biblioteca LiquidCrystal.h, permitindo ler o "Byte" de informação dividido em 2 partes, ou seja, são lidos 4bits de cada vez.

Para isso esta biblioteca controla os pinos de comunicação, permitindo que o LCD saiba qual é a forma que irá receber a informação vinda do Arduino, através de 8bits e assim utilizando os 8 pinos de informação ou através de 4btis com apenas 4 pinos.

Instalação da RTC DS1307:

Este componente tem a função de determinar a informação de data e hora, fornecendo essa informação de forma precisa, mesmo quando a alimentação externa é desligada por algum motivo. Nesta montagem utilizámos uma RTC DS1307 que contem 2 conjuntos de pinos, contendo ambos os grupos de Pinos de Alimentação e os Pinos de Comunicação, no entanto iremos utilizar o conjunto com menos pinos, pois para esta montagem apenas são necessários os pinos GND, VCC, SDA e SCL (Ver imagem acima).

Pinos de Alimentação:

  • GND;
  • VCC;
  • BAT.

Apesar da placa RTC conter a sua própria alimentação, através de uma pequena bateria do tipo botão, esta também tem pinos para a sua alimentação externa através dos pinos GND e VCC, tendo este ultimo que ter uma tensão de cerca de 5V.

O pino BAT apesar de não ser um pino de alimentação foi colocado neste grupo, pois está ligado directamente à bateria tipo botão da RTC, sendo muito utilizado para monitorização da carga desta bateria.

Pinos de Comunicação:

  • SCL;
  • SDA;
  • DS;
  • SQ.

Os pinos de comunicação SCL e SDA da placa RTC fazem parte de um sistema de comunicação com o protocolo I2C. Este sistema permite comunicar com um ou mais equipamentos através de apenas 2 únicas linhas de comunicação, sendo o pino SDA ou "Serial Data" a linha que transmite e recebe a informação, no entanto, o pino SCL ou "Serial Clock" é o responsável por sincronizar a comunicação entre os equipamento, ou seja, permite ao equipamento saber quando enviar ou receber a informação sem se descoordenarem (Ver imagem acima).

Relativamente ao Arduino UNO, este tem pinos dedicados para utilização deste protocolo de comunicação sendo nestes que devemos ligar os pinos da placa RTC. No Arduino UNO estes 2 pinos encontra-se no grupo dos pinos de entrada analógica acumulando assim funções, deste modo encontramos o pino SCL no pino A5 e o pino SDA no pino A4, dependendo da versão da placa do Arduino estes pinos podem estar identificados no caso do Arduino UNO isso não acontece (Ver imagem acima).

Caso queiram saber mais sobre o sistema de comunicação I2C, vejam a explicação mais detalhada através o seguinte tutorial:

Arduino Tutorial - SD Card - LCD I2C

https://www.instructables.com/id/Arduino-Tutorial-SD-Card-LCD-I2C/

Um dos outros pinos é o pino DS, este está ligado a um pequeno sensor de temperatura instalado na nossa placa RTC, sendo através deste pino que são transmitidos os dados relativos à temperatura do sensor, no entanto nesta montagem esta função não será utilizada (Ver ficheiro abaixo).

Já o pino SQ normalmente não é utilizado, pois apenas contem apenas um sinal de onda quadrada, não tendo uma função essencial ou relevante para a utilização da RTC, no entanto, existem algumas montagens onde este pode ser utilizado, sendo este ligado a um pequeno LED indicando assim que a RTC está a funcionar correctamente.

Instalação do Buzzer Module:

O modulo do "Buzzer" é um dispositivo electromecânico ou piezoeléctrico montado numa pequena placa, que produz um sinal sonoro, tendo nesta montagem a função de alertar a activação do alarme despertador.

Este "Buzzer"funciona a uma tensão de 5V, podendo ser alimentado directamente a uma fonte de alimentação DC produzindo um som contínuo, no entanto (Ver imagem acima), este tipo de "Buzzer" está incorporado num circuito com o transístor permitindo um melhor controlo deste equipamento (Ver ficheiro abaixo).

Pinos:

  • Gnd;
  • Vcc;
  • I/C;

Com os equipamentos mais complexos montados, colocamos finalmente os 3 botões com as suas respectivas resistência de 1KΩ na "Breadboard" e ligamos-os aos pinos de entradas digitais. Com estes botões na montagem poderemos seleccionar no LCD quais os dados queremos editar, realizando assim o acerto do relógio ou hora de alarme (Ver esquema abaixo).

Estes botões devem ser identificados e dispostos de forma a que seja fácil e intuitivo utiliza-los, assim os botões serão identificados com MAIS, MENU e MENOS.

Para relembrar o funcionamento ou saber mais sobre os pinos de sinal digital sendo utilizados como entradas, vejam o seguinte tutorial:

Arduino Tutorial - Digital Input - Button - Monitor Serial

https://www.instructables.com/id/Arduino-Tutorial-Digital-Input-Button-Monitor-Seri/

Step 2: Código

Agora no código começamos por importar as bibliotecas TimeLib.h, Wire.h e a DS1307RTC.h, estas bibliotecas facilitam a programação, pois estas contêm funções e referencias criadas especificamente para trabalhar com a placa RTC.

A biblioteca TimeLib.h activa as funcionalidades de tempo, como variáveis para os segundos, minutos, hora, dia , mês, etc, facilitando assim a determinação da hora e data.

void loop(){	//Variáveis com valores de tempo:
	second();
	minute();
	hour();
	day();
	month();
	year();
	now();	//Hora e data que está defina neste momento.
	
	//Verifica se tempo está definido ou sincronizado:
	timeStatus()
		//Devolve os seguintes valores:
		timeNotSet	//O valor de tempo não está definido;
		timeNeedsSync	//O Valor de tempo foi definido mas a sincronização falhou.
		timeSet		//O Valor de tempo está definido e sincronizado.	
	
	int h, m, s, D, M, A;		// Variáveis para alteração da hora e data.
	setTime (h, m, s, D, M, A);	//Alterar ou definir a hora e data.

	//Configura o valor de tempo sincronizado de outro equipamento.
	setSyncProvider(getTimeFunction);
}

A biblioteca Wire.h é responsável pelo controlo do sistema de comunicação com o protocolo I2C, caso queiram saber mais sobre esta biblioteca vejam a ligação https://www.arduino.cc/en/Reference/Wire. Por fim, a biblioteca DS1307RTC.h activa as funcionalidades que permitem a leitura e escrita dos dados de tempo guardados na memória da RTC.

void loop(){
	int h, m, s, D, M, A;	// Variáveis para alteração da hora e data.
	//Define uma nova hora e data:
	setTime(h, m, s, D, M, A);
	//Grava na RTC os dados de tempo:
	RTC.set(now());
	//Lê na RTC os dados de tempo:
	RTC.get();
}

Alem destas 3 bibliotecas também deve ser importada a biblioteca EEPROM.h que permite gravar e ler dados gravados na memória não volátil do Arduino, sendo assim possível memorizar a hora de alarme do despertador mesmo que este fique sem energia, não perdendo essa informação.

A memória não volátil é diferente nos vários tipos de placas do Arduino podendo estas ter diferentes capacidades:

  • ATmega328 - 1024 Bytes - 1KB;
    • Arduino UNO;
    • Arduino MICRO;
    • Arduino NANO;
    • Arduino MINI;
  • ATmega168 - 512 Bytes;
  • ATmega8 - 512 Bytes;
  • ATmega1280 - 4096 Bytes;
    • Arduino MEGA.
  • ATmega2560 - 4096 Bytes - 4KB.
    • Arduino MEGA.

Nesta montagem utilizamos um Arduino UNO e como observar este tem uma memória de 1KB, vejam também as suas especificações técnicas através da ligação https://store.arduino.cc/arduino-uno-rev3. Este tipo tem 1024 endereços onde podemos guardar os nosso dados, no entanto teremos de ter em atenção que apenas podemos guardar nesses endereços dados até 8bits, ou seja, com um valor decimal até 256 (Ver quadro acima).

Para utilizar a memória EEPROMdo Arduino através desta biblioteca, poderemos utilizar os seguintes comandos, caso queiram saber mais sobre estes e outros comandos relativos a esta biblioteca, vejam as suas referencia em https://www.arduino.cc/en/Reference/EEPROM.

//Apagar os dados na EEPROM.
int i;	//Variável para os endereços da EEPROM;
	
void loop(){
	for (int i=0; i<EEPROM.length(); i++){
		EEPROM.write(i, 0);	//"i" = Endereço onde será escritos 0.
	}
}
//-----------------------------------------------------
//Ler os dados gravados da EEPROM.
int i;		//Variável para os endereços da EEPROM;
int Valor;	//Variável para leitura da EEPROM;

void loop(){
	Valor = EEPROM.read(i);	//"i" = Endereço onde serão lidos os dados.
}
//-----------------------------------------------------
//Gravar dados na EEPROM.
int i;		//Variável para os endereços da EEPROM;
int Valor;	//Variável para leitura da EEPROM;

void loop(){
	EEPROM.write(i, Valor);	//"i" = Endereço onde serão lidos os dados.
}

Por fim importamos a biblioteca LiquidCrystal.h que facilita muito a programação do código para o LCD, sendo apenas necessário configurar 2 funções para que este fique a funcionar em pleno, o que caso contrario seria muitas mais.

//Definir os pinos de comunicação e informação do LCD:
LiquidCrystal lcd ("RS", "E", "D7", "D6", "D5", "D4");

e

void setup(){
	//Inicia a comunicação com LCD 16x2:
	lcd.begin(2, 16);
}

Para escrever no LCD será necessário primeiro definir o local onde se começará a escrever, ou seja, qual a coluna e a linha, só depois imprimimos o texto que queremos, tendo em atenção que este LCD apenas tem 16 colunas e 2 linhas, no caso do texto passar esses limites do LCD não serão visíveis todos caracteres.

void loop(){
	//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
	lcd.setCursor(0, 0);
	
	//Escreve no LCD:
	lcd.print("Bateria da RTC INOP");
}

E pronto, este é o código completo para a nossa montagem, onde são utilizados os todos conceitos descritos anteriormente tornando possível a concretização de um pequeno relógio despertador, onde se pode ver e alterar a hora do relógio e do alarme e que activa um pequeno "Buzzer" sempre que estas são coincidentes (Ver ficheiro abaixo).

#include <TimeLib.h>	//Importar a "TimeLib" library.
#include <Wire.h>	//Importar a "Wire" library.
#include <DS1307RTC.h>	//Importar a "DS1307RTC" library.

#include <EEPROM.h>	//Importar a EEPROM library.

#include <LiquidCrystal.h>	//Importar a LCD library.

//Definir os pinos de comunicação e informação do LCD.
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

int Botao_mais = 2;	//Variável para selecção do pino de entrada digital.
int Botao_menu = 3;	//Variável para selecção do pino de entrada digital.
int Botao_menos = 4;	//Variável para selecção do pino de entrada digital.

int Buzzer = 6;		//Variável para selecção do pino de saída digital.

int Num_Pag = 0;	//Variável para selecção da página do menu.

int Num_Menu = 1;	//Variável para selecção da opção da página.

int H, M, S;	//Variáveis para alteração da hora do relógio.
int A_H, A_M;	//Variáveis para alteração da hora do alarme.
int A_Act;	//Variável para activação do alarme.

//Variável array de selecção do nome da opção da página do menu.
char Lista_menu[] = {' ', 'h', 'm', 's'};

//Correr a função SETUP apenas uma vez após ser pressionado reset:
void setup() {
	//Iniciar a comunicação com LCD de 16x2:
	lcd.begin(2, 16);
	//Definição do tipo de pino (Saída ou entrada):
	pinMode(Botao_mais, INPUT);
	//Definição do tipo de pino (Saída ou entrada):
	pinMode(Botao_menu, INPUT);
	//Definição do tipo de pino (Saída ou entrada):
	pinMode(Botao_menos, INPUT);
	//Definição do tipo de pino (Saída ou entrada):
	pinMode(Buzzer, OUTPUT);
	//Função para obter o tempo da RTC.
	setSyncProvider(RTC.get);
	//Verifica se o valor de tempo não está definido.
	if (timeStatus() != timeSet) {
		//Escreve no LCD:
		lcd.print("BAT. do RTC INOP");
		//Atraso para o próximo passo:
		delay(3000);
		//Apaga a informação do LCD.
		lcd.clear();
		//Alteração dos dados de hora e data.
		H = 1;
		M = 1;
		S = 1;
		//Grava no RTC uma nova hora e data.
		setTime(H, M , S , 1 , 10 , 2001 );
		RTC.set(now());
	}
	else {
		//Escreve no LCD:
		lcd.print("RTC OK");
		//Atraso para o próximo passo:
		delay(3000);
		//Apaga a informação do LCD.
		lcd.clear();
	}
}

//Correr a função LOOP repetidamente:
void loop() {
	//Correr a função:
	Pagina_Menu_0();
	
	//Correr a função:
	Pagina_Hora_1();

	//Correr a função:
	Pagina_Alarm_2();

	//Correr a função:
	Relogio();
	
	//Correr a função:
	Alarme();

	//Atraso para o próximo passo:
	delay(500);
}

//>>>Página 0 - Menu:
	void Pagina_Menu_0() {
	//Condição para aparecer a página:
	if (Num_Pag == 0){
		//Apaga a informação do LCD.
		lcd.clear();
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(1, 0);
		//Escreve no LCD:
		lcd.print("Hora: ");
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(1, 1);
		//Escreve no LCD:
		lcd.print("Alarme: ");
		//Condição para seleccionar página 1:
		if (Num_Menu == 1) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(0, 0);
			//Escreve no LCD:
			lcd.print(">");
		}
		//Condição para seleccionar página 2:
		else if (Num_Menu == 2) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(0, 1);
			//Escreve no LCD:
			lcd.print(">");
		}
		//Condição para aparecer activação alarme:
		if (A_Act == 1) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(13, 1);
			//Escreve no LCD:
			lcd.print("(A)");
		}

		//Condição para acção dos botões na página:
		if (digitalRead(Botao_mais) == HIGH) {
			//Condição para seleccionar a página:
      			if (Num_Menu == 1) {
        			//Altera o valor de selecção do menu.
				Num_Menu = Num_Menu + 1;
			}
			//Condição para activar alarme:
			if (Num_Menu == 2) {
				if (A_Act == 1) {
					A_Act = 0;
				}
				else {
					A_Act = 1;
				}
				//Grava na EEPROM a activação do alarme.
				EEPROM.write(2, A_Act);
			}
		}

		//Condição para acção dos botões na página:
		if (digitalRead(Botao_menos) == HIGH) {
			//Condição para seleccionar a página:
			if (Num_Menu == 2) {
				//Altera o valor de selecção do menu.
				Num_Menu = Num_Menu - 1;
			}
		}
		//Condição para acção dos botões na página:
		if (digitalRead(Botao_menu) == HIGH) {
			//Condição para seleccionar a página:
			if (Num_Menu == 1) {
				//Altera o valor da página.
				Num_Pag = 1;
				//Alterar o valor de selecção do menu.
				Num_Menu = 0;
				//Apaga a informação do LCD.
				lcd.clear();
			}
			//Condição para seleccionar página:
			else if (Num_Menu == 2) {
				//Altera o valor da página.
				Num_Pag = 2;
				//Altera o valor de selecção do menu.
				Num_Menu = 0;
				//Apaga a informação do LCD.
				lcd.clear();
			}
		}
	}
}

//>>>Página 1 - Acerto do relógio:
void Pagina_Hora_1() {
	//Condição para aparecer a página:
	if (Num_Pag == 1) {
		//Apaga a informação do LCD.
		lcd.clear();
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(0, 0);
    		//Escreve no LCD:
    		lcd.print("Hora:");

    		//Condição para activar o acerto do relógio:
    		if (digitalRead(Botao_menu) == HIGH) {
      			//Altera o valor de selecção do menu.
      			Num_Menu = Num_Menu + 1;
    		}
    		
		//Condição para seleccionar o nome do dado a alterar no relógio:
    		if (Num_Menu < 4) {
      			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
      			lcd.setCursor(15, 0);
      			//Escreve no LCD:
      			lcd.print(Lista_menu[Num_Menu]);
    		}
    		//Condição para voltar ao relógio.
    		else if (Num_Menu > 4) {
			//Altera o valor de selecção do menu.
      			Num_Menu = 0;
    		}
		//Condição para sair do acerto do relógio:
		if (Num_Menu == 0) {     
			//Condição para acção dos botões na página:
			if (digitalRead(Botao_menos) == HIGH) {
				//Altera o valor da página.
				Num_Pag = 0;
				//Altera o valor de selecção do menu.
				Num_Menu = 1;
			}
		}
	}
}

//>>>Página 2 - Acerto do alarme.
void Pagina_Alarm_2() {
	//Condição para aparecer a página:
	if (Num_Pag == 2) {
		//Apaga a informação do LCD.
		lcd.clear();
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(0, 0);
		//Escreve no LCD:
		lcd.print("ALARME:");

		//Condição para activar o acerto do alarme:
		if (digitalRead(Botao_menu) == HIGH) {
			//Altera o valor de selecção do menu.
			Num_Menu = Num_Menu + 1;
		}

		//Condição para seleccionar o nome do dado a alterar no alarme:<br>		if (Num_Menu < 3) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(15, 0);
			//Escreve no LCD:
			lcd.print(Lista_menu[Num_Menu]);
		}
		//Condição para voltar ao alarme.
		else if (Num_Menu > 1) {
		
			Num_Menu = 0;
		}
		//Condição para sair da alteração do alarme:
		if (Num_Menu == 0) {
			//Condição para acção dos botões na página:
			if (digitalRead(Botao_menos) == HIGH) {
				//Altera o valor de selecção do menu.
				Num_Pag = 0;
				//Altera o valor de selecção do título do menu.
				Num_Menu = 2;   
			}
		}
	}
}

//>>>Função de escrita dos dados do relógio no LCD:
void Relogio() {
	//Verifica se o valor de tempo está definido.
	if (timeStatus() == timeSet) {
		//Condição para aparecer os dados do relógio na página:
		if (Num_Pag == 0) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(8, 0);
			//Escreve no LCD:
			if (hour() < 10)
				lcd.print('0');
				lcd.print(hour());
				lcd.print(":");
			if (minute() < 10)
				lcd.print('0');
				lcd.print(minute());
				lcd.print(":");
			if (second() < 10)
				lcd.print('0');
				lcd.print(second());
		}
		//Condição para aparecer os dados do relógio na página:
		else if (Num_Pag == 1) {
			//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
			lcd.setCursor(0, 1);
			//Escreve no LCD:
			if (hour() < 10)
				lcd.print('0');
				lcd.print(hour());
				lcd.print(":");
			if (minute() < 10)
				lcd.print('0');
				lcd.print(minute());
				lcd.print(":");
			if (second() < 10)
				lcd.print('0');
				lcd.print(second());
		}
	}
	else {
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(0, 0);
		//Escreve no LCD:
		lcd.print("BAT RTC INOP");
		//Atraso para o próximo passo:
		delay(3000);
		//Alteração dos dados de hora e data.
		H = 1;
		M = 1;
		S = 1;
		//Grava no RTC uma nova hora e data.
		setTime(H, M, S, 1, 1, 2001);
		RTC.set(now());
	}
	
	//Condição para acerto das "horas":
	if (Num_Pag == 1 & Num_Menu == 1) {
		//Condição para incrementar +1 hora:
		if (digitalRead(Botao_mais) == HIGH) {
			H = hour() + 1;
			//Grava no RTC uma nova hora e data.
			setTime(H, minute(), second(), day(), month(), year());
			RTC.set(now());
		}
		//Condição para retirar -1 hora:
		if (digitalRead(Botao_menos) == HIGH) {
			H = hour() - 1;
			//Grava no RTC uma nova hora e data.
			setTime(H, minute(), second(), day(), month(), year());
			RTC.set(now());
		}
	}
	
	//Condição para acerto dos "minutos":
	else if (Num_Pag == 1 & Num_Menu == 2) {
		//Condição para incrementar +1 minuto:
		if (digitalRead(Botao_mais) == HIGH) {
			M = minute() + 1;
			//Grava no RTC uma nova hora e data.
			setTime(hour(), M, second(), day(), month(), year());
			RTC.set(now());
		}
		//Condição para retirar -1 minuto:
		if (digitalRead(Botao_menos) == HIGH) {
			M = minute() - 1;
			//Grava no RTC uma nova hora e data.
			setTime(hour(), M, second(), day(), month(), year());
			RTC.set(now());
		}
	}

	//Condição para acerto dos "segundos":
	else if (Num_Pag == 1 & Num_Menu == 3) {
		//Condição para incrementar +1 segundo:
		if (digitalRead(Botao_mais) == HIGH) {
			S = second() + 1;
			//Grava no RTC uma nova hora e data.
			setTime(hour(), minute(), S, day(), month(), year());
			RTC.set(now());
		}
		//Condição para retirar -1 segundo:
		if (digitalRead(Botao_menos) == HIGH) {
			S = second() - 1;
			//Grava no RTC uma nova hora e data.
			setTime(hour(), minute(), S, day(), month(), year());
			RTC.set(now());
		}
	}
}

//>>>Função de escrita dos dados do Alarme no LCD:
void Alarme() {
	//Define os dados de hora do alarme guardados na EEPROM:
	A_H = EEPROM.read(0);
	A_M = EEPROM.read(1);
	A_Act = EEPROM.read(2);

	//Condição para aparecer os dados do Alarme na página:<br>	if (Num_Pag == 0) {
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(8, 1);
		//Escreve no LCD:
		if(A_H < 10)
			lcd.print('0');
			lcd.print(A_H);
			lcd.print(":");
		if(A_M < 10)
			lcd.print('0');
			lcd.print(A_M);
	}
	//Condição para aparecer os dados do Alarme na página:
	else if (Num_Pag == 2) {
		//Define a coluna (em 16) e a linha (em 2) do LCD onde escrever:
		lcd.setCursor(0, 1);
		//Escreve no LCD:
		if(A_H < 10)
			lcd.print('0');
			lcd.print(A_H);
			lcd.print(":");
		if(A_M < 10)
			lcd.print('0');
			lcd.print(A_M);
	}

	//Condição para a alteração das "horas":
	if (Num_Pag == 2 & Num_Menu == 1) {
		//Condição para incrementar +1 hora:
		if (digitalRead(Botao_mais) == HIGH) {
			A_H = A_H + 1;
			//Grava na EEPROM uma nova hora no alarme.
			EEPROM.write(0, A_H);
		}
		//Condição para retirar -1 hora:
		if (digitalRead(Botao_menos) == HIGH) {
			A_H = A_H - 1;
			//Grava na EEPROM uma nova hora no alarme.
			EEPROM.write(0, A_H);
		}
	}
	
	//Condição para a alteração dos "minutos":
	if (Num_Pag == 2 & Num_Menu == 2) {
		//Condição para incrementar +1 minuto:
		if (digitalRead(Botao_mais) == HIGH) {
			A_M = A_M + 1;
			//Grava na EEPROM um novo minuto no alarme.
			EEPROM.write(1, A_M);
		}
		//Condição para retirar -1 minuto:
		if (digitalRead(Botao_menos) == HIGH) {
			A_M = A_M - 1;
			//Grava na EEPROM um novo minuto no alarme.
			EEPROM.write(1, A_M);
		}
	}

	//Condição para activação do alarme:
	if (hour()== A_H & minute()== A_M & A_Act == 1){
		//Liga o alarme (HIGH e nível alto):
		digitalWrite(Buzzer, HIGH);
		//Atraso para o próximo passo:
		delay(500);
		//Desliga o alarme (LOW e nível baixo):
		digitalWrite(Buzzer, LOW);
		//Atraso para o próximo passo:
		delay(500);
	}
}

Caso queiram saber mais ou tenham dúvidas sobre estas ou outras referências no código, vejam a sua explicação detalhada no site oficial do Arduino, através da ligação https://www.arduino.cc/en/Reference/HomePage.
Procurem os nossos tutoriais sobre o Arduino, onde são explicadas diversas montagens e o funcionamento dos seus componentes, já agora visitem também o nosso canal no Youtube, Instagram, Facebook ou Twitter.

Arduino Contest 2017

Participated in the
Arduino Contest 2017