Projeto 53 - Usando alarmes com RTC DS3231 (pino SQW) - Arduino

Básico - Projeto 53

Usando alarmes com RTC DS3231 (pino SQW)

Objetivo

Neste projeto mostraremos como utilizar o pino SQW do módulo RTC DS3231 para gerar até dois alarmes. Também vamos criar um relógio digital com data e monitoramento da temperatura ambiente. O relógio exibe no display a hora, minutos e segundos e a cada 3 segundos exibe a data e a temperatura sucessivamente. Ao setarmos a data, hora, minutos e/ou segundos do disparo dos alarmes, o relógio irá atuar como um temporizador de disparos para acionarmos 2 componentes eletrônicos que no nosso projeto utilizamos 2 leds.

Observações:

1) Utilizamos o módulo RTC DS3231 para funcionar como relógio, alarme e controle de temperatura ambiente.

2) Este projeto foi desenvolvido para um display LCD com controlador HD44780 em conjunto com o módulo serial I2C (opcional), que poderá ser separado ou soldado diretamente no display.

3) Se você não possui um módulo I2C para display LCD, poderá adequar o projeto para o display LCD sem o adaptador. Veja como montar o display no projeto Projeto 38 - Controlando um display LCD (instalação e comandos básicos).

4) Este projeto utilizará uma biblioteca específica para o módulo RTC DS3231 e portanto não funcionará com outros módulos RTC. A biblioteca utilizada possui comandos para alarme através do pino SQW.

Módulo RTC DS3231 de alta precisão: O Real Time Clock (RTC) DS3231 é um relógio de tempo real de alta precisão e baixo consumo de energia. Em sua placa vem embutido um sensor de temperatura, um gravador de dados EPROM e um cristal oscilador para melhorar sua exatidão.

Observações sobre o módulo RTC DS3231:

1) Utiliza o protocolo de comunicação I2C. O I2C é um protocolo de baixa velocidade de comunicação criado pela Philips para comunicação entre placa mãe e dispositivos, Sistemas Embarcados e circuitos de celulares.

2) É capaz de fornecer informações como segundo, minutos, dia, data, mês e ano (de 2000 a 2099). Correções como meses com menos de 31 dias e anos bissextos são corrigidos automaticamente e pode operar tanto no formato 12 horas como 24 horas.

3) Em caso de falha de energia o DS3231 automaticamente aciona a bateria para evitar perda de dados.

4) Possui um sensor de temperatura com precisão de 3ºC.

Aplicação

Para fins didáticos e projetos para controle de tempo e temperatura com exibição em display de cristal líquido.

Componentes necessários

Referência

Componente

Quantidade

Imagem

Observação

Protoboard Protoboard 830 pontos 1 Resultado de imagem para protoboard 830v

No mínimo utilizar protoboard com 830 pontos

Jumpers Kit cabos ligação macho / macho 1    
Display LCD Display LCD 16 X 2 com pinos soldados 1

LCD que utilize o controlador HD44780 (veja na descrição ou datasheet do componente)

O display poderá ser de qualquer cor (fundo verde, azul ou vermelho)

Módulo I2C para display LCD

Módulo I2C com CI PCF8574

(opcional)

1 Módulo I2C display LCD Arduino

O módulo I2C poderá vir separado ou já soldado no display LCD

(datasheet)

Módulo RTC Módulo RTC DS3231 1

Módulo de alta precisão com comunicação I2C.

Tensão de operação: 3,3V - 5,0V

Chip de memória: AT24C32 de 32K bytes

Computa segundos, minutos, horas, dias da semana, dias do mês, meses e anos (de 2000 a 2099)

Consumo menor que 500nA no modo bateria

(datasheet)

Led 5mm led 5mm 2  

1 LED vermelho e 1 LED azul

 

Você poderá utilizar LEDs de qualquer outra cor ou LEDs de alto brilho de 3 ou 5mm nas cores que desejar.

 
Resistor Resistor 2  1 Resistor de 100Ω (led azul) / 1 Resistor de 150Ω (led vermelho)
 
Se precisar usar outros valores, calcule o resistor apropriado para o led utilizado.
Arduino UNO R3 Arduino UNO 1

Você poderá utilizar uma placa Arduino UNO original ou similar

Montagem do Circuito

Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.


Atenção

1. Utilizamos neste projeto o módulo RTC DS3231 que permite um controle completo e preciso de tempo. Para conectar o módulo é necessário conhecer um pouco a estrutura do componente:

1.1. Observe na imagem acima que em uma extremidade do módulo existem 6 pinos de conexão, sendo:

