Reloj con Alarma usando displays diferentes

Hola a todos :raising_hand_man:

Tengo en mente hacer un proyecto Reloj y Alarma

A la mano tengo un Arduino NANO, un modulo RTC 3231, un Buzzer pasivo, un LCD 16x2 con modulo I2C, un modulo LED Display de 7 segmentos a 4 dígitos con MAX7219, un encoder Ky-040 y algunos push button.

Lo que me gustaría lograr con estos componentes que tengo a la mano es que en el led display solo se muestre la hora y la temperatura y en el display LCD solo se muestre la alarma.
Para simplificar me gustaría que con el encoder poder configurar los parámetros de hora/minutos y alarma. Y con un push button desactivar la alarma.

He buscado por internet algún proyecto parecido pero no he encontrado algo asi.
Solo he visto proyectos con un solo usa display ya sea de 7 segmentos o solo LCD pero hasta ahora no he encontrado alguno que implemente estos dos tipos de displays.

¿Alguien sabe de algún proyecto así o que haya visto alguno por internet que me lo pueda compartir?

Saludos.

No he visto ninguno pero no es algo difícil de implementar.

Busca uno o dos ejemplos para tu LCD en la IDE así aprendes a manejarlo.

Busca un ejemplo de reloj con 7 segmentos, y agrega lo que aprendiste sobre el LCD para mostrar la hora de alarma.

Es así de sencillo y así de complicado. :wink:

Saludos

La lista de materiales y criterios, ¿esta cerrada?, ó , ¿se admite alguna modificación ?

Si he estado viendo algunos ejemplos y haciendo pruebas.
Si tienes algún otro tip que me puedas dar te lo agradeceré.

en cuanto a la lista de materiales escribí esos ya que son los que tengo disponibles pero puedo conseguir otros y los criterios igual los puedo modificar.

Acepto sugerencias.

En cuanto al RTC 3231 indiscutible yo tambien lo uso, el buzzer yo uso uno activo controlado por un transistor, (2n2222), pero si es inactivo con la funciom tone no tendrias problemas.
En cuanto a los displays , sinceramente , para un prototipo de aprendizaje valen, pero si vas a utilizarlo como un reloj fucional te vas a dejar los ojos mirando el LCD , (muy pequeño para ver de lejos),
Una posile solución seria usar esto

Y te podria quedar mas o menos asi:


A eso le añades una LDR para cotrolar el brillo , unos cuantos pulsadores , (te ahorarias el segundo display 7 sementos) , pulsado uno de ellos te mostraria la alarma en la msma matriz de led. Y un modulo pir para que solo se encieenda cuando detecte presencia animal,( ahorro de energia ), creo que tendrias un buen despertador para la mesita de noche.

Suena interesante la idea que me compartes y te lo agradezco.
La verdad yo había pensado en algo mas compacto y que en el led Display solo se muestre la hora (claro en un led display mas o menos grande para que se vea la hora a distancia) Y que en el LCD solo muestre la Hora de la Alarma programada y la temperatura.
Mas o menos como la imagen que comparto.
El led display que tengo en lo suficiente mente grande para ver la hora a una distancia considerable (a mi gusto personal).
Igual sigo aceptado sugerencias y orientación.

En tren de sugerir, mostraría en el LCD

01/01/22  22°C
AL  12:00  ON

Sobre el código te reitero, busca ejemplos que hay muchos con ambos tipos de display, estúdialos para entenderlos, aprende a manejar el encoder y te va a resultar más fácil fusionar todo en uno.

Saludos

Hola amigos :raising_hand_man:

Ya después de varios días de estudiar códigos y hacer pruebas, que por cierto ya me estaba saturando :confounded: de tanta información jeje ya pude lograr mi objetivo :grinning_face_with_smiling_eyes: de usar dos display diferentes

La idea original la base en este proyecto y les comparto en enlace para que le echen un vistazo.

Me pareció genial ese proyecto porque se me hizo simple y que incluso lleva un sensor de movimiento que al sacudir el reloj se desactiva la alarma.

