NUNCA MAIS CHEGUE ATRASADO! RELÓGIO DESPERTADOR com ARDUINO

Atire a primeira pedra quem nunca chegou atrasado para um evento, seja ele uma reunião, ou simplesmente a um almoço com os amigos. Então quando se fala em acordar de manhã a horas, a situação pode tornar-se ainda pior! Neste projeto, vamos acabar com esses atrasos matinais de uma forma fácil e divertida, utilizando, claro, a nossa placa microcontroladora Arduino!

Para este projeto, vamos precisar dos seguintes elementos:

Imagem Produto Comprar
Arduino (Nano)

Display LCD 20×4 I2C

Breadboard 830 Pinos

4 Botões de Pressão

Módulo RTC DS1307 I2C

Buzzer Passivo

Fios de Ligação Macho-Macho

Fios de Ligação Macho-Fêmea

 

Montagem do Circuito

Recorremos à comunicação I2C entre o Arduino e o módulo RTC e o LCD para minimizar a desorganização do nosso projeto. O buzzer passivo irá garantir o sinal sonoro uma vez ativado o alarme.

Vamos começar por montar o circuito com todos os componentes acima mencionados de acordo com este esquema de montagem:

 

Preparação do Ambiente e Envio do Código

Vamos começar por transferir as bibliotecas necessárias para o projeto:

Biblioteca LiquidCrytal_I2C.h
Biblioteca RTCLib.h

No nosso ambiente do Arduino IDE, adicionamos as bibliotecas necessárias em “Rascunho” -> “Incluir Biblioteca” -> “Adicionar Biblioteca .ZIP” e selecionando, um por um, os ficheiros .ZIP transferidos.

 

Após selecionar a respetiva placa microcontroladora a utilizar, basta compilar e carregar o seguinte código:

/*Código para o Projeto: Alarmuino - Relógio Despertador com Arduino
   Utilizando os 4 botões de pressão, navegue pelos menus para ativar/desativar o alarme e para definir o mesmo.
   Botão Menu ====> Botão conectado ao pino 2, utilizado para aceder ou sair dos menus
   Botão Confirmação ====> Botão conectado ao pino 3, utilizado para entrar nos menuns ou confirmar escolhas
   Botão Anterior ====> Botão conectado ao pino 4, utilizado para diminuir ou substrair input's do utilizador
   Botão Avançar ====> Botão conectado ao pino 5, utilizado para aumentar ou acrescentar input's do utilizador
   Conectar um dispositivo de saída ao pino 6 (Buzzer) para resposta sonora ou visual à atuação do alarme
   www.electrofun.pt/blog/nunca-mais-chegue-atrasado-relogio-despertador-com-arduino/
   Electrofun@2022 ---> www.electrofun.pt
*/

//Inclusão de Bibliotecas
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"

//Definição de pinos
#define pinoBotaoMenu 2
#define pinoBotaoConfirmacao 3
#define pinoBotaoAnterior 4
#define pinoBotaoAvancar 5
#define pinoBuzzer 6

LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;

//Declaração de variáveis
int debouce = 200; //Esta variável é utilizada apenas para conhecimento do utilizador do motivo da função delay() no pedaço de código
int minutoAtual = 60;
int horaAlarme = 12;
int minutoAlarme = 30;
int estadoBotaoMenu, estadoBotaoConfirmacao, estadoBotaoAnterior, estadoBotaoAvancar;
bool alarmeCancelado;
bool alarmeAtivado = false;
bool idaMenu = false;


//Caracteres Necessários em BitMap
byte simboloSino[] = {
  B01110,
  B01110,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
  B00100
};

byte setaDireita[] = {
  B10000,
  B11000,
  B11100,
  B11111,
  B11111,
  B11110,
  B11000,
  B10000
};

byte setaEsquerda[] = {
  B00001,
  B00011,
  B00111,
  B11111,
  B11111,
  B01111,
  B00011,
  B00001
};