1.1.1. O par de pinos 1 e 2 se refere à alimentação 3.3V ou 5V (Vcc e GND).

1.1.2. O par de pinos 3 e 4 deve ser utilizado para a comunicação I2C (SDA e SCL) que deverão estar conectados nos pinos analógicos A4 (SDA) e A5 (SCL) do Arduino Uno ou nos pinos A20 (SDA) e A21 (SCL) do Arduino Mega 2560.

1.1.3. O pino 5 (SQW) é usado para disparo de alarmes. O pino 5 deverá estar conectado no pino digital 2 do Arduino, devendo ser definido na programação como Pull-up interno.

1.1.4. O pino 6 não é utilizado neste projeto. O pino 6 (32K) deve ser usado para saída de onda do cristal e é raramente utilizado.

2. Neste projeto poderão ser utilizados display LCD 16x2 ou display LCD 20X4 que possuem controlador HD44780. Estes displays se adaptam aos mais diversos projetos com vários modelos de placas e microcontroladores. Podem ter luz de fundo (backlight) verde, azul ou vermelha e possuem 16 pinos para a conexão. com No nosso exemplo vamos utilizar o display LCD 16x2 que possui 16 colunas por 2 linhas. Atenção: Utilize um display LCD com os pinos soldados.

3. Para a montagem do display com adaptador, entenda a estrutura do módulo I2C para display LCD 16x2 e display LCD 20X4:

Módulo I2C - Detalhes

3.1. Na lateral do adaptador encontramos 4 pinos, sendo: 2 pinos para alimentação (Vcc e GND) e 2 pinos para conexão com a interface I2C (SDA e SCL) que deverão estar conectados nos pinos analógicos A4 (SDA) e A5 (SCL) do Arduino Uno ou nos pinos A20 (SDA) e A21 (SCL) do Arduino Mega 2560. Veja a tabela abaixo com onde temos as principais placas Arduino e suas conexões com o I2C.

3.2. Para controlar o contraste do display, utilize o potenciômetro de ajuste de contraste. O jumper lateral, quando utilizado, permite que a luz do fundo (backlight) seja controlada pelo programa ou permaneça apagada.

 

3.3. A seleção de endereço do adaptador I2C para display LCD, na maioria dos módulos fornecidos no mercado já vêm configurados com o com o endereço 0x27.

Se você não sabe qual endereço que o seu módulo I2C e/ou módulo RTC DS3231 está configurado, baixe o seguinte "sketch":

DOWNLOAD - I2C_scanner.ino

3.3.1 Após instalar e rodar o sketch acima, abra o monitor serial que mostrará qual é o endereço que o seu módulo I2C e o módulo RTC DS3231 está configurado:

 

3.3.1.1 Nos casos em que módulo I2C estiver configurado com uma faixa de endereços diferente do endereço 0X27 altere a alinha de programação -> LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); com o endereço correto.

3.5. Para saber mais sobro a montagem e utilização de display LCD com módulo I2C leia: Projeto 48 - Como controlar um display LCD com o módulo I2C.

4. Para a montagem dos leds, lembre-se que o LED tem polaridade: O terminal maior tem polaridade positiva e o lado do chanfro tem polaridade negativa.

5. Determinamos o valor do resistor através da tabela prática: Tabela prática de utilização de leds 3mm e 5mm. Entretanto, o mais correto é sempre verificar o datasheet do fabricante do LED para você ter os exatos valores de tensão e corrente do mesmo - leia Como calcular o resistor adequado para o led e Leds ligados em série e em paralelo.

5.1. Valor do resistor utilizado no nosso projeto para o LED Azul = 100 Ω e para o Led vermelho 150 Ω. Você poderá utilizar valores iguais ou superiores de 200 Ω para qualquer cor de led.

6. Veja abaixo como realizamos a montagem do nosso projeto utilizando um protoboard:

Incluindo biblioteca LiquidCrystal_I2C no IDE do Arduino

Para que o módulo I2C funcione corretamente é necessário adicionarmos a biblioteca LiquidCrystal_I2C no IDE do Arduino. Uma das grandes vantagens das placas Arduino é a diversidade de bibliotecas disponíveis que podem ser utilizadas em seus programas. Estas bibliotecas podem ser criadas para a linguagem "C" ou especificamente para o Arduino, reduzindo drasticamente o tempo gasto com programação.

Download dos arquivos da biblioteca LiquidCrystal_I2C

DOWNLOAD - NewliquidCrystal_1.3.4.zip