Tome como base ese código y lo estudié a fondo y le hice algunos cambios y agregue código para que me mostrara la hora en el LED Display.
Además puse por separado la alarma usando un Attiny85 al que conecte el buzzer y un neopixel WS2812 que suena y activa cada hora por un segundo y que aparte para que suene la alarma a la hora que se programe.

El código original no mostraba la temperatura y pues agregue algunas líneas para mostrarla y entre otras cosas que la hora me la muestre en formato de 12horas en el led display.

Agregue un sensor LDR para que se ajuste automaticamente el brillo del LED Display segun la luz del dia y en plena oscuridad no moleste.

Pienso agregar un boton mas para apagar o encender la luz del LCD y asi no moleste si despierto a media noche.

En lugar de usar push botton pienso usar 4 sensores capacitivos para los ajustes, aunque mi idea original era usar un encoder pero por el momento asi lo dejare.

Aquí les comparto una foto de la ultima prueba que hice con ambos displays funcionando.

Además les comparto el código, ya es funcional con algunas ligeras fallas, pero estoy trabajando en eso.

Le seguiré haciendo algunos cambios y mejoras.
Por ejemplo quiero que la hora de la alarma me la muestre en formato de 12horas y agregar que aparezca AM o PM junto a la alarma ¿alguien que me pueda ayudar o orientar con esto?

Aquí el código del Reloj

/*Digital Clock, Alarm with Thermometer Function
 */

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16,2);
#include <EEPROM.h>

#include <DS3231.h>
DS3231  rtc(SDA, SCL);

RTC_DS1307 RTC; //DS1307 i2c
//  PINES PARA I2C  //
//A4 SDA
//A5 SCL

// DISPLAY 7 SEGMENTS //
#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);
// ARDUINO   MAX7219
// pin12   = DataIn
// pin11   = CLK
// pin10   = LOAD
unsigned long delaytime=250;
// DISPLAY 7 SEGMENTS //


char daysOfTheWeek[7][12] = {"DOM","LUN", "MART", "MIER", "JUEV", "VIER", "SAB"};

const int btSet = 2;         //Boton SET ADJUST
const int btAdj = 3;         // +
const int btAlarm = 4;       // - & Alarm ON/OFF
const int shakeSensor = A3;  // Sensor de Movimiento Alarm OFF

//  ALARMA  //
unsigned long currentTime=0;
unsigned long previousTime=0;
//interval1 Pulso para Desactivar (DESACTIVADO)
//interval2 Pulso para Activar (ACTIVO)
unsigned long interval,interval1=1000,interval2=1;
bool ledState=HIGH;

// TONO CADA HORA  //
int PULSE_ALARMA = 8;

// PULSO POR SEGUNDO  //
int PULSE_SECOND = 6; //LED AZUL

//Variables
int DD,MM,YY,H,M,S,set_state, adjust_state, alarm_state,AH,AM, shake_state;
int shakeTimes=0;
int i =0;
int btnCount = 0;
String sDD; //DIA
String sMM; //MES
String sYY; //AÑO
String sH;  //HORA
String sM;  //MINUTOS
String sS;  //SEGUNDOS
String aH="12"; //HORA ALARMA
String aM="00"; //MUNUTOS ALARMA
String alarm = "OFF";

//Boolean flags
boolean setupScreen = false;
boolean alarmON=false;
boolean turnItOn = false;

int setminstemp;
int setsecs = 0;


