Reloj – Alarma con ATmega328 y DS1307

¡He vuelto! Después de un tiempo de ausencia por diversos motivos vuelvo a escribir y con unas cuántas cosillas que contar, pero antes vamos a lo que quedaba pendiente desde hace tiempo ya, el post sobre mi proyecto integrado del ciclo de Desarrollo de productos electrónicos, un “Sistema de señalización de clases con Arduino/ATmega328” o también podemos considerarlo como un “Reloj – Alarma – Despertador con Arduino/ATmega328“.

El objeto del proyecto es el diseño de un sistema μControlado de alarmas con reloj a tiempo real, pantalla para visualización de datos y actuadores para configuración.

Un sistema automático definido de forma que permita la configuración de la fecha y la hora, así como diferentes alarmas a diferentes horas del día, efectuando cambios en la configuración del sistema a través de pulsadores, obteniendo una representación visual de los datos en el módulo LCD instalado.

El sistema podrá ser configurado para la actuación sobre una sirena externa automáticamente o permitirá la acción manual sobre dicha sirena.

Antes de empezar, lo que haremos será elegir los elementos con los que vamos a realizar el proyecto, ya que es un proyecto muy versátil y existen muchas combinaciones de elementos que darían lugar al mismo resultado final.

Este es un proyecto bastante sencillo de realizar para el cuál se necesitan conocimientos de Arduino y su programación y nociones de electrónica analógica.

Vamos al lío, sigue leyendo! 

Como he dicho antes, existen muchas maneras de realizar este proyecto, yo personalmente me decidí por utilizar los siguientes componentes principales:

– μControlador ATmega328P: Es el microcontrolador que poseen las placas Arduino UNO y nos permite programarlo mientras está insertado en la placa de Arduino y luego retirarlo y colocarlo en cualquier otra placa que hayamos diseñado. Funcionará como controlador principal del proyecto ya que será el encargado de procesar y manejar el reloj a tiempo real, la pantalla LCD, y actuar sobre el relé que activará la sirena.

– RTC DS1307: Una forma económica de obtener una base de tiempo con un microcontrolador, es un reloj a tiempo real. El RTC DS1307 es económico, muy sencillo de utilizar y tan solo nos ocupará el puerto I2C de nuestro microcontrolador, por tanto, solo 2 pines.

– Sirena 220V AC: Esta sirena (Modelo E2S A105N) donación de @CuninganLostPwd (Gracias!) y es ideal para el proyecto, puesto que al ser de 220V AC nos permite tener que mezclar en el proyecto corriente continua para la alimentación de la placa y los componentes, y corriente alterna para la alimentación de la sirena.

– Relé 5V 8A: Para activar la alarma usaré un dispositivo electromecánico, un relé, que conmutará para encender o apagar la sirena.

– Display LCD 16×2: De los modulos visualizadores para trabajar con Arduino, los displays LCD 16×2, son económicos y muy simples de utilizar gracias a las librerías de Arduino.

Teniendo los componentes principales elegidos, pasamos al diseño del proyecto, es decir, esquemas electrónicos y conexiones.

Salvo que vayamos a utilizar un transformador comercial de los de tipo “cargador de móvil” debemos buscar una manera de transformar y reducir los  220V corriente alterna que tenemos en casa, a 5V corriente continua para poder alimentar nuestro circuito, debido a que tanto el ATmega328, el RTC DS1307 como el relé, trabajarán a esta pequeña tensión, así que manos a la obra.

Rebuscando en casa, encontré un pequeño transformador de 220V – 9V, pero esto nos dará 9V en corriente alterna, por lo que habrá que rectificar, rizar y regular la señal alterna hasta conseguir una señal de 5V corriente continua:

El esquema que he utilizado es el siguiente:

El transformador conectado en “J3” nos dará 9V en corriente alterna mientras que el puente de diodos rectificará dicha corriente alterna hasta obtener una señal pulsatoria de 7,6V aproximadamente puesto que tendrá una caída de tensión de 1,4V.  El condensador C1 se encargará de rizar la señal mientras que el regulador de tensión LM7805 regulará la tensión de los 7,6V a 5Vcc. De este modo obtenemos una fuente de alimentación de 5Vcc. El diodo D2, está colocado para proteger al regulador de tensión.

Con la alimentación, pasamos a diseñar el circuito que controlará todo el proyecto, yo personalmente siempre realizo los circuitos en una protoboard y una vez comprobado que todo está correctamente y funciona, paso al diseño del esquema electrónico y posterior placa de circuito impreso.

Proyecto montado en protoboard para su programación y verificación de funcionamiento.