Para saber detalhes desta biblioteca clique aqui.

Instalando a biblioteca pelo IDE do Arduino

Após fazer o download do arquivo NewliquidCrystal_1.3.4.zip com todos os arquivos da biblioteca compactados no formato zip, abra o IDE do Arduino e siga o tutorial:Como incluir uma biblioteca no IDE do Arduino.

Incluindo biblioteca DS3231 no IDE do Arduino

Para gerarmos os disparos do alarme com o pino SQW do módulo DS3231 é necessário utilizarmos uma biblioteca que possui estes comandos. Portanto, se você já realizou experimentos anteriores o módulo DS3231 deverá excluir a biblioteca atual instalada no IDE do Arduino no seu computador. Para isso, exclua a pasta DS323, se existir, localizada em C:\Users\NOME DO USUÁRIO\Documents\Arduino\libraries\DS3231 (Substitua NOME DO USUÁRIO pelo "user" do seu computador).

Após excluir a pasta DS3231 é necessário adicionar a nova biblioteca DS3231.h responsável por obter os valores do tempo, dia e temperatura ambiente, além de possibilitar o ajuste e disparo de 2 alarmes.

Download dos arquivos da biblioteca DS3231-master

DOWNLOAD - Arduino-DS3231-master

Para saber detalhes desta biblioteca clique aqui.

Instalando a biblioteca pelo IDE do Arduino

Após fazer o download do arquivo Arduino-DS3231-master.zip com todos os arquivos da biblioteca compactados no formato zip, abra o IDE do Arduino e siga o tutorial: Como incluir uma biblioteca no IDE do Arduino.

Para conhecer outras bibliotecas para módulos veja a Coletânea de bibliotecas para módulos.

Sketch do projeto

1. Faça o dowload e abra o arquivo projeto53.ino no IDE do Arduino:  DOWNLOAD - projeto53.ino

Obs. 1: Nos casos em que módulo I2C estiver configurado com um endereço diferente do endereço 0X27, altere a alinha de programação -> LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); com o endereço correto.

Obs. 3: Se estiver utilizando um display de LCD 20 X 4, altere o comando da linha 26 para lcd.begin (20,4);

Obs. 4: Utilizamos a biblioteca DS3231 para o controle de tempo, temperatura e disparos de alarme.

Obs. 5: Ao utilizar o RTC pela primeira vez é necessário ajustar a hora e data com os valores atuais: retire as barras duplas da linhas 44  para executar a função que vai ajustar a data e hora atual. do seu módulo.

Obs. 6: Depois de ajustar a hora e data no "sketch" rode o programa para alterar os dados no módulo RTC. Desligue o Arduino da fonte e altere novamente o "sketch", inserindo as duas barras nestas linhas.

Obs. 7: Se você já utilizou o seu módulo RTC em qualquer outro projeto e já ajustou a hora e data, não precisará mais fazer isto até substituir a bateria que deve durar em torno de 5 anos.

Ou se preferir, copie e cole o código abaixo no IDE do Arduino:

/*******************************************************************************
*
*    Projeto 53: RTC DS3231 - Alarme com pino SQW
*                     http://squids.com.br/arduino
*    
*    Referência:
*    Web: http://www.jarzebski.pl
*    (c) 2014 by Korneliusz Jarzebski                 
*
*******************************************************************************/
#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

DS3231 clock;
RTCDateTime dt;

uint32_t timer = 0;
int control = 0;

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);

