Cerradura Electronica-Arduino

download Cerradura Electronica-Arduino

of 55

description

Programa de una cerradura en Arduino

Transcript of Cerradura Electronica-Arduino

Cerradura electronica10-12-2012http://www.youtube.com/watch?v=xSuP_aj86BkHe modificado la cerradura electronica, que se puede ver en el video, para que funione con Arduino.He usado:Un Arduino Nano. 12Un teclado keypad de ebay. 3Un lcd 1602 que vale unos 5Un modulo de dos rels de ebay. 3Un sensor magnetico de puerta abierta. 4Un zumbador. 3El Motor con mando a distancia de ABUs Hometec. 70 (En Alemania cuesta unos 40, en ferreteria Espaola unos 150... sin comentarios)Estoy esperando de china:-RCT por I2C. Mi arduino atrasa 10 minutos al da Se puede paliar por soft, pero el RTC es lo suyo y vale menos de 3-Un LCD con I2C para liberar pines y as poder poner sensor temperatura 18B20, grabador de tarjetas SD, sensor llamadas al timbre (poniendole un rel de 220 en paralelo) y cuarta columna keypad.He conectado los dos rels a los botones del motor que abren y cierran la puerta manualmente. He tenido que usar el motor alrevs (que cierre cuando abre y viceversa).El codigo fuente es el siguiente (compilado con Arduino 1.0.2):/******************************************************************************* * CERRADURA ELECTRONICA de Antonio EB4CAK * Pongo este programa bajo licencia GNU GPL. * * 22-5-2011 INICIO * 20-6-11 Version 1.0* 12-7-11 V 1.1 Puerta se cierra ante clave erronea - corregir bug que no cierra la puerta -* 10-9-11 V 1.2 Avisa de la ultima clave erronea* 08-10-12 v 1.3 Modificacion para Mari Carmen y aadida clave 7 generica * 1-12-2012 v1.4 Adaptacion de STM8s a Arduino. Quitada clave7. Espera incremental si error. * 7-12-2012 Lo instalo ******************************************************************************Cosas Pendientes:-RTC (pines A4 y A5)-SD para grabar entradas y salidas-Pin de entrada para avisar si han llamado al timbrePINES: 2 Teclado Col 13 Teclado Col 24 ABRIRCERRADURA Rele cerradura ON5 CERRARCERRADURA Rele cerradura OFF6 Teclado Col 37 Zumbador Teclado Col 4 (Opcional)8 Teclado Fila 19 Teclado Fila 210Teclado Fila 311Teclado Fila 412 LCD RS13* LCD EA0 LCD D4A1 LCD D5A2 LCD D6A3 LCD D7A4* RTCA5* RTC A6 Sensor timbre? 18b20?A7 Sensor puerta abierta (Poner una R de 5v al pin y luego el pin a Masa pasando por el interruptor)*/#include #include #include // Para la hora#include #include // a basic DS1307 library that returns time as a time_t#include // initialize the library with the numbers of the interface pinsLiquidCrystal lcd(12, 13, 17, 16, 15, 14);//////////// Config tecladoconst byte ROWS = 4; //Filasconst byte COLS = 3; //Columnaschar keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'}};byte rowPins[ROWS] = {8,9,10,11}; //connect to the row pinouts of the keypadbyte colPins[COLS] = {2,3,6}; //connect to the column pinouts of the keypadKeypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );//////////// Fin Config Teclado////// Claveschar Clave1[15]={"1234"}; // Pueden ser 15 caracteres o menos.char Clave2[15]={"00000000"}; char Clave3[15]={"1111111111111"}; // Para Mari Carmenchar Clave4[15]={"32165498732165"}; // Clave de un solo usochar Clave5[15]={"32112346549878"}; // Clave de un solo usochar Clave6[15]={"55555556546546"}; // Clave de un solo uso// Nota: Hay que cambiar estas claves. Solo son de prueba para la difusion del codigo.////// Fin Claves#define LUNES 2 #define MARTES 3#define MIERCOLES 4#define JUEVES 5#define VIERNES 6#define SABADO 7#define DOMINGO 1#define SI 0xFF#define NO 0#define COMPROBAR 1 // Usado en exceso_de_tiempo#define INICIAR 2// Usado en exceso_de_tiempo#define ANULAR 0// Usado en exceso_de_tiempo#define SensorPuerta A7#define BUZZ 7 //Definimos el pin del zumbador#define ABRIRCERRADURA 4#define CERRARCERRADURA 5#define INACTIVO HIGH // Para no liarse con ABRIRCERRADURA#define ACTIVO LOW/********* PARA TEMPORIZACIONES Y RELES ***********/unsigned int error_acumulativo=1; // Para que a cada codigo erroneo la espera sea mayor/********* FIN PARA TEMPORIZACIONES Y RELES *************/time_t pctime = 1354786049; // Tiempo inicial de prueba hasta poner el RTC.time_t TiempoError = 0; // Para pintar hora de ultima entrada erroneavoid setup() { delay(50); // Por si acaso, para estabilizar. Serial.begin(9600); // Para depuracion solo. lcd.begin(16, 2); // 16 Columnas y 2 filas lcd.clear(); //Para evitar que queden cosas mal. pinMode(BUZZ, OUTPUT); // Esto se puede quitar. pinMode(ABRIRCERRADURA, OUTPUT); pinMode(CERRARCERRADURA, OUTPUT); digitalWrite(ABRIRCERRADURA, INACTIVO); // Reles inactivos digitalWrite(CERRARCERRADURA, INACTIVO); // Reles inactivos /* Aqui PONEMOS RTC Revisarlo para varios intentos setSyncProvider(RTC.get); // the function to get the time from the RTC if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); */ setTime(pctime); melodia(2); // Musiquilla que indica reinico}// Del setupvoid loop() { pinta_reloj(); delay(5); char key = keypad.getKey(); // Capturamos tecla clave_tecla(key); // Comprobamos si es la clave OK // Pintamos errores if(TiempoError)pinta_reloj_eventos(); // Si PUERTA ABIERTA pasamos a modo configuracion if(analogRead(SensorPuerta) > 500){ // if(analogRead(SensorPuerta) > 500){ luz_puerta(SI); // Encendemos la luz de la entrada modo_configuracion(); luz_puerta(SI); // Volvemos para iniciar contador otra vez }else luz_puerta(NO); // Con la puerta cerrada pensamos en apagar la luz de la entrada y en cerrar la cerradura a los x seg.}// Del loop/************************************************************************//************ Pintamos la Hora ***********************//************************************************************************/void pinta_reloj(){int dia;dia=weekday(); lcd.setCursor(0,0); // Situamos el cursor if(hour() < 10) lcd.print('0'); lcd.print(hour()); printDigits(minute());// printDigits_segundos(second()); lcd.print(" ");/* lcd.print(day(),DEC); lcd.print("/"); lcd.print(month(),DEC); lcd.print("/"); lcd.print(year(),DEC); */switch(dia){case LUNES:lcd.print("L");break;case MARTES:lcd.print("M");break;case MIERCOLES:lcd.print("X");break;case JUEVES:lcd.print("J");break;case VIERNES:lcd.print("V");break;case SABADO:lcd.print("S");break;case DOMINGO:lcd.print("D");break;} }//Fin pinta_reloj()void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 lcd.print(":"); if(digits < 10) lcd.print('0'); lcd.print(digits);}void printDigits_segundos(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 lcd.print("."); if(digits < 10) lcd.print('0'); lcd.print(digits);}/************************************************************************//************ Centralizacion de Musiquillas ***********************//* Tuve problemas hasta que descubr que sin el delay() no funciona *//************************************************************************/void melodia(int tipo){ // Musiquillas 1->Error 2->Inicio 3->Correcto 4->Pulsar tecla 5->puerta abierta 6->Puerta cerradaswitch(tipo){ case 1: cerrar_puerta(); // En caso de clave mal, echamos cerrojo tone(BUZZ,2000); TiempoError=now(); // Memorizamos hora para recordar el ultimo error delay(2000*error_acumulativo++); // Mas retraso y acumulativo (puede llegar a un pitido de 35 horas por cada error) noTone(BUZZ); break; case 2: tone(BUZZ,1000); delay(50); tone(BUZZ,4000); delay(50); tone(BUZZ,1000); delay(50); noTone(BUZZ); break; case 3: tone(BUZZ,1000); delay(20); tone(BUZZ,4000); delay(40); tone(BUZZ,2000); delay(20); tone(BUZZ,1000); delay(40); tone(BUZZ,4000); delay(40); tone(BUZZ,2000); delay(20); tone(BUZZ,1000); delay(40); tone(BUZZ,4000); delay(60); tone(BUZZ,2000); delay(40); tone(BUZZ,1000); delay(40); tone(BUZZ,4000); delay(40); tone(BUZZ,1000); delay(60); noTone(BUZZ); error_acumulativo=1; // Reiniciamos la espera si claves errorneas. break; case 4: tone(BUZZ,1000); delay(80); noTone(BUZZ); break; case 5: tone(BUZZ,2000); delay(80); tone(BUZZ,4000); delay(50); tone(BUZZ,1000); delay(80); tone(BUZZ,4000); delay(30); noTone(BUZZ); break; case 6: tone(BUZZ,4000); delay(40); tone(BUZZ,2000); delay(30); tone(BUZZ,4000); delay(30); tone(BUZZ,1000); delay(100); noTone(BUZZ); break; }//Del switch noTone(BUZZ); // Por si acaso.}//del melodia()/************************************************************************//* Entramos en modo configuracion al abrir la puerta *//* Solo saldremos al cerrar la puerta *//* Mantenemos la luz de la entrada encendida *//************************************************************************/void modo_configuracion(void){char key=0; char estado=0;melodia(5); // Avisamos de puerta abierta lcd.setCursor(0,1); // Situamos el cursorlcd.print(" CONFIG PULSE 0 "); pctime=now(); // Igualamos pctime al tiempo del sistema. // Encender luz entrada (y mantenerla despues, quizas usando exceso_de_tiempo())while(analogRead(SensorPuerta) > 500){ // Mientras la puerta este abierta: pinta_reloj(); key = keypad.getKey(); //Capturamos tecla if (key) //new key has been pressed {melodia(4); // Pitidito de pulsacionif(key=='0')estado++; // Cambiamos de menu con el CEROif(estado>4)estado=1; // Lo hacemos ciclicoswitch(estado){case 1: // BORRAR ENTRADAS ERRONEASlcd.setCursor(0,1);lcd.print(" BORRAR ENTRADA");if(key=='*'){TiempoError=0;error_acumulativo=1;}if(key=='#'){TiempoError=0;error_acumulativo=1;}break;case 2: // AJUSTAR HORAlcd.setCursor(0,1);lcd.print(" AJUSTE HORA ");if(key=='*'){pctime-=3600;}if(key=='#'){pctime+=3600;} setTime(pctime); // igualamos el tiempo de sistema al de pctimebreak;case 3: // AJUSTAR MINUTOSlcd.setCursor(0,1);lcd.print(" AJUSTE MINUTOS");if(key=='*'){pctime-=60;}if(key=='#'){pctime+=60;} setTime(pctime); break;case 4: // AJUSTAR DIAlcd.setCursor(0,1);lcd.print(" AJUSTE DIA ");if(key=='*'){pctime-=86400;}if(key=='#'){pctime+=86400;} setTime(pctime); break;} } // Del si key } // Del whilelcd.clear(); // Al salir hay que limpiar el display melodia(6); // Cantamos q la puerta se cierra}/************************************************************************//* COMPROBAMOS LAS TECLA PULSADAS en busca de claves *//************************************************************************/void clave_tecla(char Tecla){static char oldkey, posicion_clave=0; static char Clave[15];if(exceso_de_tiempo(10, COMPROBAR)){posicion_clave=0; melodia(1); return;} // Damos seal de errorif (Tecla != oldkey) //new key has been pressed { if (Tecla) {melodia(4); // Pitidito de pulsacionexceso_de_tiempo(10, INICIAR);Clave[posicion_clave]=Tecla;Clave[posicion_clave+1]=0; // Finalizamos la cadena para evitar erroresif(posicion_clave < 14){ posicion_clave++; } else{// Si metemos 15 num y no hay clave hay que esperarposicion_clave=0; melodia(1);exceso_de_tiempo(10, ANULAR);// Implantar esperas si se mete codigo erroneo X veces} if(!strcmp(Clave, Clave1)){ // CLAVE CORRECTA clave_correcta();// abrir puertaposicion_clave=0; // Reiniciamos contador}if(!strcmp(Clave, Clave2)){ // CLAVE CORRECTA clave_correcta();// abrir puertaposicion_clave=0; // Reiniciamos contador}/* La clave3 funcionar los dias de curro de 2 a 9 (OJO Hasta el RTC pongo todos los dias de 9 a 23) */if(hour()>9 && hour() (horaX+20))){ //GPIO_WriteLow(GPIOA, GPIO_PIN_3); //Apagar luz cerrar_puerta();horaX=0; // Reiniciamos el contador}} // Del else}