void setup() {
  pinMode(pinoBotaoMenu, INPUT_PULLUP);
  pinMode(pinoBotaoConfirmacao, INPUT_PULLUP);
  pinMode(pinoBotaoAnterior, INPUT_PULLUP);
  pinMode(pinoBotaoAvancar, INPUT_PULLUP);
  pinMode(pinoBuzzer, OUTPUT);
  if (! rtc.begin()) {
    while (1) delay(10)
      ;
  }
  if (! rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  lcd.init();
  lcd.backlight();
  lcd.setCursor(5, 0);
  lcd.print("Alarmuino");
  lcd.setCursor(0, 1);
  lcd.print("Relogio Despertador");
  lcd.setCursor(4, 2);
  lcd.print("com Arduino");
  lcd.setCursor(1, 3);
  lcd.print("by Electrofun@2022");
  delay(5000);
  lcd.clear();
}

void loop() {
  DateTime now = rtc.now();
  if (minutoAtual != now.minute() || idaMenu == true) {
    if (minutoAtual != now.minute()) {
      alarmeCancelado = false;
    }
    idaMenu == false;
    lcd.setCursor(0, 0);
    lcd.print("Hora Atual:");
    if (now.hour() < 10) {
      lcd.setCursor(12, 0);
      lcd.print("0");
      lcd.setCursor(13, 0);
      lcd.print(now.hour());
    } else {
      lcd.setCursor(12, 0);
      lcd.print(now.hour());
    }
    lcd.setCursor(14, 0);
    lcd.print(":");
    if (now.minute() < 10) {
      lcd.setCursor(15, 0);
      lcd.print("0");
      lcd.setCursor(16, 0);
      lcd.print(now.minute());
    } else {
      lcd.setCursor(15, 0);
      lcd.print(now.minute());
    }
    lcd.setCursor(0, 1);
    lcd.print("Data:");
    if (now.day() < 10) {
      lcd.setCursor(6, 1);
      lcd.print("0");
      lcd.setCursor(7, 1);
      lcd.print(now.day());
    } else {
      lcd.setCursor(6, 1);
      lcd.print(now.day());
    }
    lcd.setCursor(8, 1);
    lcd.print("/");
    if (now.month() < 10) {
      lcd.setCursor(9, 1);
      lcd.print("0");
      lcd.setCursor(10, 1);
      lcd.print(now.month());
    } else {
      lcd.setCursor(9, 1);
      lcd.print(now.month());
    }
    lcd.setCursor(11, 1);
    lcd.print("/");
    lcd.setCursor(12, 1);
    lcd.print(now.year());
    lcd.setCursor(0, 3);
    lcd.print("Alarme:");
    if (horaAlarme < 10) {
      lcd.setCursor(8, 3);
      lcd.print("0");
      lcd.setCursor(9, 3);
      lcd.print(horaAlarme);
    } else {
      lcd.setCursor(8, 3);
      lcd.print(horaAlarme);
    }
    lcd.setCursor(10, 3);
    lcd.print(":");
    if (minutoAlarme < 10) {
      lcd.setCursor(11, 3);
      lcd.print("0");
      lcd.setCursor(12, 3);
      lcd.print(minutoAlarme);
    } else {
      lcd.setCursor(11, 3);
      lcd.print(minutoAlarme);
    }
    if (alarmeAtivado == true) {
      lcd.createChar(0, simboloSino);
      lcd.setCursor(19, 3);
      lcd.write(0);
    }
  }
  if (now.minute() == minutoAlarme && now.hour() == horaAlarme) {
    if (alarmeAtivado == true && alarmeCancelado == false) {
      tone(pinoBuzzer, 5000);
      delay(500);
      noTone(pinoBuzzer);
      delay(500);
    }
  }
  if (digitalRead(pinoBotaoConfirmacao) == 0 && alarmeAtivado == true) {
    noTone(pinoBuzzer);
    alarmeCancelado = true;
  }
  estadoBotaoMenu = digitalRead(pinoBotaoMenu);
  if (estadoBotaoMenu == 0) {
    delay(debouce);
    menu1Alarme();
    idaMenu = true;
  }
  minutoAtual = now.minute();
}

void menu1Alarme() {
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("1 - Alarme");
  if (alarmeAtivado == 1) {
    lcd.setCursor(7, 2);
    lcd.print("Ligado");
  } else if (alarmeAtivado == 0) {
    lcd.setCursor(5, 2);
    lcd.print("Desligado");
  }
  lcd.createChar(1, setaEsquerda);
  lcd.setCursor(0, 3);
  lcd.write(1);
  lcd.createChar(2, setaDireita);
  lcd.setCursor(19, 3);
  lcd.write(2);
  do {
    estadoBotaoMenu = digitalRead(pinoBotaoMenu);
    estadoBotaoConfirmacao = digitalRead(pinoBotaoConfirmacao);
    estadoBotaoAnterior = digitalRead(pinoBotaoAnterior);
    estadoBotaoAvancar = digitalRead(pinoBotaoAvancar);
  } while (estadoBotaoMenu == 1 && estadoBotaoConfirmacao == 1 && estadoBotaoAnterior == 1 && estadoBotaoAvancar == 1);
  if (estadoBotaoConfirmacao == 0) {
    delay(200);
    alarmeAtivado = !alarmeAtivado;
    menu1Alarme();
  } else if (estadoBotaoAnterior == 0) {
    delay(debouce);
    menu2Alarme();
  } else if (estadoBotaoAvancar == 0) {
    delay(debouce);
    menu2Alarme();
  } else if (estadoBotaoMenu == 0) {
    delay(debouce);
    lcd.clear();
    return;
  }
}

void menu2Alarme() {
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("2 - Definir Alarme");
  if (horaAlarme < 10) {
    lcd.setCursor(7, 2);
    lcd.print("0");
    lcd.setCursor(8, 2);
    lcd.print(horaAlarme);
  } else {
    lcd.setCursor(7, 2);
    lcd.print(horaAlarme);
  }
  lcd.setCursor(9, 2);
  lcd.print(":");
  if (minutoAlarme < 10) {
    lcd.setCursor(10, 2);
    lcd.print("0");
    lcd.setCursor(11, 2);
    lcd.print(minutoAlarme);
  } else {
    lcd.setCursor(10, 2);
    lcd.print(minutoAlarme);
  }
  lcd.setCursor(0, 3);
  lcd.write(1);
  lcd.setCursor(19, 3);
  lcd.write(2);
  do {
    estadoBotaoMenu = digitalRead(pinoBotaoMenu);
    estadoBotaoConfirmacao = digitalRead(pinoBotaoConfirmacao);
    estadoBotaoAnterior = digitalRead(pinoBotaoAnterior);
    estadoBotaoAvancar = digitalRead(pinoBotaoAvancar);
  } while (estadoBotaoMenu == 1 && estadoBotaoConfirmacao == 1 && estadoBotaoAnterior == 1 && estadoBotaoAvancar == 1);
  if (estadoBotaoConfirmacao == 0) {
    delay(debouce);
    definirAlarme();
  } else if (estadoBotaoAnterior == 0) {
    delay(debouce);
    menu1Alarme();
  } else if (estadoBotaoAvancar == 0) {
    delay(debouce);
    menu1Alarme();
  } else if (estadoBotaoMenu == 0) {
    delay(debouce);
    lcd.clear();
    return;
  }
}

void definirAlarme() {
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("2 - Definir Alarme");
  //Definir Hora Alarme
  do {
    if (horaAlarme < 10) {
      lcd.setCursor(7, 2);
      lcd.print("0");
      lcd.setCursor(8, 2);
      lcd.print(horaAlarme);
    } else {
      lcd.setCursor(7, 2);
      lcd.print(horaAlarme);
    }
    lcd.setCursor(9, 2);
    lcd.print(":");
    if (minutoAlarme < 10) { lcd.setCursor(10, 2); lcd.print("0"); lcd.setCursor(11, 2); lcd.print(minutoAlarme); } else { lcd.setCursor(10, 2); lcd.print(minutoAlarme); } estadoBotaoAnterior = digitalRead(pinoBotaoAnterior); estadoBotaoAvancar = digitalRead(pinoBotaoAvancar); if (estadoBotaoAvancar == 0) { delay(debouce); horaAlarme++; if (horaAlarme > 23) {
        horaAlarme = 0;
      }
    } else if (estadoBotaoAnterior == 0) {
      delay(debouce);
      horaAlarme--;
      if (horaAlarme < 0) {
        horaAlarme = 23;
      }
    }
  } while (digitalRead(pinoBotaoConfirmacao) == 1);
  delay(debouce);

  //Definir Minutos Alarme
  do {
    if (horaAlarme < 10) {
      lcd.setCursor(7, 2);
      lcd.print("0");
      lcd.setCursor(8, 2);
      lcd.print(horaAlarme);
    } else {
      lcd.setCursor(7, 2);
      lcd.print(horaAlarme);
    }
    lcd.setCursor(9, 2);
    lcd.print(":");
    if (minutoAlarme < 10) { lcd.setCursor(10, 2); lcd.print("0"); lcd.setCursor(11, 2); lcd.print(minutoAlarme); } else { lcd.setCursor(10, 2); lcd.print(minutoAlarme); } estadoBotaoAnterior = digitalRead(pinoBotaoAnterior); estadoBotaoAvancar = digitalRead(pinoBotaoAvancar); if (estadoBotaoAvancar == 0) { delay(debouce); minutoAlarme++; if (minutoAlarme > 59) {
        minutoAlarme = 0;
      }
    } else if (estadoBotaoAnterior == 0) {
      delay(debouce);
      minutoAlarme--;
      if (minutoAlarme < 0) {
        minutoAlarme = 59;
      }
    }
  } while (digitalRead(pinoBotaoConfirmacao) == 1);
  delay(debouce);
  lcd.clear();
}

Funcionamento

A breadboard montada acima conta com 4 botões. Da esquerda para a direita: botão de menu, utilizado para aceder ou sair ao menu das configurações; botão de confirmação, utilizado para entrar ou confirmar uma opção do menu; botão “anterior”, para diminuir valores na definição da hora do alarme; e botão “avançar”, para aumentar os mesmos valores.

Por definição, o despertador está desligado e a hora pré-definida é 12:30. Para utilizar o alarme, prima o botão de menu e, no menu “1 – Alarme”, pressionar o botão de confirmação. Pode ser confirmado o passo anterior pelo surgimento de um pequeno sino no LCD.

Seguidamente, prima o botão de menu novamente, pressione o botão “avançar” para ir ao menu “2 – Definir Alarme” e prima o botão de confirmação. Utilizando os botões “avançar” e “anterior”, defina a hora do alarme. Volte a pressionar o botão de confirmação para inserir os minutos do alarme. Uma vez terminado, pressione o botão de confirmação e o alarme encontra-se definido.

Para desativar o alarme, repita o primeiro passo. O desaparecimento do sino no LCD confirma a alteração.

Não se esqueçam de ver o nosso vídeo sobre este artigo no nosso canal do YouTube:


Para mais projetos, percorram o nosso blog, onde podem encontrar vários artigos interessantes relacionados com eletrónica, robótica e muito mais! Visitem também o nosso site, onde encontram tudo para eletrónica e robótica!