Veamos mi esquema una vez terminado. El esquema es todo uno entero, solo que lo he dividido en bloques que realizarán cada uno su “parte” del proyecto.

Esquema electrónico dividido en bloques

Bloque 1: El μControlador ATmega328 será el encargado de controlar todo el proyecto, y como todo μControlador necesita de un cristal de cuarzo con sus correspondientes condensadores. En este caso el Atmega328 funcionará a 16Mhz . Así mismo, tendremos que alimentarlo, de modo que conectamos los 5Vcc y GND obtenidos de la fuente diseñada anteriormente a los pines correspondientes (Siempre comprobar el pinout del circuito integrado en su Datasheet para asegurarnos de no conectar los pines equivocados). También es conveniente colocar un condensador entre los pines de VCC y GND del circuito integrado que funcionen a modo de filtro, en el esquema serían C6 y C7.

Bloque 2: Este bloque corresponde a la botonera del proyecto que utilizaremos para configurar la hora, alarmas y “movernos” por los menús del proyecto que podremos visualizar en la pantalla LCD. En mi caso he utilizado 5 pulsadores normalmente abiertos, cada uno con su resistencia Pull-down necesaria para evitar valores aleatorios al leer el pin de cada pulsador, de modo al presionar el pulsador obtengamos una señal lógica HIGH (5V) en el pin donde esté conectado. Este bloque va a discreción de cada uno tanto los pines de conexión de cada pulsador así como la cantidad de pulsadores.

Bloque 3: Opcionalmente podemos añadir este pequeño bloque, al igual que la gran mayoría de productos electrónicos, yo he añadido un led conectado a los 5Vcc de la fuente de alimentación, que indique de modo visual que la fuente de alimentación esté encendida. Calculamos la resistencia para evitar quemar el led aplicando la ley de Ohm: R = V/I = 5Vcc/0,020 mA = 250 Ω. Un valor estándar sería  270 Ω.

Bloque 4: El RTC DS1307 podemos comprarlo en muchas tiendas electrónicas montado en una pequeña plaquita listo para conectar, en mi caso, compré todas sus partes por separado para poder integrarlas en la placa de circuito del proyecto. El pequeño circuito integrado de 8 pines necesita de un cristal de cuarzo de 32.768 Khz, así como alimentación 5Vcc y GND que obtendremos de la fuente. Utiliza el bus I2C para comunicarse con un μControlador, por tanto los pines SDA y SCL del DS1307 los conectaremos al bus I2C de nuestro μControlador. Por último, para evitar perder la hora y fecha programadas al cortar el suministro eléctrico, se conecta una pequeña pila de botón tipo CR2032 de 3V el pin correspondiente (Comprobar siempre el datasheet).

Bloque 5: Siempre digo que los LCD son de los elementos que no deben faltar en un proyecto electrónico. El bloque 5 corresponde al esquema de conexión de un display LCD 16×2 con el μControlador. Esto es opcional y los pines de conexión pueden variar a elección de cada uno puesto que los podremos configurar posteriormente en el código.

Bloque 6: Este bloque es de los más importantes del circuito, ya que nos permitirá encender o apagar la sirena cuyo funcionamiento es a 220V de corriente alterna, con tan solo una pequeña señal de 5V de corriente continua enviada desde el μControlador. Para esto utilizamos un relé.

¿Pero… qué es un relé?
Un relé es un dispositivo electromecánico que funciona a modo de interruptor.
Para entender el funcionamiento de un relé, una imagen vale más que mil palabras.
En la Wikipedia vemos el siguiente gif:

http://es.wikipedia.org/wiki/Rel%C3%A9

Funcionamiento de un relé

El relé está formado por un electroimán, un núcleo de hierro dulce rodeado de una bobina de hilo de cobre (Cilindro amarillo en la izquierda del gif) que al ser atravesada por una corriente eléctrica creará un campo magnético que magnetizará dicho núcleo de hierro, atrayendo un “inducido” de hierro (Pieza con forma de L que se ve en el gif) que a su vez accionará uno o varios contactos libres de potencial (Los 3 “palitos” amarillos de la derecha) para abrir o cerrar un circuito independiente conectado a estos contactos.

Los contactos del relé por la posición en la que se encuentran cuando está en reposo serán:

– Contacto normalmente cerrado: El “palito amarillo” de más a la izquierda.
– Contacto común: El “palito amarillo” del centro.
– Contacto normalmente abierto: El “palito amarillo” de la derecha.

De modo que con una pequeña señal, en mi caso 5Vcc procedente de uno de los pines digitales ATmega328, podemos cerrar el circuito de alimentación de la sirena que funcionará a 220V AC.