Example1. #include 2. 3. Password password=Password("1234");4. 5. voidsetup(){6. Serial.begin(9600);7. 8. password.append('1');//add 1 to the guessed password9. password.append('2');//add 2 to the guessed password10. password.append('3');//add 3 to the guessed password11. password.append('4');//add 4 to the guessed password12. //should print true, since 1234 == 123413. Serial.println(password.evaluate()?"true":"false");14. 15. password.reset();//reset the guessed password to NULL16. //should print false, since 1234 != NULL17. Serial.println(password.evaluate()?"true":"false");18. 19. password.set("qwerty");//set target password to qwerty20. //should print true, since qwerty == qwerty21. Serial.println(password.is("qwerty")?"true":"false");22. //should print false, since qwerty != qwirty23. Serial.println(password.is("qwirty")?"true":"false");24. }25. 26. voidloop(){/*nothing to loop*/}

Teclado numrico 34 con LCD10 enero, 2012Arduino,Micros,Teclado numrico con LCD.Arduino,Cristal Liquido,HD44780,Keypad,LCD,LiquidCrystal,Switch,TecladoPrologo.En otro artculo ya hice un esbozo superficial sobre las pantallas de cristal lquido LCD, distinguiendo dos grandes grupos, las pantallas alfanumricas y las pantallas grficas. Por el momento, nos referiremos las pantallas LCD alfanumricas, en concreto las de cuatro lneas y 40 columnas. En la actualidad la mayora de los LCD estn controlados con el conocido HD44780 de Hitachi. El cual puede ser configurado para manejar un display de matriz de puntos de cristal lquido bajo el control de un microprocesador de 4 u 8 bits.En este artculo, pretendo hacer una aplicacin que tenga utilidad para quien disponga de un LCD y quiera realizar una aplicacin que le sirva de ayuda en su trabajo o para una aplicar en un proyecto. Hay muchas aplicaciones descritas en gran cantidad de artculos y webs de distintos autores y en todas ellas subyace un toque personal que hace la diferencia, espero que en este, tambin encuentren la novedad o el punto que buscaban.El propsito de este artculo es reunir una serie de unidades sencillas, como base de los ejemplos, con pantalla de cristal lquido LCD, que se encuentran disponibles para trabajar con Arduino. Se describen algunos ejercicios para comprender los principios de uso y sin perder el carcter didctico de lo descrito.Display LCD.El uso de este dispositivo se ha extendido en los ltimos aos debido a la proliferacin de los microcontroladores con sus cada ves mayores prestaciones y los sistemas de desarrollo que los sustentan. Hay esencialmente dos tipos de pantalla para elegir, serie y paralelo, en referencia a cmo se conectan y se comunican con el mismo PC.En cuanto a los LCD, en el mercado pueden encontrarse distintos modelos que se adaptan a las necesidades de los proyectos que se planteen. As, podemos encontrar LCD de una lnea y 8 a 40 caracteres, 4 lneas por 40 caracteres y tantas lneas y caracteres que se necesiten. Los LCD grficos estn avanzando tanto que sus precios son cada da ms asequibles a cualquier necesidad.