void setup() {
  
  // DISPLAY 7 SEGMENTS
  lc.shutdown(0,false);
  lc.setIntensity(0,8); // brightness value 0 min ~ 15 max
  lc.clearDisplay(0);
  // DISPLAY 7 SEGMENTS
  
  pinMode(PULSE_SECOND, OUTPUT);
  
  digitalWrite(7, HIGH);
  pinMode(PULSE_ALARMA, OUTPUT);  //Activa BUZZER una vez cada hora
  digitalWrite(PULSE_ALARMA,LOW); //PIN D8
  delay(1);
  digitalWrite(PULSE_ALARMA,HIGH); //PIN D8
  
  //Init RTC and LCD library items
  RTC.begin();
  rtc.begin();
  lcd.init();
  lcd.backlight();
  lcd.begin(16,2);
  
  //Set outputs/inputs
  pinMode(btSet,INPUT_PULLUP);
  pinMode(btAdj,INPUT_PULLUP);
  pinMode(btAlarm, INPUT_PULLUP);
  pinMode(7, OUTPUT); //Pin D7 Pulso para activar Alarma
  
  //Check if RTC has a valid time/date, if not set it to 00:00:00 01/01/2018.
  //This will run only at first time or if the coin battery is low.
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    
    // Comment out below lines once you set the date & time.
    // Following line sets the RTC to the date & time this sketch was compiled
    //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    
    // This line sets the RTC with an explicit date & time, for example to set
    // January 1, 2018 at 00:00am you would call:
    RTC.adjust(DateTime(2018, 01, 01, 00, 00, 0));
     
  }
  delay(100);
  //Read alarm time from EEPROM memmory
  AH=EEPROM.read(0);
  AM=EEPROM.read(1);
  //Check if the numbers that you read are valid. (Hours:0-23 and Minutes: 0-59)
  if (AH>23){
    AH=0;
  }
  if (AM>59){
    AM=0;
  }
}

void loop() {

  //Codigo para sensor LDR
   adc_value = analogRead(A1); //Pin para sensor LDR conectado a PIN A1
   brightness = adc_value/65; // Divide by 65 to get Maximum Brightness 15.
   lc.setIntensity(0,brightness);
  //Codigo para sensor LDR

  readBtns();       //Read buttons 
  getTimeDate();    //Read time and date from RTC
  if (!setupScreen){
    lcdPrint();     //Normanlly print the current time/date/alarm to the LCD
    if (alarmON){
     callAlarm();   // and check the alarm if set on
    }
  }
  else{
    timeSetup();    //If button set is pressed then call the time setup function
  } 
}

/*************** Functions ****************/
//Read buttons state
void readBtns(){
  set_state = digitalRead(btSet);
  adjust_state = digitalRead(btAdj);
  alarm_state = digitalRead(btAlarm);
  if(!setupScreen){
    if (alarm_state==LOW){
      if (alarmON){
        alarm="OFF";
        alarmON=false; //default false
      }
      else{
        alarm="ON ";
        alarmON=true;
      }
      delay(500);
    }
  }
  if (set_state==LOW){
    if(btnCount<7){
      btnCount++;
      setupScreen = true;
        if(btnCount==1){
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("------SET------");
          lcd.setCursor(0,1);
          lcd.print("-TIME and DATE-");
          delay(2000);
          lcd.clear();
        }
    } 
    else{
      lcd.clear();
      RTC.adjust(DateTime(YY, MM, DD, H, M, 0)); //Save time and date to RTC IC
      EEPROM.write(0, AH);  //Save the alarm hours to EEPROM 0
      EEPROM.write(1, AM);  //Save the alarm minuted to EEPROM 1
      lcd.print("Saving....");
      delay(2000);
      lcd.clear();
      setupScreen = false;
      btnCount=0;
    }
    delay(500);
  }
}

//Read time and date from rtc ic
void getTimeDate(){
  if (!setupScreen){
  DateTime now = RTC.now();
  DD = now.day();
  MM = now.month();
  YY = now.year();
  H = now.hour();
  M = now.minute();
  S = now.second();

  //Muestra la Hora en Formato de 12Horas en LED Dysplay
  int H = now.hour() %12;
  H = H ? H : 12;
  //Muestra la Hora en Formato de 12Horas en LED Dysplay

  //Muestra Hora en LED Display
  int zo = int(H/10); // determin cifra zecilor
  int uo = H - 10*zo; // determin cifra unitatilor
  if (zo >= 1) lc.setDigit(0,0,zo, false);

  //Muestra Minutos en LED Display
  int zm = int(M/10); // determin cifra zecilor
  int um = M - 10*zm; // determin cifra unitatilor
  lc.setDigit(0,2,zm, false); //
  lc.setDigit(0,3,um, false); //

  //Muestra Segundos en LED Display
  //int zm = int(S/10); // determin cifra zecilor
  //int um = S - 10*zm; // determin cifra unitatilor
  //lc.setDigit(0,4,zm, false); //
  //lc.setDigit(0,5,um, false); //
  
  //Configuración de L1 y L2 como segundero
  lc.setDigit(0,1,uo, false);
  lc.setRow(0,4,B1000000);
  delay(80);
  lc.setRow(0,4,B0000000);
  delay(80);
  //Configuración de L1 y L2 como segundero


  if(now.second() == 00 && now.second()== 00){
  //int second0 = now.second();
  //if(second0 >=00){
  digitalWrite(PULSE_SECOND, LOW);
  delay(30);
  digitalWrite(PULSE_SECOND, HIGH);
  delay(30);
  }else{
  digitalWrite(PULSE_SECOND, HIGH);
  delay(30);   
  }

  //ACTIVAR BUZZER 1 VEZ POR HORA
  if (now.minute() == 00 && now.second() == 00){
  digitalWrite(PULSE_ALARMA, HIGH);
  delay(10);
  digitalWrite(PULSE_ALARMA, LOW);
  delay(5);
  }else{
  digitalWrite(PULSE_ALARMA, HIGH);
  //ACTIVAR BUZZER 1 VEZ POR HORA
  }
  }
  
  //Make some fixes...
  if (DD<10){ sDD = '0' + String(DD); } else { sDD = DD; }
  if (MM<10){ sMM = '0' + String(MM); } else { sMM = MM; }
  sYY=YY-2000;
  if (H<10){ sH = '0' + String(H); } else { sH = H; }
  if (M<10){ sM = '0' + String(M); } else { sM = M; }
  if (S<10){ sS = '0' + String(S); } else { sS = S; }
  if (AH<10){ aH = '0' + String(AH); } else { aH = AH; }
  if (AM<10){ aM = '0' + String(AM); }  else { aM = AM; }

}

//Print values to the display
void lcdPrint(){

  String line1 = ""+aH+":"+aM; //Muestra Hora y Minutos de Alarma en LCD
  String line2 = alarm; //Muestra la Hora de Alarma en LCD
  String line3 = "ALARM"; //Muestra Palabra ALARM en LCD
  String line4 = "TEMP"; //Muestra Palabra TEMP en LCD
  //String line5 = ""+sS; //Muestra segundos en LCD
  //String line6 = sDD+"/"+sMM+"/"+sYY +""; //Muestra Fecha en LCD
  
  lcd.setCursor(2,0); //Hora de Alarma en LCD
  lcd.print(line1);

  lcd.setCursor(6,1); //ON/OFF (Alarm) en LCD 
  lcd.print(line2);

  lcd.setCursor(0,1); //Alarm en LCD
  lcd.print(line3);

  lcd.setCursor(12,0); //TEMP en LCD
  lcd.print(line4);

  //lcd.setCursor(9,0); //Segundos en LCD
  //lcd.print(line5);

  //lcd.setCursor(0,0); //Fecha en LCD
  //lcd.print(line6);
  
  //TEMPERATURE
  lcd.setCursor(12,1);
  //lcd.print(rtc.getTemp()); //Muestra 22.45 con decimales
  lcd.print(rtc.getTemp(),0); //Muestra 22 sin decimales
  lcd.setCursor(14,1);
  lcd.print(char(223)); //Simbolo de °
  lcd.setCursor(15,1);
  lcd.print('C');
  //TEMPERATURE
}

//Setup screen
void timeSetup(){
  int up_state = adjust_state;
  int down_state = alarm_state;
  if(btnCount<=5){
    if (btnCount==1){         //Set Hour
      lcd.setCursor(4,0);
      lcd.print(">"); 
      if (up_state == LOW){   //Up button +
        if (H<23){
          H++;
        }
        else {
          H=0;
        }
        delay(350);
      }
      if (down_state == LOW){ //Down button -
        if (H>0){
          H--;
        }
        else {
          H=23;
        }
        delay(350);
      }
    }
    else if (btnCount==2){      //Set  Minutes
      lcd.setCursor(4,0);
      lcd.print(" ");
      lcd.setCursor(9,0);
      lcd.print(">");
      if (up_state == LOW){
        if (M<59){
          M++;
        }
        else {
          M=0;
        }
        delay(350);
      }
      if (down_state == LOW){
        if (M>0){
          M--;
        }
        else {
          M=59;
        }
        delay(350);
      }
    }
    else if (btnCount==3){      //Set Day
      lcd.setCursor(9,0);
      lcd.print("  ");
      lcd.setCursor(1,1);
      lcd.print(">");
      if (up_state == LOW){
        if (DD<31){
          DD++;
        }
        else {
          DD=1;
        }
        delay(200);
      }
      if (down_state == LOW){
        if (DD>1){
          DD--;
        }
        else {
          DD=31;
        }
        delay(200);
      }
    }
    else if (btnCount==4){      //Set Month
      lcd.setCursor(0,1);
      lcd.print("  ");
      lcd.setCursor(6,1);
      lcd.print(">");
      if (up_state == LOW){
        if (MM<12){
          MM++;
        }
        else {
          MM=1;
        }
        delay(200);
      }
      if (down_state == LOW){
        if (MM>1){
          MM--;
        }
        else {
          MM=12;
        }
        delay(350);
      }
    }
    else if (btnCount==5){      //Set Year
      lcd.setCursor(5,1);
      lcd.print("  ");
      lcd.setCursor(11,1);
      lcd.print(">");
      if (up_state == LOW){
        if (YY<2025){
          YY++;
        }
        else {
          YY=2000;
        }
        delay(200);
      }
      if (down_state == LOW){
        if (YY>2021){
          YY--;
        }
        else {
          YY=2025;
        }
        delay(200);
      }
    }   
    lcd.setCursor(5,0);
    lcd.print(sH);
    lcd.setCursor(8,0);
    lcd.print(":");
    lcd.setCursor(10,0);
    lcd.print(sM);
    lcd.setCursor(2,1);
    lcd.print(sDD);
    lcd.setCursor(5,1);
    lcd.print("/");
    lcd.setCursor(7,1);
    lcd.print(sMM);
    lcd.setCursor(10,1);
    lcd.print("/");
    lcd.setCursor(12,1);
    lcd.print(sYY);
  }
  else{
    setAlarmTime();
  }
}

//Set alarm time
void setAlarmTime(){
  int up_state = adjust_state;
  int down_state = alarm_state;
  String line2;
  lcd.setCursor(0,0);
  lcd.print("SET  ALARM TIME");
  if (btnCount==6){             //Set alarm Hour
    if (up_state == LOW){
      if (AH<23){
        AH++;
      }
      else {
        AH=0;
      }
      delay(200);
    }
    if (down_state == LOW){
      if (AH>0){
        AH--;
      }
      else {
        AH=23;
      }
      delay(200);
    }
    line2 = "    >"+aH+" : "+aM+"    ";
  }
  else if (btnCount==7){        //Set alarm Minutes
    if (up_state == LOW){
      if (AM<59){
        AM++;
      }
      else {
        AM=0;
      }
      delay(200);
    }
    if (down_state == LOW){
      if (AM>0){
        AM--;
      }
      else {
        AM=59;
      }
      delay(200);
    }
    line2 = "     "+aH+" :>"+aM+"    ";    
  }
  lcd.setCursor(0,1);
  lcd.print(line2);
}

void callAlarm(){
  if (aM==sM && aH==sH && S>=0 && S<=2){
    turnItOn = true;
  }
  if(alarm_state==LOW || shakeTimes>=6 || (M==(AM+5))){
    turnItOn = false;
    alarmON=true;
    delay(500);
  } 
  if(analogRead(shakeSensor)>200){
    shakeTimes++;
    Serial.print(shakeTimes);
    delay(50);
  }
  if (turnItOn){
  currentTime=millis();
  if(ledState){
    interval=interval2; //Pulso para Activar (ACTIVO)
  }else{
    interval=interval1; //Pulso para Desactivar (DESACTIVADO)
  }
  if((currentTime-previousTime)>interval){
    previousTime=currentTime;
    ledState=!ledState;
    digitalWrite(7,!ledState);
      i++; 
      if(i>3){i=0; };
    }
  }
  else{
    digitalWrite(7, HIGH);
    shakeTimes=0;
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.