Conectamos uno de los polos de tensión 220V AC al contacto común del relé y el otro polo de tensión lo conectaremos a uno de los hilos de alimentación de la sirena.

SIEMPRE DESCONECTADOS DE LA CORRIENTE, NUNCA TOCAREMOS LOS CABLES DE TENSIÓN ESTANDO ESTOS CONECTADOS A LA PARED, ESTAMOS HABLANDO DE 220v DE CORRIENTE ALTERNA Y ES PELIGROSO. REALIZAR ESTE PASO BAJO LA SUPERVISION DE ALGÚN PROFESIONAL CUALIFICADO O CON LA PROTECCIÓN ADECUADA. 

Al contacto normalmente abierto del relé conectaremos el hilo de alimentación restante de la sirena, de modo que al accionar el relé, el contacto común cierre el circuito con el contacto normalmente abierto, permitiendo que la sirena quede alimentada a 220V y comience a funcionar.

Para terminar de analizar el bloque 6, vemos que no podemos conectar directamente el relé a los pines de un μControlador directamente, ya que estos no proporcionan la corriente suficiente para poder excitar el bobinado del relé, por lo que tendremos que hacerlo a través de un transistor.

En mi caso, como se ve en el esquema utilicé un transistor NPN 2N3904 el cuál tendrá su base conectada al pin digital del ATmega328, con la resistencia adecuada previamente calculada (R1) mediante la ley de Ohm para obtener la corriente necesaria para asegurar la saturación del transistor. Conectaremos el emisor del transistor a masa/GND y el colector irá conectado ánodo de un diodo y a uno de los pines del bobinado del relé. El cátodo del diodo lo conectaremos tanto a 5Vcc como al pin restante del relé.  

Así, al aplicar corriente a la base del transistor, este entrará en estado de saturación, permitiendo el paso de corriente entre colector y emisor, corriente que previamente atravesará la bobina del relé, activándolo. El diodo protegerá la bobina del relé de un cortocircuito.

Con eso, terminamos el “análisis” del circuito del proyecto.

– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

El siguiente paso será diseñar PCB  en algún software de diseño electrónico y para cuya realización puedo proponer él método casero de realización de placas de circuito impreso a la plancha. Esto a elección de cada uno, yo utilicé el OrCAD y realicé la placa de forma casera obteniendo los siguientes resultados:

Fotolito adherido al cobre mediante el método de la plancha.

PCB previamente atacada con ácido y lista para agujerear.

PCB montada y lista para conectar y probar.

Proyecto montado listo para programar y usar.

Una vez montado y comprobado que todo funciona correctamente, el paso final será programar el ATmega328.
Este paso es “personal”, cada uno puede programar el ATmega para funcionar del modo que le parezca mejor o más efectivo.

Por esta razón, no voy a colgar todo el código de mi proyecto, sino que haré al igual que el esquema, una serie de bloques de código de algunas partes importantes del funcionamiento del proyecto:

– Visualización de la hora y fecha del RTC DS1307 en el LCD: 

#include <LiquidCrystal.h> // Libreria para control del LCD
#include <DS1307.h>        // Libreria del reloj DS1307
#include <Wire.h>          // Libreria de comunicacion I2C

LiquidCrystal lcd(12, 7, 11, 10, 9, 8);  // Declaracion de los pines del LCD</pre>

#define botonUno 2
#define botonDos 3
#define botonTres 4
#define botonCuatro 5

char fechaActual[20], horaActual[20]; //Variable para formateo de fecha y hora
int RTCValues[7];                     //Variable para el almacenaje de fecha y hora

void setup()
{
for(int a = 2; a <=5; a++) pinMode(a,INPUT); //Declaramos los botones como entradas
  lcd.begin(16, 2); // Iniciamos LCD 16 caracteres x 2 filas
  DS1307.begin();   // Iniciamos el Reloj
}

void loop()
{
    mostrarHora(); // Mostramos hora y fecha en el LCD
}

void mostrarHora()
{
 do{

     DS1307.getDate(RTCValues);                          // Obtenemos la hora y fecha

     sprintf(horaActual, "%02d:%02d:%02d", RTCValues[4], // La formateamos
             RTCValues[5], RTCValues[6]);

     sprintf(fechaActual,"%02d-%02d-%02d", RTCValues[2],
	     RTCValues[1], RTCValues[0]);

     lcd.setCursor(4, 0); lcd.print(horaActual);     // Y mostramos por pantalla
     lcd.setCursor(0, 1); lcd.print(diaSemana(RTCValues[3]));
     lcd.setCursor(8, 1); lcd.print(fechaActual);

  } while(digitalRead(botonCuatro) != HIGH);         // Hasta que se pulse el boton 4
}