void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);

  pinMode(2, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  
  // Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();

  // Disarm alarms and clear alarms for this example, because alarms is battery backed.
  // Under normal conditions, the settings should be reset after power and restart microcontroller.
  clock.armAlarm1(false);
  clock.armAlarm2(false);
  clock.clearAlarm1();
  clock.clearAlarm2();
 
  // Manual (Year, Month, Day, Hour, Minute, Second)
  //clock.setDateTime(2019, 3, 4, 15, 13, 54);

  // alarmes (1)
  
  // Set Alarm - Every second.
  // DS3231_EVERY_SECOND is available only on Alarm1.
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(0, 0, 0, 0, DS3231_EVERY_SECOND);
  
  // Set Alarm1 - Every 20s in each minute
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(0, 0, 0, 20, DS3231_MATCH_S);

  // Set Alarm1 - Every 01m:25s in each hour
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(0, 0, 1, 25, DS3231_MATCH_M_S);

  // Set Alarm1 - Every 01h:10m:30s in each day
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(0, 1, 10, 30, DS3231_MATCH_H_M_S);

  // Set Alarm1 - 07h:00m:00s in 25th day in month
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(25, 7, 0, 0, DS3231_MATCH_DT_H_M_S);

  // Set Alarm1 - 10h:45m:30s in every Friday (1 - Mon, 7 - Sun)
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm1(5, 10, 40, 30, DS3231_MATCH_DY_H_M_S);

  // alarmes (2)

  // Set Alarm - Every full minute.
  // DS3231_EVERY_MINUTE is available only on Alarm2.
  // setAlarm2(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  // clock.setAlarm2(0, 0, 0, 0, DS3231_EVERY_MINUTE);

  // Set Alarm2 - Every 01m in each hour
  // setAlarm2(Date or Day, Hour, Minute, Mode, Armed = true)
  // clock.setAlarm2(0, 0, 37, DS3231_MATCH_M);

  // Set Alarm - Hora e minutos coincidem (Ex: 16:52min).
  // DS3231_MATCH_H_M is available only on Alarm2.
  // setAlarm2(Date or Day, Hour, Minute, Mode, Armed = true)
  // clock.setAlarm2(0, 18, 49, DS3231_MATCH_H_M);

   // Set Alarm - Data, horas e minutos coincidem.
  // DS3231_MATCH_DT_H_M is available only on Alarm2.
  // setAlarm2(Date or Day, Hour, Minute, , Mode, Armed = true)
   //clock.setAlarm2(0, 0, 0, 0, DS3231_MATCH_DT_H_M);

   // Set Alarm -10h:45m in every Friday (1 - Mon, 7 - Sun)
  // DS3231_EVERY_MINUTE is available only on Alarm2.
  // setAlarm2(Date or Day, Hour, Minute, Mode, Armed = true)
   //clock.setAlarm2(5, 10, 45, DS3231_EVERY_MINUTE);
  
  // Check alarm settings
  checkAlarms();
}

void loop()
{
  dt = clock.getDateTime();
  float t = clock.readTemperature();
  clock.forceConversion();

  Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt));
  
  // inicia a exibição no display LCD
       lcd.setCursor(4,0);
       if (dt.hour < 10) {
          lcd.print("0");
       }
       lcd.print(dt.hour);
       lcd.print(":");
       if (dt.minute < 10) {
          lcd.print("0");
       }
       lcd.print(dt.minute);
       lcd.print(":");
       if (dt.second < 10) {
          lcd.print("0");
       }
       lcd.print((dt.second));

 // Controle do display de LCD (2ª linha)
  switch(control)    {
          case 0: {
             lcd.setCursor(0,1);
             lcd.print("Data: ");
             lcd.print(dt.day);
             lcd.print("/");
             lcd.print(dt.month);
             lcd.print("/");
             lcd.print(dt.year); 
             lcd.print("                ");             
             temporizador(1);
             break;
          }
       case 1: {
             lcd.setCursor(0,1);             
             lcd.print("Temp: ");
             lcd.print(t);
             lcd.print(" C");
             lcd.print("            ");
             temporizador(2);
             break; 
       }
       case 2: {
            lcd.setCursor(0,1);     
            lcd.print(" Squids Arduino");
            lcd.print("                ");           
            temporizador(0);
            break; 
       }
  }
   
  // Call isAlarm1(false) if you want clear alarm1 flag manualy by clearAlarm1();
  if (clock.isAlarm1())
  {  
    Serial.print("ALARM 1 TRIGGERED! ");
    digitalWrite(7, HIGH);  
  }
 
  // Call isAlarm2(false) if you want clear alarm1 flag manualy by clearAlarm2();
  if (clock.isAlarm2())
  {
    Serial.print("ALARM 2 TRIGGERED! ");
    digitalWrite(5, HIGH);
  }
         
} // end void loop