La mayora de los LCD paralelos son muy similares, usan chips de interfaz estndar en la industria (como elHD44780oHD44100) para la asignacin de pines, a menudo son idnticos.En este artculo, slo tratar de los LCD de cuatro lneas y 20 caracteres o columnas. Naturalmente por que es el que tengo a mi disposicin. Para controlar pantallas Cristal Liquido (LCD) basada en el Hitachi HD44780 (o compatible) se necesita laNueva librera LiquidCrystalque nos proporciona FM, como se le conoce en el foro. Adems, tambin utilizaremos un teclado 34 similar al de la imagen de abajo, dos resistencias, dos LEDs, dos pulsadores y algunos hilos de colores para conectar todo.No voy a entrar sobre los pros y los contras de cada uno, ya que este no es el objetivo del presente artculo, sin embargo, lo que voy a decir es que que, fundamentalmente, la decisin se reduce a su costo en comparacin con la facilidad de uso, es la cuestin.Si bien los displays serie son ms fciles de poner en marcha y tienen un poco mejor ayuda con el software, adems de tener algunas caractersticas adicionales. Por otro lado, los LCD paralelos, necesita cablearlas usted mismo, pero son mucho ms baratos y en su mayor parte se puede mostrar la misma informacin.Lo que pretendo realizar es un teclado, con el que introducir una clave de un nmero de entre 4, 6 o ms dgitos y el programa compare los dgitos que se pulsan por el usuario, con la clave guardada y si hay coincidencia que, haga una cosa, en caso de no coincidir que, haga otra cosa. En principio, se ve sencillo.Para abordar el proyecto, necesitamos unos pocos materiales a parte de la placa Arduino y el LCD, como estos mostrados.El ms importante, el teclado, este tipo de teclados, a pesar de que es de los aos 80 (foto deFuturlec), es bastante corriente y fcil de encontrar en el mercado. El resto de componentes, es de uso comn. El circuito electrnico que voy a utilizar se muestra en la imagen que sigue.Mediante la ayuda de un teclado de 12 pulsadores, podemos entrar una serie de dgitos que, formen el cdigo secreto para activar un sistema, si existe coincidencia o por el contrario, pondr en accin otro sistema que indique que, se est forzando el acceso no autorizado a la instalacin, por un desconocido.Para esto, en primer lugar debemos configurar la libreraKeypad.zipy declararemos los 7 pines de Arduino que conformaran el teclado, por un lados las 4 lneas (rows) y las 3 columnas (cols) y la conformacin que tomarn los contactos, como se puede ver a continuacin:El primer paso es incluir la librera y las constantes que vamos a utilizar:?Ver cdigoPHP12345678910 #include "Keypad.h"

