DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628.

Que tal amigos, en esta oportunidad presentamos nuestro proyecto DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628. El objetivo de este proyecto es lograr la fabricación de un reloj 100% funcional, de bajo costo y con los mínimos componentes posibles.

Vemos por que y como llevamos a cabo este proyecto:

Problema de mi reloj alarma

Sucede que hace ya varios años compre un reloj radio alarma de la marca SONY para despertarme de mis pocas hora de sueño. Sin embargo este pequeño amigo resulto que cada cierto tiempo se adelantaba algunos minutos.

Y ya me había cansado de estar corrigiendo el tiempo además por que los pulsadores de control con el uso se ponen muy duros.

Otra cosa que no me gusta de este tipo de relojes es que traen muchos botones para configurar la hora y la alarma y cada cierto tiempo te olvidas de como se hace para ponerlo a hora.

Reloj Despertador radio Sony ICF-C218 máquina de ensueño AM FM | eBay

Entonces decidimos dar de baja a este compañero y reemplazarlo por uno de mejores prestaciones, que no consuma tanta batería, hecho por nosotros mismos y que además sea fácil de configurar, por lo menos para mi.

El plan es utilizar todas las cosas que tenemos a la mano en nuestro taller electrónico, que en realidad no es mas que un pequeño escritorio ; ) Manos a la obra entonces.

Lista de componentes para el DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628.

Esta es la lista de componentes para nuestro reloj.

  1. Un microcontrolador PIC16f628.
  2. Un cristal de 4Mhz.
  3. Condensador de 22pf (2 unidades)
  4. Display LCD de 16×2.
  5. Batería recargable de 3.7 Voltios.
  6. Un par de pulsadores.
  7. Un potenciómetro.
  8. Un led.
  9. Un speaker.
  10. Resistencias de 1kh (3).
  11. Soldadura, cautin, estaño y muchas de ganas de trabajar.

Circuito del proyecto.

Este es el circuito que diseñamos para nuestro proyecto simulado en proteus.

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Como ven el circuito es bastante sencillo, nos permite mostrar en el mismo display la hora y la hora de la alarma.

En la segunda fila se muestra la función de calendario.

El botón numero 1 selecciona los distintos parámetros del reloj, y el botón numero 2, sirve para setear los valores correctos del reloj la alarma y calendario.

El programa del Reloj Alarma y calendario con pic16f628 y LCD.

El programa que hemos diseñado se basa en el incremento de una variable entera llamada “segundos” por medio de una interrupción generada por el timer1 del pic.

Existen varias maneras de hacer que un PIC realice ciclos de 1 segundo y con eso poder llevar a cabo el resto de nuestra programación que en este caso no seria mas que cada ves que la variable segundos llegue a 60, se reinicie a 0 la variable segundos y se incremente en 1 la variable minutos. Lo mismo para minutos, horas, días, meses y años. Cada una con su respectiva lógica de conteo y reinicio de variable.

Las variables acumuladas se muestran en el display por medio de la función de LCD del programa de compilación CCS.

A continuación y luego de varias horas de optimización, prueba y error les muestro el código del programa que hace funcionar nuestro reloj. Este se puede adaptar a cualquier PIC con una frecuencia de 4MHz.

