Académique Documents
Professionnel Documents
Culture Documents
10-12-2012
http://www.youtube.com/watch?v=xSuP_aj86Bk
He modificado la cerradura electronica, que se puede ver en el video, para que funione con Arduino.
He usado:
Un Arduino Nano. 12
Un teclado keypad de ebay. 3
Un lcd 1602 que vale unos 5
Un modulo de dos rels de ebay. 3
Un sensor magnetico de puerta abierta. 4
Un zumbador. 3
El 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 timbre
PINES:
2 Teclado Col 1
3 Teclado Col 2
4 ABRIRCERRADURA Rele cerradura ON
5 CERRARCERRADURA Rele cerradura OFF
6 Teclado Col 3
7 Zumbador
Teclado Col 4 (Opcional)
8 Teclado Fila 1
9 Teclado Fila 2
10Teclado Fila 3
11Teclado Fila 4
12 LCD RS
13* LCD E
A0 LCD D4
A1 LCD D5
A2 LCD D6
A3 LCD D7
A4* RTC
A5* 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 <LiquidCrystal.h>
#include <Keypad.h>
#include <Time.h> // Para la hora
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <EEPROM.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 17, 16, 15, 14);
//////////// Config teclado
const byte ROWS = 4; //Filas
const byte COLS = 3; //Columnas
char 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 keypad
byte colPins[COLS] = {2,3,6}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//////////// Fin Config Teclado
////// Claves
char Clave1[15]={"1234"}; // Pueden ser 15 caracteres o menos.
char Clave2[15]={"00000000"};
char Clave3[15]={"1111111111111"}; // Para Mari Carmen
char Clave4[15]={"32165498732165"}; // Clave de un solo uso
char Clave5[15]={"32112346549878"}; // Clave de un solo uso
char 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
/************************************************************************/
/************
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
cerrada
switch(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);
tone(BUZZ,4000);
tone(BUZZ,1000);
tone(BUZZ,4000);
delay(80);
delay(50);
delay(80);
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 cursor
lcd.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 pulsacion
if(key=='0')
estado++; // Cambiamos de menu con el CERO
if(estado>4)estado=1; // Lo hacemos ciclico
switch(estado)
{
case 1: // BORRAR ENTRADAS ERRONEAS
lcd.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 HORA
lcd.setCursor(0,1);
lcd.print(" AJUSTE HORA ");
if(key=='*'){pctime-=3600;}
if(key=='#'){pctime+=3600;}
setTime(pctime);
setTime(pctime);
break;
case 4: // AJUSTAR DIA
lcd.setCursor(0,1);
lcd.print(" AJUSTE DIA ");
if(key=='*'){pctime-=86400;}
if(key=='#'){pctime+=86400;}
setTime(pctime);
break;
}
} // Del si key
} // Del while
lcd.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 error
if (Tecla != oldkey) //new key has been pressed
{
if (Tecla)
{
melodia(4); // Pitidito de pulsacion
exceso_de_tiempo(10, INICIAR);
Clave[posicion_clave]=Tecla;
Clave[posicion_clave+1]=0; // Finalizamos la cadena para evitar errores
if(posicion_clave < 14){ posicion_clave++; }
else{ // Si metemos 15 num y no hay clave hay que esperar
posicion_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 puerta
}
}
return NO; // Tiempo de espera no excedido
}
/************************************************************************/
/* Pintamos horas de eventos especificos */
/************************************************************************/
void pinta_reloj_eventos(){
int dia;
dia=weekday(TiempoError);
lcd.setCursor(0,1); // Situamos el cursor
if(hour() < 10) lcd.print('0');
lcd.print(hour(TiempoError));
printDigits(minute(TiempoError));
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 del void pinta_reloj_eventos()
/******************************************************************/
/**
Encendemos y apagamos la luz de la entrada
**/
/**
La luz se apaga con 20seg de reatraso
**/
/** Tambin cerramos la cerradura a los 20 seg de cerrar puerta **/
/******************************************************************/
void luz_puerta(char estado)
{
static time_t horaX=0;
if(estado){
//GPIO_WriteHigh(GPIOA, GPIO_PIN_3); // Encendemos luz
horaX=now(); // Empezamos a contar (cada vez que pasemos por aqui, empezamos a contar)
}else{
// Si el estado es NO, nos preparamos para apagar y cerrar
if((horaX) && (now() > (horaX+20))){
//GPIO_WriteLow(GPIOA, GPIO_PIN_3); //Apagar luz
cerrar_puerta();
horaX=0; // Reiniciamos el contador
}
} // Del else
}
Example
1.
#include <Password.h>
2.
3.
Password password = Password( "1234" );
4.
5.
void setup(){
6.
Serial.begin(9600);
7.
8.
password.append('1');//add 1 to the guessed password
9.
password.append('2');//add 2 to the guessed password
10.
password.append('3');//add 3 to the guessed password
11.
password.append('4');//add 4 to the guessed password
12.
//should print true, since 1234 == 1234
13.
Serial.println( password.evaluate()?"true":"false" );
14.
15.
password.reset(); //reset the guessed password to NULL
16.
//should print false, since 1234 != NULL
17.
Serial.println( password.evaluate()?"true":"false" );
18.
19.
password.set("qwerty"); //set target password to qwerty
20.
//should print true, since qwerty == qwerty
21.
Serial.println( password.is("qwerty")?"true":"false" );
22.
//should print false, since qwerty != qwirty
23.
Serial.println( password.is("qwirty")?"true":"false" );
24.
}
25.
26.
void loop(){/*nothing to loop*/}
Prologo.
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.
La mayora de los LCD paralelos son muy similares, usan chips de interfaz estndar en
la industria (como el HD44780 o HD44100) para la asignacin de pines, a menudo son
idnticos.
1
2
3
4
5
6
7
8
9
10
#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.
?
1
2
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
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:
?
1
2
1
2
3
4
5
6
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
librera keypad representados
por keypad.setHoldTime y keypad.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:
?
1
2
3
4
5
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 rutina void correctPIN() que, se ejecutar en el caso
de haber coincidencia, es decir:
?
1
2
1
2
Se ha incluido una rutina para activar un sistema (en este caso, visual) para activar un
LED en su caso. Con void 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 a char 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 de if (key != NO_KEY), en la cual permanecer la
ejecucin del programa, esperando a que se produzca una entrada. As que, este es el
listado:
?
1
2
Le sigue la funcin switch (key) que es capaz de detectar la tecla que se ha pulsado.
Cuando se produce una entrada del teclado, se guarda en la variable attempt, lo
reconoce y evala con PIN[] 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 subrutina incorrectPIN(); y
cuando termina, vuelve hasta la lnea: for (int zz=0; zz<6; zz++) // borrar tentativa, para
borrar la tentativa actual.
En ltimo lugar est el lazo o loop() que, en este caso, contiene la llamada
a readKeypad();que ejecutar continuamente.
Veamos un primer ejemplo, este es el cdigo para el programa de reconocimiento de
clave:
Nmero PIN
?
//
// pin_clave.pde - keypad switch con seis-digitos para el PIN
// basado en un programa de: http://tronixstuff.wordpress.com/
/* Usando el actual ejemplo de hardware se pueden activa algo o
desactivar mediante el teclado - emulando lo que se puede
encontrar en algunos sistemas de alarma y as sucesivamente.
Nuestro objetivo con este ejemplo es muy simple. El sistema
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
}
void checkPIN()
{
int correct=0;
for (int q=0; q<=5; q++)
{
if (attempt[q]==PIN[q])
{ correct++;
}
}
if (correct==6)
{ correctPIN();
} else
{ incorrectPIN();
}
for (int zz=0; zz<6; zz++) // borrar tentativa
{ attempt[zz]=0;
}
}
void readKeypad()
{
char key = keypad.getKey();
if (key != NO_KEY)
{
switch(key)
{
case '*': z=0;
Serial.println(" ");
break;
case '#': delay(50);
Serial.println(" ");
checkPIN();
break;
default: attempt[z]=key; z++;
}
Serial.print("*");
led();
}
}
void loop()
{
readKeypad();
}
Este cdigo, es susceptible de ser modificado y mejorado, sin duda. Por ese motivo,
vamos a seguir en nuestro empeo en descubrir nuevos modos de lograr ese resultado
e incluso mejorarlo. A continuacin, veremos otra forma de enfocar el proyecto para
lograr el mismo resultado.
seguridad que, incluya una clave de 6 o ms dgitos. Veamos los pasos a seguir, para
comprender cmo lograrlo.
EL CIRCUITO.
En primer lugar, presento el esquema electrnico es muy sencillo, a pesar de los cables
que necesita utilizar para el conexionado de los distintos componentes. Se adjunta el
archivo Fritzing, aunque lleva pequeas modificaciones (el teclado y el PCF8574 son de
mi creacin).
Como
previsiblemente se van a necesitar muchos puertos del Arduino, he pensado en aplicar
un expansor de puertos, para actualizar y refrescar conocimientos, se puede leer
El cdigo.
El siguiente es el cdigo del segundo ejemplo, en este listado, he introducido unos
cambios que permitirn una mayor flexibilidad, en el especto de margen de clave a
utilizar, gracias a usar la librera Password que, nos facilita esta labor a la hora de crear
y comparar una matriz de n dgitos.
La idea es la misma descrita en el ejemplo anterior. La inclusin de un LCD, para su
control, hace necesario el uso de la librera LiquidCrystal, por supuesto, tambin hace
falta usar las libreras incluidas en el ejemplo anterior que, no es necesario repetir.
Un punto a resaltar es que debido a que necesitamos ms puertos del Arduino, en este
caso, vamos a utilizar las entradas analgicas como entradas digitales, esto es posible
si los declaramos con el numeral que le corresponde, es decir, en Arduino, los pines
digitales normalmente, van del pin0 al pin13. Segn el playground de Arduino:
?
1
2
3
4
5
6
7
8
9
10
Mapeo de Pins.
Los pines de Arduino correspondientes a los pines analgicos son desde el 14
al 19.
Observa que esto son pines de Arduino y no corresponden con los nmeros
de los pines fsicos del chip Atmega. Los pines analgicos, pueden usarse
de manera idntica que los digitales, as que por ejemplo, podras ver un
cdigo como este para configurar un pin analgico, y establecerlo a HIGH:
pinMode(14, OUTPUT);
digitalWrite(14, HIGH);
Aqu, usaremos los siguientes, del pinA0 por pin14 a pinA3 por pin17, procurando no
utilizar los pines analgicos pinA4 y pinA5, por si se emplean en algn momento como
E/S I2C.
?
byte rowPins[ROWS] = {5, 4, 3, 2}; // pines a conectar los row del teclado.
2 byte colPins[COLS] = {16, 15, 14}; // AN0, AN1 y AN2. Por falta de pines
3 const int buttonPin = 6; // para los rels mediante una R de 10k y un
4 transistor NPN
5 int sal1 = 17; // pin A4 salida a rele
int sal2 = 18; // pin A5 salida a rele
/* password_lcd.pde
Basado en artculos de la red.
Modificado y adaptado el 07.11.2011 por V. Garcia.
Para hispavila.com Utilizamos las libreras:
[Password.h LiquidCrystal.h Keypad.h] que puede
encontrar en:
http://www.hispavila.com/3ds/atmega/clavenum.html
Usando el actual ejemplo de hardware se pueden activa
algo o desactivar mediante el teclado - emulando lo
que se puede encontrar en algunos sistemas de alarma y
as sucesivamente. Nuestro objetivo con este ejemplo
es muy simple. Un sistema de espera para obtener un PIN
que se especifique previamente. Si el PIN es correcto,
hacer algo. Si el PIN es incorrecto, hacer otra cosa.
Lo que las acciones pueden llegar a hacer. Con el proyecto
vamos a activar o desactivar una salida digital.
Este ejemplo es para darle un concepto y un marco para
adaptar o construir ideas propias.
Usa 4654 bytes con el IDE v. 00013
*/
#include <Password.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); Password
password = Password( "1234456" ); // aqu puede poner su pasword
const byte ROWS = 4; // Cuatro rows
const byte COLS = 3; // Tres columns
// Define el Keymap
char keys[ROWS][COLS] = {
{'1','2','3',},
{'4','5','6',},
{'7','8','9',},
{'*','0',' ',} };
// Conectar keypad ROW0, ROW1, ROW2 y ROW3 a los pines de Arduino.
byte rowPins[ROWS] = {5, 4, 3, 2}; // pines a conectar los row del teclado.
byte colPins[COLS] = {16, 15, 14}; // AN0, AN1 y AN2. Por falta de pines
const int buttonPin = 6; //
int buttonState = 0;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
int i;
int sal1 = 17; // pin A4 salida a rele
int sal2 = 18; // pin A5 salida a rele
// Crear el Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
#define ledPin 13
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(sal1, OUTPUT);
pinMode(sal2, OUTPUT);
pinMode(ledPin, OUTPUT);
lcd.begin(20, 4);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
keypad.addEventListener(keypadEvent); //aad. un evento listener para el
keypad
keypad.setDebounceTime(250);
lcd.clear();
//Borra el LCD
lcd.setCursor(0,0);
lcd.print("Entre secuencia PIN:");
lcd.setCursor(2,2);
lcd.print("* Para terminar");
lcd.setCursor(0,3);
lcd.print(" Intentelo: ");
}
void loop()
{
keypad.getKey();
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
{
lcd.clear();
}
}
// atender algunos eventos especiales
void keypadEvent(KeypadEvent eKey)
{
switch (keypad.getState())
{ case
PRESSED: lcd.print(eKey);
switch (eKey)
{
case ' ': guessPassword();
break;
default: password.append(eKey);
}
}
}
void guessPassword()
{
if (password.evaluate())
{
digitalWrite(ledPin,HIGH); // activa el LED de la puerta .5 seg.
delay(500);
digitalWrite(ledPin,LOW); // desactiva LED de la puerta
digitalWrite(sal1, HIGH); // activa rel1 de la puerta
digitalWrite(sal2, LOW); // desactiva rel2 de la puerta
lcd.clear();
lcd.setCursor(0,0);
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
A estas subrutinas, se les ha incluido unos mensajes que, estn acordes en cada caso,
para hacer comprender al usuario, la situacin que impera en cada momento. De modo
que al iniciar el proceso, rige un mensaje que invita a introducir un nmero PIN y la
forma de hacer su entrada mediante la pulsacin de la tecla * (asterisco), como
confirmacin del PIN introducido.
Mediante la librera Pasword, se evala el PIN introducido y se produce un destello de
un LED por un corto perodo de tiempo 1/2 segundo cuando hay coincidencia con la
clave correcta. En ese momento, el mensaje que muestra la pantalla LCD, cambia a un
nuevo mensaje que, le indica al usuario que ha obtenido el acceso y termina el
proceso.
En este
diseo, para mayor claridad, no se han incluido los rels y los componentes asociados
para su control.
Nota.- En estos ejemplos, se utilizado un LCD de 204, sin duda que el usuario, puede
adaptar otro tipo de LCD, modificando los pines que se dedican al control de cada tipo
de LCD.
string
Descripcin
Los strings se representan como arrays de caracteres (tipo char)
que terminan con el caracter NULL.
Ejemplos
Todas las siguientes son declaraciones vlidas de strings.
char
char
char
char
char
char
Str1[15];
Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
Str4[ ] = "arduino";
Str5[8] = "arduino";
Str6[15] = "arduino";
Arrays de strings
valor = EEPROM.read(a);
Serial.print(a);
Serial.print("\t");
Serial.print(value);
Serial.println();
a = a + 1;
if (a == 512)
a = 0;
delay(500);
}
#include <EEPROM.h>
void setup()
{
for (int i = 0; i < 512; i++)
EEPROM.write(i, i);
}
void loop()
{
}
toCharArray().
getChars()
en vez de la
This example is for Wiring version 1.0 build 0100+. If you have a previous version, use the examples
included with your software. If you see any errors or have comments, please let us know.
DynamicKeypad by BREVIG http://alexanderbrevig.com
*** THE KEYPAD REQUIRES PULL-UP RESISTORS ON THE ROW PINS. *** * This is a demonstration of
keypadEvents. It's used to switch between keymaps while using only one keypad. The main concepts being
demonstrated are: Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding. How to use
setHoldTime() and why. Making more than one thing happen with the same key. Assigning and changing
keymaps on the fly.
Another useful feature is also included with this demonstration although it's not really one of the concepts
that I wanted to show you. If you look at the code in the PRESSED event you will see that the first section of
that code is used to scroll through three different letters on each key. For example, pressing the '2' key will
step through the letters 'd', 'e' and 'f'.
Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding Very simply, the PRESSED event
occurs imediately upon detecting a pressed key and will not happen again until after a RELEASED event.
When the HOLD event fires it always falls between PRESSED and RELEASED. However, it will only occur if a
key has been pressed for longer than the setHoldTime() interval.
How to use setHoldTime() and why Take a look at keypad.setHoldTime(500) in the code. It is used to set the
time delay between a PRESSED event and the start of a HOLD event. The value 500 is in milliseconds (mS)
and is equivalent to half a second. After pressing a key for 500mS the HOLD event will fire and any code
contained therein will be executed. This event will stay active for as long as you hold the key except in the
case of bug #1 listed above.
Making more than one thing happen with the same key. If you look under the PRESSED event (case
PRESSED:) you will see that the '#' is used to print a new line, Serial.println(). But take a look at the first
half of the HOLD event and you will see the same key being used to switch back and forth between the letter
and number keymaps that were created with alphaKeys[4][5] and numberKeys[4][5] respectively.
Assigning and changing keymaps on the fly You will see that the '#' key has been designated to perform two
different functions depending on how long you hold it down. If you press the '#' key for less than the
setHoldTime() then it will print a new line. However, if you hold if for longer than that it will switch back and
forth between numbers and letters. You can see the keymap changes in the HOLD event.
In addition... You might notice a couple of things that you won't find in the Arduino language reference. The
first would be #include . This is a standard library from the C programming language and though I don't
normally demonstrate these types of things from outside the Arduino language reference I felt that its use
here was justified by the simplicity that it brings to this sketch. That simplicity is provided by the two calls to
isalpha(key) and isdigit(key). The first one is used to decide if the key that was pressed is any letter from az or A-Z and the second one decides if the key is any number from 0-9. The return value from these two
functions is either a zero or some positive number greater than zero. This makes it very simple to test a key
and see if it is a number or a letter. So when you see the following:
if (isalpha(key)) // this tests to see if your key was a letter
And the following may be more familiar to some but it is equivalent:
if (isalpha(key) != 0) // this tests to see if your key was a letter
And Finally... To better understand how the event handler affects your code you will need to remember that
it gets called only when you press, hold or release a key. However, once a key is pressed or held then the
event handler gets called at the full speed of the loop().
*** THE KEYPAD REQUIRES PULL-UP RESISTORS ON THE ROW PINS. ***
#include <Keypad.h>
#include <ctype.h>
char alphaKeys[4][3] = {
{ 'a','d','g' },
{ 'j','m','p' },
{ 's','v','y' },
{ ' ','.','#' }
};
char numberKeys[4][3] = {
{ '1','2','3' },
{ '4','5','6' },
{ '7','8','9' },
{ ' ','0','#' }
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these pins, eg. ROW0 = Arduino pin2.
byte rowPins[] = { 9, 8, 7, 6 };
// Connect keypad COL0, COL1 and COL2 to these pins, eg. COL0 = Arduino pin6.
byte colPins[] = { 12, 11, 10 };
void setup() {
Serial.begin(9600);
digitalWrite(ledPin, HIGH);
LED on.
// Turns the
keypad.addEventListener(keypadEvent);
event listener.
// Add an
keypad.setHoldTime(500);
is 1000mS
// Default
keypad.setDebounceTime(250);
is 50mS
// Default
void loop() {
char key = keypad.getKey();
if (alpha) {
digitalWrite(ledPin,!digitalRead(ledPin));
delay(100);
}
}
switch (keypad.getState())
{
case PRESSED:
keymap.
if (isalpha(key)) {
characters.
if (physKey != key) {
pressCount = 0;
virtKey = key;
physKey = key;
}
else {
virtKey++;
pressCount++;
}
if (pressCount > 2) {
pressCount = 0;
virtKey = key;
}
Serial.print(virtKey);
}
if (isdigit(key) || key == ' ' || key == '.')
if (key == '#')
Serial.print(key);
Serial.println();
break;
case HOLD:
if (key == '#')
letters
if (alpha == true)
keypad.begin(*numberKeys);
alpha = false;
}
else
numbers
keypad.begin(*alphaKeys);
alpha = true;
}
}
else
case RELEASED:
if (buildCount >= sizeof(buildStr))
Start fresh.
buildCount = 0;
break;
}
}
// end switch-case
string
Description
Text strings can be represented in two ways. you can use the String
data type, which is part of the core as of version 0019, or you can
make a string out of an array of type char and null-terminate it.
This page described the latter method. For more details on the
String object, which gives you more functionality at the cost of more
memory, see the String object page.
Examples
All of the following are valid declarations for strings.
char
char
char
char
char
char
Str1[15];
Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
Str4[ ] = "arduino";
Str5[8] = "arduino";
Str6[15] = "arduino";
Arrays of strings
It is often convenient, when working with large amounts of text,
such as a project with an LCD display, to setup an array of strings.
Because strings themselves are arrays, this is in actually an
example of a two-dimensional array.
In the code below, the asterisk after the datatype char "char*"
indicates that this is an array of "pointers". All array names are
actually pointers, so this is required to make an array of arrays.
Pointers are one of the more esoteric parts of C for beginners to
understand, but it isn't necessary to understand pointers in detail to
use them effectively here.
Example
char* myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};
void setup(){
Serial.begin(9600);
}
void loop(){
for (int i = 0; i < 6; i++){
Serial.println(myStrings[i]);
delay(500);
}
}
Funciones.
Ejemplo
Otro ejemplo:
Esta funcin leer un sensor cinco veces con analogRead() y
calcular la media de las cinco lecturas. Escala los datos a 8 bits (0255), los invierte y devuelve el resultado invertido.
int ReadSens_and_Condition(){
int i;
int sval;
for (i = 0; i < 5; i++){
sval = sval + analogRead(0);
}
PROGMEM
Sintaxis
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
Ejemplo
En el siguiente cdigo se indica cmo leer y escribir caracteres sin
signo (bytes) y enteros (2 bytes) en PROGMEM.
#include <avr/pgmspace.h>
// guardar enteros sin signo
PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};
// guardar caracteres
prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED
BY THE UNITED STATES DEPART"};
unsigned int displayInt;
int k; // variable contador
char myChar;
=
=
=
=
=
=
"String
"String
"String
"String
"String
"String
string_3,
string_4,
string_5 };
char buffer[30];
void setup()
{
Serial.begin(9600);
}
void loop()
{
/* La funcin strcpy_P copia un string del espacio de programa a un string en RAM
("buffer").
Hay que asegurarse de que el string en RAM es suficientemente grande para recibir el
dato. */
for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Casts necesarios e
inferencia
Serial.println( buffer );
delay( 500 );
}
}
The String functions charAt() and setCharAt() are used to get or set the value of a character at
a given position in a String.
At their simplest, these functions help you search and replace a given character. For example, the
following replaces the colon in a given String with an equals sign:
String reportString = "SensorReading: 456";
int colonPosition = reportString.indexOf(':');
reportString.setCharAt(colonPosition, '=');
[Get Code]
Here's an example that checks to see if the first letter of the second word is 'B':
String reportString = "Franklin, Benjamin";
int spacePosition = reportString.indexOf(' ');
if (reportString.charAt(spacePosition + 1) == 'B') {
Serial.println("You might have found the Benjamins.")
}
[Get Code]
Caution: If you try to get the charAt or try to setCharAt() a value that's longer than the
String's length, you'll get unexpected results. If you're not sure, check to see that the position you
want to set or get is less than the string's length using the length() function.
Hardware Required:
Arduino Board
Circuit
There is no circuit for this example, though your Arduino must be connected to your computer
via USB.
image developed using Fritzing. For more circuit examples, see the Fritzing project page
Code
/*
String charAt() and setCharAt()
Examples of how to get and set characters of a String
created 27 July 2010
modified 2 Apr 2012
by Tom Igoe
http://arduino.cc/en/Tutorial/StringCharacters
This example code is in the public domain.
*/
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("\n\nString
}
void loop() {
// make a string to report a sensor reading:
String reportString = "SensorReading: 456";
Serial.println(reportString);
// the reading's most significant digit is at position 15 in the
reportString:
char mostSignificantDigit = reportString.charAt(15);
Serial.println("Most significant digit of the sensor reading is:
" + mostSignificantDigit);
// add blank space:
Serial.println();
// you can alo set the character of a string. Change the : to a =
character
reportString.setCharAt(13, '=');
Serial.println(reportString);
// do nothing while true:
while(true);
}
search and replace substrings, and more. This tutorial shows you
how to initialize String objects.
String stringOne = "Hello String";
// using a
constant String
String stringOne = String('a');
// converting a
constant char into a String
String stringTwo = String("This is a string");
// converting a
constant string into a String object
String stringOne = String(stringTwo + " with more");// concatenating
two strings
String stringOne = String(13);
// using a
constant integer
String stringOne = String(analogRead(0), DEC);
// using an int
and a base
String stringOne = String(45, HEX);
// using an int
and a base (hexadecimal)
String stringOne = String(255, BIN);
// using an int
and a base (binary)
String stringOne = String(millis(), DEC);
// using a long
and a base
[Get Code]
All of these methods are valid ways to declare a String object. They
all result in an object containing a string of characters that can be
manipulated using any of the String methods. To see them in action,
upload the code below onto an Arduino and open the Serial Monitor.
You'll see the results of each declaration. Compare what's printed by
each println() to the declaration above it.
Hardware Required
Arduino Board
Circuit
image developed using Fritzing. For more circuit examples, see the Fritzing
project page
Code
/*
String constructors
Examples of how
// send an intro:
Serial.println("\n\nString Constructors:");
Serial.println();
}
void loop() {
// using a constant String:
String stringOne = "Hello String";
Serial.println(stringOne);
// prints "Hello String"
// converting a constant char into a String:
stringOne = String('a');
Serial.println(stringOne);
// prints "a"
// converting a constant string into a String object:
String stringTwo = String("This is a string");
Serial.println(stringTwo);
// prints "This is a string"
// concatenating two strings:
stringOne = String(stringTwo + " with more");
// prints "This is a string with more":
Serial.println(stringOne);
// using a constant integer:
stringOne = String(13);
Serial.println(stringOne);
// prints "13"
Serial.println(stringOne);
// do nothing while true:
while(true);
}