const byte ROWS = 4; //four rows const byte COLS = 3; //three columns char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} };

El paso que sigue es, reservar memoria en bytes, para los valores de los pulsadores y la asignacin del pin que se corresponde con los de Arduino. Sin embargo, hay que observar que, vamos a necesitar un nmero alto de pines en este y los siguientes ejemplos. Por este motivo, la asignacin de pines, se hace con vistas a no tener que cambiar con frecuencia dicha disposicin. Adems, se asignaran otras variables, en funcin de las necesidades que surjan.?Ver cdigoPHP12 byte rowPins[ROWS] = {5, 4, 3, 2}; //conecta los pinouts row del keypad byte colPins[COLS] = {8, 7, 6}; //conecta los pinouts column del keypad

Este es el momento de crear el teclado propiamente dicho, es decir, con esta sentencia, el programa generar una matriz que ver como un teclado, al que se remitir, cuando tenga que representar un dgito. Esto se consigue con la siguiente lnea:?Ver cdigoPHP1 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

Tenemos que guardar una clave, luego, necesitamos hacer una reserva de memoria y adems, el cdigo que introduzca el usuario, tambin requiere un espacio de memoria. Posteriormente, con slo comparar ambas matrices, obtendremos fcilmente si hay coincidencia entre ambas. Veamos como se hace:?Ver cdigoPHP12 char PIN[6]={'1','2','3','4','5','6'}; // o numero secreto (!) char attempt[6]={0,0,0,0,0,0}; // usado para comparar