void checkAlarms() {
  
  RTCAlarmTime a1;  
  RTCAlarmTime a2;

  if (clock.isArmed1())
  {
    a1 = clock.getAlarm1();

    Serial.print("Alarm1 será disparado ");
    switch (clock.getAlarmType1())
    {
      case DS3231_EVERY_SECOND:
        Serial.println("todo segundo");
        break;
      case DS3231_MATCH_S:
        Serial.print("quando os segundos coincidirem com: ");  
        Serial.println(clock.dateFormat("__ __:__:s", a1));      
        break;
      case DS3231_MATCH_M_S:
        Serial.print("quando os minutos e segundos coincidirem com: ");
        Serial.println(clock.dateFormat("__ __:i:s", a1));
        break;
      case DS3231_MATCH_H_M_S:
        Serial.print("quando horas, minutos e segundos coincidirem com: "); 
        Serial.print(clock.dateFormat("__ H:i:s", a1));      
        break;
      case DS3231_MATCH_DT_H_M_S:
        Serial.print("quando a data, horas, minotos e segundos coincidirem com: "); 
        Serial.println(clock.dateFormat("d H:i:s", a1));       
        break;
      case DS3231_MATCH_DY_H_M_S:
        Serial.print("quando o dia da semana, horas, minutos e segundos coincidirem com: ");
        Serial.println(clock.dateFormat("l H:i:s", a1));       
        break;
      default: 
        Serial.println("UNKNOWN RULE");
        break;
    }
  } else
  {
    Serial.println("Alarm1 is disarmed.");
  }

  if (clock.isArmed2())
  {
    a2 = clock.getAlarm2();

    Serial.print("Alarm2 será disparado ");
    switch (clock.getAlarmType2())
    {
      case DS3231_EVERY_MINUTE: 
        Serial.println("todo minuto");
        break;
      case DS3231_MATCH_M:
        Serial.print("Quando minutos coincidirem com: ");
        Serial.println(clock.dateFormat("__ __:i:s", a2));        
        break;
      case DS3231_MATCH_H_M:
        Serial.print("Quando as horas e minutos coincidirem com: ");
        Serial.println(clock.dateFormat("__ H:i:s", a2));        
        break;
      case DS3231_MATCH_DT_H_M:
        Serial.print("Quando a data, hora e minutos coincidirem com: "); 
        Serial.println(clock.dateFormat("d H:i:s", a2));       
        break;
      case DS3231_MATCH_DY_H_M:
        Serial.print("Quando o dia da semana, horas e minutos coincidirem com: ");
        Serial.print(clock.dateFormat("l H:i:s", a2));
        break;
      default: 
        Serial.println("UNKNOWN RULE"); 
        break;
    }
  } else
  {
    Serial.println("Alarm2 is disarmed.");
  }
}

// atualiza a cada 3 segundos
void temporizador(int x) {
  if (millis() - timer >=3000) {
    control = x;
    timer = millis(); // Atualiza a referência            
  }
} 

ATENÇÃO: Se o display acender e não mostrar os caracteres provavelmente é em função do contraste. Gire o eixo do potenciômetro de ajuste de contraste no sentido horário. Se mesmo assim o display não mostrar os caracteres, então corrija a montagem do circuito e/ou o código.

Vídeo

Como o projeto deve funcionar

1. Se você vai utilizar o módulo RTC pela primeira vez, altere os sketch do projeto para configurar a hora e data atual: Retire as barras duplas de comentário da linha 44 executar a função que vai ajustar a data e hora do seu módulo.

1.1. Após ajustar o programa, você não precisará mais realizar esta operação. Somente altere os dados novamente no caso de precisar substituir a bateria do módulo, que deve durar aproximadamente 5 anos.

2. Ao iniciar o programa, você irá visualizar na primeira linha do display a hora, minutos e segundos e na segunda linha a data e a temperatura a cada 3 segundos.

2. Se você realizou o ajuste para configurar a hora e data atuais, desligue o Arduino da fonte e altere novamente o sktech, inserindo as duas barras na linha 44.

3. Pronto, agora rode o programa para visualizar a hora, data e temperatura ambiente. Se acabar a energia elétrica ou se você desligar o Arduino, a hora e data estarão sempre atualizadas graças a bateria que vem acoplada ao módulo RTC.

4. Para setar os alarme, abra o editor IDE do Arduino e defina apenas um "alarm1" e/ou um "alarm2", retirando as barras duplas que antecedem as linhas de comando.

4.1. Altere os valores de Date, Hour, Minute e Second de acordo com o período que se deseja disparar o alarme.

4.1.1. Veja o exemplo abaixo onde setamos o alarme 1 para disparar a cada 20 segundos e o alarme 2 para disparar todos os dias às 16h:52min.

 

 ATENÇÃO: Para desativar os alarmes que foram definidos, basta adicionar novamente as barras no início das linhas de comandos.

5. Quando o alarme 1 for disparado o led vermelho se acenderá e quando o alarme 2 for disparado o led azul se acenderá.

6. Abrindo o monitor serial, você poderá acompanhar todos os disparos dos alarmas em tempo real, segundo a segundo.

Desafios

Com base neste projeto, resolva o seguinte desafio:  Desafio 39

O anúncio abaixo ajuda a manter o Squids Arduino funcionando

Comentários

×

Infomações do site / SEO








×

Adicionar Marcadores