– Activación manual de la alarma:

#include <LiquidCrystal.h> // Libreria para control del LCD

#define rele A3 // Definicion de pines de pulsadores y rele
#define botonUno 2
#define botonDos 3
#define botonTres 4
#define botonCuatro 5

LiquidCrystal lcd(12, 7, 11, 10, 9, 8); // Declaracion de los pines del LCD

byte estado = 0, ultimoestado = 0; // Variables para el control de los pulsadores

void setup()
{
 lcd.begin(16, 2); // Iniciamos LCD 16 caracteres x 2 filas

for (int a = 2; a <=5; a++) pinMode(a, INPUT); // Declaramos los pines de salida
 pinMode(rele, OUTPUT);
}

void loop()
{
 estado = digitalRead(botonTres);
 if (estado != ultimoestado && estado==HIGH) activacionManual();
 ultimoestado = estado;
}

void activacionManual()
{
 lcd.setCursor(3, 0); lcd.print("Activacion"); // Mostramos el texto de activacion manual
 lcd.setCursor(5, 1); lcd.print("manual");

// Pulsando el boton 3 exitamos la base del transistor
// que encenderá el relé y hará sonar la alarma

 do{
 digitalWrite(rele, HIGH);               // Saturamos el transistor
 }while(digitalRead(botonTres) == HIGH); // mientras el botón 3 esté pulsado.

 digitalWrite(rele, LOW); //"Apagamos" el relé al soltar el botón 3
}

– Creación y visualización de 3 menús accesibles por pulsador:


#include <LiquidCrystal.h> // Libreria para control del LCD

#define rele A3 // Definicion de pines de pulsadores y rele
#define botonUno 2
#define botonDos 3
#define botonTres 4
#define botonCuatro 5

LiquidCrystal lcd(12, 7, 11, 10, 9, 8); // Declaracion de los pines del LCD

byte estado = 0, ultimoestado = 0; // Variables para el control de los pulsadores
byte seleccion = 0;

#define borraLCD lcd.clear(); // Define de la funcion clear() del LCD

void setup()
{
lcd.begin(16, 2); // Iniciamos LCD 16 caracteres x 2 filas

for (int a = 2; a <=5; a++) pinMode(a, INPUT); // Declaramos los pines de salida
pinMode(rele, OUTPUT);
}

void loop()
{
menuPrincipal(); // Mostramos el menu principal y esperamos seleccion
}
void menuPrincipal()
{

lcd.setCursor(0, 0); lcd.print("1- Hora/Fecha"); //Mostramos el menu en el LCD.
lcd.setCursor(0, 1); lcd.print("2- Alarmas");
lcd.setCursor(12, 1); lcd.print("3-");

// Leemos constantemente los botones, si alguno es pulsado, cambia el valor de "seleccion"
 // que después hará la llamará a la función asignada a dicho valor.

estado = digitalRead(botonUno);
if (estado != ultimoestado && estado==HIGH) seleccion = 1;
ultimoestado = estado;

estado = digitalRead(botonDos);
if (estado != ultimoestado && estado==HIGH) seleccion = 2;
ultimoestado = estado;

estado = digitalRead(botonTres);
if (estado != ultimoestado && estado==HIGH) seleccion = 3;
ultimoestado = estado;

estado = digitalRead(botonCuatro);
if (estado != ultimoestado && estado==HIGH) seleccion = 4;
ultimoestado = estado;

switch(seleccion) // Dependiendo del boton pulsado, realizamos una accion u otra.
{
case 1: borraLCD;
menuUno(); // BOTON 1 --> Menu 1
borraLCD;
break;

case 2: borraLCD;
menuDos(); // BOTON 2 --> Menu 2
borraLCD;
break;

case 3: borraLCD;
menuTres(); // BOTON 3 --> Menú 3
borraLCD;
break;

case 4: menuPrincipal(); // BOTON 4 --> Vuelve al menú principal
break;
}
}

void menuUno()
{
do{

// Código de las acciones del menú Uno.

}while(digitalRead(botonCuatro) != HIGH);
}

void menDos()
{
do{

// Código de las acciones del menú Dos.

}while(digitalRead(botonCuatro) != HIGH);
}

void menuTres()
{
do{

// Código de las acciones del menú Tres.

}while(digitalRead(botonCuatro) != HIGH);
}

Estos son códigos generales, están puestos para utilizar de forma individual cada bloque, pero combinándolos entre todos yo obtuve el código final del proyecto.

Y ya por último… un vídeo de funcionamiento! 🙂

🙂

Anuncios

113 comentarios en “Reloj – Alarma con ATmega328 y DS1307

Deja un comentario!

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s