En la asignacin de las dos matrices de 6 dgitos, utilizamos la funcincharpara almacenar los bytes de cada matriz. Una, para los dgitos de entrada llamadaattempt, se compararn con la otra matriz, contenida enPIN. Slo, si hay coincidencia, la clave es correcta y actuar la salida correspondiente. Se han dispuesto dos salidas complementarias, las cuales se pueden conectar a los dispositivos adecuados que, deriven la potencia necesaria para sus actuadores.En elsetup, configuramos los distintos pines, segn convenga a cada uno, se declara el puerto serie y su velocidad:?Ver cdigoPHP123456 pinMode(sal1, OUTPUT); pinMode(sal2, OUTPUT); Serial.begin(9600); //Configura la velocidad del puerto serie keypad.setHoldTime(500); // Default is 1000mS keypad.setDebounceTime(250); // Default is 50mS

Destacar las funciones que afectan al rebote de los pulsadores que, estn integrados en la librerakeypadrepresentados porkeypad.setHoldTimeykeypad.setDebounceTime. Aqu. se ha reducido su tiempo de mantenimiento como se puede apreciar en el propio cdigo.Adems, se ha incluido el mensaje que presentar al inicio del programa. En este mensaje, se puede hacer una descripcin corta de lo que hay que hacer para entrar el cdigo PIN. Esto se ha hecho con el siguiente cdigo:?Ver cdigoPHP12345 Serial.println(" Debe introducir la secuencia: "); Serial.print(" * X X X X X X # "); Serial.println(" >> X = del 0 al 9"); incorrectPIN();Serial.print(" "); Serial.println(" Intentelo: ");

En este punto, para una mayor claridad, se deben declarar las rutinas que intervengan en el programa, acurdese de hacer comentarios, para poder comprender qu hace cada rutina. As pues, se declara la rutinavoid correctPIN()que, se ejecutar en el caso de haber coincidencia, es decir:?Ver cdigoPHP12 digitalWrite(10, LOW); // desactiva un contacto pin 1 digitalWrite(11, HIGH); // activa un contacto pin 2

Y le seguir la rutinavoid incorrectPIN()que se ejecutar en el caso contrario. Que hace exactamente lo mismo pero invertidos?Ver cdigoPHP12 digitalWrite(11, LOW); // desactiva un contacto pin 2 digitalWrite(10, HIGH); // activa un contacto pin 1

Se ha incluido una rutina para activar un sistema (en este caso, visual) para activar un LED en su caso. Convoid readKeypad(), se lee cualquier entrada de teclado, o sea, hace un chequeo del teclado, de modo que cuando se presione un pulsador o llave. Esto lo consigue mediante este cdigo, asignando achar key, todo lo que llegue por el teclado con:char key = keypad.getKey();si no se produce una entrada, permanecer en espera. Gracias a esta sentencia deif (key != NO_KEY), en la cual permanecer la ejecucin del programa, esperando a que se produzca una entrada. As que, este es el listado:?Ver cdigoPHP12 char key = keypad.getKey(); if (key != NO_KEY)

Le sigue la funcinswitch (key)que es capaz de detectar la tecla que se ha pulsado. Cuando se produce una entrada del teclado, se guarda en la variableattempt, lo reconoce y evala conPIN[]si es exactamente igual, sale de esta subrutina y salta a la subrutinacorrectPIN()y sigue hasta el final de la misma.En caso de que la evaluacin no sea exacta, salta a la subrutinaincorrectPIN();y cuando termina, vuelve hasta la lnea:for (int zz=0; zz