#include <lcd.c>
int32 Ticker; 
int Segundos=0;
int8 Year=0,Mes=1,ndia=1,dia=1,Hora=0,Minuto=0,alhora=0,alminuto=0;
#define BISIESTO(year) (year%4 == 0)
void buzzer(unsigned int duration) // duration in ms.
{   
unsigned int n;
n = (duration << 1) + (duration >> 1);
while (n) {
output_high(PIN_a3);
Delay_us(206);
output_low(PIN_a3);
Delay_us(206);
n--; }
}
void showdisplay ()
{ 
lcd_gotoxy(1, 1);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d:%d%d:%d%d - %d%d:%d%d ", hora/10,(hora%10),Minuto/10,(minuto%10),segundos/10,(segundos%10),alhora/10,(alhora%10),alminuto/10,(alminuto%10));
lcd_gotoxy(3, 2);                              // Go to column 1 row 2
switch(dia){
case 1: lcd_putc("Lun "); break;
case 2: lcd_putc("Mar "); break;
case 3: lcd_putc("Mie "); break;
case 4: lcd_putc("Jue "); break;
case 5: lcd_putc("Vie "); break;
case 6: lcd_putc("Sab "); break;
case 7: lcd_putc("Dom "); break;}
printf(lcd_putc,"%d%d/%d%d/%d%d", ndia/10,(ndia%10),mes/10,(mes%10),year/10,(year%10));;
} 
void showminuto ()
{ 
lcd_gotoxy(5, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Minutos:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", minuto/10,(minuto%10));
} 
void showhora ()
{ 
lcd_gotoxy(7, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Hora:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", hora/10,(hora%10));
} 
void showalminuto ()
{ 
lcd_gotoxy(2, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Alarma Minuto:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", alminuto/10,(alminuto%10));
} 
void showalhora ()
{ 
lcd_gotoxy(3, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Alarma Hora:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", alhora/10,(alhora%10));
} 
void showdia ()
{ 
lcd_gotoxy(7, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Dia:");
lcd_gotoxy(7, 2);                              // Go to column 1 row 2
switch(Dia){
case 1: lcd_putc("Lun "); break;
case 2: lcd_putc("Mar "); break;
case 3: lcd_putc("Mie "); break;
case 4: lcd_putc("Jue "); break;
case 5: lcd_putc("Vie "); break;
case 6: lcd_putc("Sab "); break;
case 7: lcd_putc("Dom "); break;}
} 
void showndia ()
{ 
lcd_gotoxy(4, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Numero dia:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", ndia/10,(ndia%10));
} 
void showmes ()
{ 
lcd_gotoxy(7, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Mes:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", mes/10,(mes%10));
} 
void showyear ()
{ 
lcd_gotoxy(7, 1);                              // Go to column 1 row 1
printf(lcd_putc,"Year:");
lcd_gotoxy(8, 2);                              // Go to column 1 row 1
printf(lcd_putc,"%d%d", year/10,(year%10));
} 
void alarm_check(){
if((alminuto == minuto) &&  (alhora == hora ) && (segundos==0) && (alminuto+alhora!=0))
while (segundos!=30) 
{
showdisplay(); 
output_high(PIN_B3);
delay_ms(200);
output_low(PIN_B3);
delay_ms(200);
buzzer(500);
delay_ms(100);
buzzer(500);
}
}
#int_TIMER1    
void TIMER1_isr()                          //subrutina de interrupción.
{ 
Ticker -= 65536;                        // Decrementa ticker 
if ( Ticker < 65536 )                   // Si ya pasó 1 segundo 
{  Ticker += FRECUENCIA_TIMER1;          //   Incrementa ticker 
Segundos++;
if(Segundos == 60) 
{Minuto++; Segundos=0;
if(Minuto == 60) {Hora++; Minuto=0; 
if(Hora == 24) {ndia++; Hora=0; dia++;
if (dia>7) {dia=0;} 
if (  (ndia == 29 && Mes==2 && !BISIESTO(Year)) 
|| (ndia == 30 && Mes==2) 
|| (ndia == 31 && (Mes==4 || Mes==6 || Mes==9 || Mes==11 )) 
|| (ndia == 32) 
) {Mes++;ndia=1;} 
if(Mes == 13) {Year++; Mes=1;}}}}   
}}
void main(void)
{
Ticker = FRECUENCIA_TIMER1;                    //  Frecuencia _Timer1 tiene el valor de 1000000 se carga ticker con ese valor
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );    // initializa TIMER1 para interrupción 
enable_interrupts( INT_TIMER1 );               // habilita LA interrupción (CUANDO LLEGA A SU VALOR MAXIMO 65536 ) TIMER1
enable_interrupts(GLOBAL); 
output_b(0);
set_tris_b(0b00000000);                        // Configure RB0 & RB1 as inputs
set_tris_a(0b00000011);                        // A0 Y A1 COMO PULSADORES
delay_ms(1000);  // wait a second
lcd_init();
lcd_putc('\f');
while(TRUE)
{
if (input (pin_a0)==1)                       // PULSO 1 DE SETEO DE RELOJ RA0
{  delay_ms(200);                         // Este delay evita el rebote del pulsador
lcd_putc('\f');                        // Limpia el Lcd
while (true)                           // While Principal del SETEO de RELOJ
{
showminuto();                          // *********MUESTRA MINUTOS***********
delay_ms(200);                         
if (input (pin_A1)==1)           //***** Aumenta minutos con RA1 ****** 
{
minuto++;
if(minuto > 59)
minuto = 0;
}   
if(input(PIN_a0) == 1)           // PULSO 2 DE SETEO DE RELOJ RA0
{     delay_ms(200);
lcd_putc('\f');
while (true)
{
showhora();             // ******** MUESTRA HORAS ************
delay_ms(200);
if(input (pin_A1)==1)   // ******** Aumenta HORAS ************
{hora++;
if(hora > 23)
hora = 0;
}
if(input(PIN_a0) == 1)   // PULSO 3 DE SETEO DE RELOJ RA0
{ delay_ms(200);
lcd_putc('\f');
while (true)
{
showalminuto();           // ***** MUESTRA ALARMA MINUTO *****
delay_ms(200);
if(input (pin_A1)==1)     // ***** Aumenta Alarma minutos ****
{alminuto++;
if(alminuto > 59)
alminuto = 0;
}
if(input(PIN_a0) == 1)   // PULSO 4 DE SETEO DE RELOJ RA0
{ delay_ms(200);
lcd_putc('\f');
while (true)
{
showalhora();          // ** MUESTRA ALARMA HORA ******
delay_ms(200);         
if(input (pin_A1)==1)  //**** Aumenta Alarma Horas ****
{alhora++;
if(alhora > 23)
alhora = 0;
}
if(input(PIN_a0) == 1)              // PULSO 5 DE SETEO DE RELOJ RA0
{delay_ms(200);
lcd_putc('\f');
while (true)
{
showdia();                        // **** Muestra Nombre Dia ****** 
delay_ms(200);
if(input (pin_A1)==1)             //**** Aumenta Nombre Dia *******
{Dia++;
if(dia > 7)
dia = 1;
}
if(input(PIN_a0) == 1)            // PULSO 6 DE SETEO DE RELOJ RA0
{ delay_ms(200);
lcd_putc('\f');
while (true)
{
showndia();                       // **** MUESTRA NRO DIA ********
delay_ms(200);
if(input (pin_A1)==1)             // ***** Aumenta Nro DIA *******
{ndia++;
if(ndia > 31)
ndia = 1;
}
if(input(PIN_a0) == 1)             // PULSO 7 DE SETEO DE RELOJ RA0
{ delay_ms(200);
lcd_putc('\f');
while (true)
{
showmes();                        // ***** Muestra MES **********
delay_ms(200);
if(input (pin_A1)==1)             // ***** aumenta MES **********
{mes++;
if(mes > 12)
mes = 1;
}
if(input(PIN_a0) == 1)            // PULSO 7 DE SETEO DE RELOJ RA0
{ delay_ms(200);
lcd_putc('\f');
while (true)
{
showyear();                        // ***** Muestra AÑO **********
delay_ms(200);
if(input (pin_A1)==1)              //*****  Aumenta AÑOS *********
{year++;
if(year > 99)
year = 0;
}
if(input(PIN_a0) == 1)             // ************ PULSO 8 de ESCAPE del WHILE **************
{
lcd_putc('\f');                    // *********** LIMPIA EL LCD ANTES DE SALIR **************
delay_ms(200);                     // *********** Evita el rebote del pulso *****************
goto salida;                       // *********** Va directo a SHOW DISPLAY *****************
}
}}}}}}}}}}}}}}} 
}
salida:
alarm_check(); 
showdisplay(); 
}
}

Con el programa listo solo nos queda montar en un protoboard todos los componentes y ver si todo funciona de manera correcta:

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Los resultados del montaje fueron muy alentadores, todo funcionaba de manera correcta por lo que nos decidimos a realizar un montaje mas adecuado para nuestro proyecto.

Realizaríamos nuestra propia pcb con ayuda de nuestra super versatil CNC y se nos ocurrió también que montaríamos todo en una cajita de acrílico aprovechando un letrero viejo de una publicidad que teníamos por allí guardado.

A continuación los pasos para el montaje final de nuestro proyecto.

Diseño del PCB para el reloj alarma lcd con PIC16f628.

Realizamos el diseño de la PCB con la ayuda de nuestro programa PCB WIZARD.

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Y el diseño de los tracks para el maquinado con la CNC nos quedaría así:

PCB DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Guardamos el diseño en un PDF y realizamos el proceso de vectorizacion con nuestro programa Aspire.

Este proceso de como realizar nuestros pcb en la CNC ya lo he explicado en un post Anterior.

Maquinado de la PCB en la CNC de TECNOCIENCIA.

Luego de realizar nuestro proceso de vectorización tanto de las pistas del circuito como de los agujeros mandamos el trabajo a la CNC y estos serian los resultados:

PCB DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

El resultado final de la PCB ya con los agujeros es este:

PCB LCD DISPLAY

A continuación solo nos queda poner manos a la obra para el ensamblaje del reloj.

Ensamblaje de Piezas del Reloj LCD

EL proceso de soldadura de componentes no fue muy difícil de realizar ya que la PCB nos facilita mucho el trabajo.

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Luego de soldar los componentes principales hacemos una prueba de funcionamiento para verificar que no existan fallas.

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Y todo funciona de forma correcta.

No queda mas que montar todo en la cajita de acrílico que cortamos con nuestra CNC.

Hacemos los agujeros para montar la plaquita PCB y luego ensamblamos todo dentro de ella.

Al final quedamos muy contentos con el resultado.

DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628

Finalmente podemos decir que el reemplazo de nuestro viejo reloj despertador fue todo un éxito.

Que opinas intentarías hacerlo ? te animo a que lo hagas. Suerte.

Recuerda que puedes ver las demás entradas de nuestro blog en:

https://www.tecnocienciaperu.com/blog/

También puedes visitar nuestro canal de YouTube:

CANAL YOUTUBE TECNOCIENCIA

5 Replies to “DISPLAY LCD RELOJ ALARMA Y CALENDARIO CON PIC16F628.

  1. Evitás la variable FRECUENCIA_TIMER1 que es “long” (y no está declarada en código), si escribís:

    Ticker += 65536; // suma 65536 ticks
    if (Ticker > 1000000){ //encontró 1 segundo ?
    Ticker -= 1000000;// ajuste fino de segundo, hay que jugar con este valor !!!

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *