Control de Acceso con RFID-RC522 y KEYPAD MATRIX 4X3

... O no haya entendido la pregunta :blush:
Ahora que veo lo sencillo de la solución, entiendo lo de "intento colar la orden de parar el motor en lugar del retardo de digitalWrite"; pero en serio que (y tal vez a otros también) me despistó. Disculpas, en todo caso, por no haberte pedido una aclaración.

GRACIAS POR RESPONDER!!!!

aunque estoy en un momento de decepción... empiezo a sospechar que con arduino no voy a obtener la estabilidad y seguridad que requiere mi proyecto, porque va a estar dentro de una caja fuerte, mayormente, y si falla hay que taladrar

ya tuve un susto; compré dos tarjetas y después de un día de pruebas me falla el ATMEGA de una de ellas

y ahora, no me funciona el logro del otro día, bueno funciona una sí, una no.

el sistema original lleva dos sensores y un imán en el cerrojo, pero yo lo voy a cambiar a dos imanes y un sensor, para simplificar el código. el retardo de un segundo lo uso para que le dé tiempo al imán a separarse del sensor, hasta que lo alcanza el otro imán. el otro día funcionaba bien pero ahora me ocurre lo siguiente

el comparador de claves funciona perfecto, cuando se mete la clave correcta la primera vez el cerrojo se desplaza, y se para cuando el sensor le dice que tiene que parar. hasta ahí bien. lo malo viene la segunda vez que se mete la clave correcta, el do...while no funciona y el cerrojo se para cuando pasa un segundo. si se mete la clave mal el siguiente ciclo lo rula bien, pero si se mete la clave siempre bien, funciona una sí, una no.

lo que me preocupa es que el otro día funcionaba a la perfección, y desmonté el cableado de prueba para el montaje final y de repente bam bum crash... lo más seguro es que la haya pifiado, porque estuve metiendo varios códigos, del Button, Debounce, StateChangeDetection, DigitalInputPullup... a lo mejor me he dejado una línea que está rompiendo la armonía... luego mirando un manual descubrí el DO-WHILE y eureka...

empezaré de cero y os iré contando, gracias por leerme, un saludo

digitalWrite(13, HIGH);
delay(1000);
do
{
x = digitalRead(9);
digitalWrite(13, HIGH);
} while (x == HIGH);

digitalWrite(13, LOW);

Hola Jucar.
Enhorabuena por tu trabajo y por dejar que los que sabemos menos podamos aprovecharnos un poco a la vez que aprendemos.
El caso es que iba a utilizarlo y me da un error. Este:

#include <SPI.h>
#include <RFID.h>
RFID rfid(10,9); // Pines de conexión del RFID EN ESTA LINEA
char tecla; // Variable para almacenar la tecla pulsada en el KeyPad
//____________________________________
char clave="1234"; // 1234 ES LA CLAVE DE 4 DÍGITOS PARA QUE ABRA CON EL TECLADO. MODIFICAR***
char *introducida="xxxx"; // Para guardar espacio en memoria para la clave que introducimos
int indiceTeclado=0;

Esto es lo que dice:

sketch_dec19b:29: error: 'RFID' does not name a type
sketch_dec19b.ino: In function 'void setup()':
sketch_dec19b:41: error: 'rfid' was not declared in this scope
sketch_dec19b.ino: In function 'void loop()':
sketch_dec19b:52: error: 'rfid' was not declared in this scope
sketch_dec19b:76: error: 'rfid' was not declared in this scope

Gracias de antemano por la ayuda

hola chemamata

o mucho me equivoco o no has descargado la librería para que la instale con el sketch, porque el software arduino no la trae de serie

si no es eso lo siento, mi nivel es muy bajo y es lo único que se me ocurre. suerte

¿Tienes correctamente instalada la librería RFID?
El archivo RFID.h debería aparecer (junto con el resto de los archivos y carpetas de la misma) exactamente en la ruta Arduino\libraries\RFID\RFID.h.
Saludos.

Hola
¿Aguien sabe si con este lector RFID se puede leer el codigo de las tarjetas de metro de valencia o de algun pais? lo digo para usarlas como identificador porque son mas chulas de las blancas.

Gracias

Postéo aquí las conexiones de los pines por si a alguien le hiciesen falta:

Las conexiones del RC-522 son:
MOSI: Pin 11
MISO: Pin 12
SCK : Pin 13
SAD : Pin 10
RST : Pin 9
3.3: Power 3.3
GND: GND

Las del relé son las que puse en otro mensaje de este mismo post en este esquema:

Y el teclado en mi caso es de 12 teclas y 7 conexiones. Las conexiones son de izquierda a derecha:
conexión 1 : pin 8
conexión 2 : pin 6
conexión 3: pin 5
conexión 4: pin 4
conexión 5: pin 3
conexión 6: pin 2
conexión 7: pin A0

Un saludo!!!!

holaaaa, señores tengo un problemón!!!

creo que se me ha cascado la placa, arduino uno r3, pero me lo podrían confirmar??

este es el código que uso, la mayoría calcado de este post, omitiendo la parte del RFID y añadiendo como dije anteriormente el do...while para esperar al sensor. una vez funcionó, pero al día siguiente ya no funcionaba y ocasionalmente ha vuelto a funcionar pero por poco rato, una o dos veces.

el caso es que en el codigo de ejemplo Button la placa me hace una cosa rara. en reposo, con el interruptor abierto el led 13 está encendido, aunque poco, y cuando pulso el interruptor se ilumina más fuerte

tambien usando el codigo de ejemplo DigitalReadSerial me hace una cosa rara, pues abriendo la ventana del monitor serial, hay veces que muestra un 1 sin tocar el interruptor, aunque cuando está mostrando 0 sí reacciona al pulsar el interruptor, mostrando un 1

sacadme de dudas por favor... es arduino uno r3 un pelín malo?? de hecho compré dos tarjetas y el atmega de una ya cascó,

gracias por vuestra atención

// ARDUINO UNO + RFID-RC522 + KEYPAD MATRIX 4X3
//Sketch que, por medio de un relé, activa la apertura de una cerradura eléctrica
//Funciona indistintamente por RFID mediante una tarjeta (o llave tipo moneda) 
//Y tambien introduciendo una secuencia de caracteres determinada en el teclado
// en este ejemplo la clave será "1234" y el caracter # al final.
//La ultima parte del código referente a la apertura con el KeyPad corresponde
//al usuario "Noter" del Foro Arduino.cc. ¡¡Gracias!!


//INICIO CONFIGURACION TECLADO
#include <Keypad.h>
const byte filas=4;
const byte columnas=3;
byte pinsfilas[filas]={5,6,4,3}; //en orden F1,F2,F3,F4
byte pinscolumnas[columnas]={0,1,2};//en orden C1,C2,C3
char teclas[filas][columnas]=
 {
   {'1','2','3'},
   {'4','5','6'},
   {'7','8','9'},
   {'*','0','#'},
 };
Keypad teclado = Keypad(makeKeymap(teclas),pinsfilas,pinscolumnas,filas,columnas);
//FIN CONFIGURACION TECLADO



char tecla; // Variable para almacenar la tecla pulsada en el KeyPad
//____________________________________
char *clave="3366"; // *****1234 ES LA CLAVE DE 4 DÃ?GITOS PARA QUE ABRA CON EL TECLADO. MODIFICAR*********
char *introducida="xxxx"; // Para guardar espacio en memoria para la clave que introducimos
int indiceTeclado=0;
int x = 0;
//____________________________________

void setup()
{ 
 Serial.begin(9600);
 
 pinMode(13,OUTPUT);//Pin que activa el relé de apertura de la puerta
 digitalWrite(13,LOW);
 
}

void loop()
{

    
    
    //INICIO CODIGO APERTURA CON TECLADO
     tecla=teclado.getKey();
     if (tecla != NO_KEY)//si se presionó una tecla
     {
           if (tecla == '9')//si tecleamos el caracter "#" del KeyPad comprobaremos si abrir la puerta, y reiniciaremos clave introducida
           {
                 if (indiceTeclado==4) // Si no hemos introducido cuatro caracteres, ni comprobamos
                 {
                       bool coincide=true;
                       for (int i=0;i<4;i++){
                             if (clave[i]!=introducida[i])
                             {
                                   coincide=false;
                                   Serial.println(" ");
                                   Serial.println("Clave INCORRECTA");
                                   Serial.println(" ");
                                   break; //si uno de los caracteres no coincide, salimos del bucle
                             }     
                       }
                       if (coincide)
                       {
                             Serial.println(" ");
                             Serial.println("Usuario Autorizado. Bienvenido");
                             Serial.println(" ");                          
                             //Activa el Relé mientras el pin 8 es "0"
                    
                    
                    
                    
                             
digitalWrite(13, HIGH); 
delay(1500);
do{
x = digitalRead(9);
digitalWrite(13, HIGH);
delay(50);
} while (x == LOW);
digitalWrite(13, LOW);
                             



                       }
                 }
                 Serial.println();
                 indiceTeclado=0; // Siempre que se pulse 9 "borramos" la clave
           }
           else      // Si la tecla no es 9
           {
                 if (indiceTeclado < 4) // Cuando existan ya cuatro caracteres "pasamos de recibir más"
                 {
                       introducida[indiceTeclado]=tecla; 
                       indiceTeclado++;
                       Serial.print(tecla);
                 }
           }
     }
     //FIN CODIGO APERTURA CON TECLADO
}

si le agregas un display, puedes hacer un menu administrativo, y usar la eeprom para almacenar las claves, y una tarjeta o codigo maestro que es el unico autorizado a cambiar datos.

esa idea mola, pero principalmente estoy atascado en que me falla la detección de fin de carrera del cerrojo, para que pare y se quede cerrado o abierto respectivamente

también había pensado en ponerle un módulo bluetooth y que no hubiera teclado ni display por fuera, todo interno, pero eso es el cuarto o quinto paso y estoy atascado en el primero

gracias por tu aporte

RESUELTO!!!!

no os lo vais a creer pero el problema era del ordenador. el ordenador del trabajo tiene alguna diferencia el la alimentación que suministra por USB, porque en el de casa funciona perfectamente. entre eso y el do while, estaba bloqueadísimo

digitalWrite(13, HIGH);
delay(2000);

do{
digitalRead(2);
delay(10);
digitalWrite(13, HIGH);
}
while (digitalRead(2) == HIGH); //aquí no sirve un LOW haciendo la función inversa con el pulsador

digitalWrite(13, LOW);

estando el código así tal cual, todo va bien. como tengo puesto un pulsador en lugar del senson HALL, si aprieto el pulsador durante los 2 segundos que tardaría el sensor en separarse del imán de final de carrera, el código funciona y el relé está alimentado hasta que el sensor llega al imán de principio de carrera.

creo que ese es el funcionamiento del HALL; hace de interruptor abierto cuando el imán está pegado, y cerrado al separarse. si es al revés, chungo porque en el digitalRead (2) == HIGH no sirve un LOW

bueno a lo mejor no comunico bien jjjeejejee, pero lo sigo intentando

Perdonen que moleste pero alguien podría ayudarme a entender como guardan la clave introducida para compararla con la clave almacenada en el programa

Holaaa soy nuevo en esto y me parece muy interesante tu proyecto pero tengo alguna duda.
El problema lo tengo a nivel de hardware. Yo tambien tengo un keypad, un arduino uno y un rfid rc522. El problema es que mirando el datasheet del lector rfid pone que trabaja a 3.3V. Si arduino trabaja con niveles logicos de 5V. Como has conectado el arduino al lector?? Si lo conectas directamente no podria freir la tarjeta o el arduino?? Muchas gracias de antemano y saludos

amigo en el Arduino hay una salida de 3.3v en la cual puedes conectar tu módulo RFID sin ningún problema.

Y para la coincidencia de la clave:

bool coincide=true;
for (int i=0;i<4;i++){
if (clave_!=introducida*)_
_
{_
_
coincide=false;_
_
Serial.println(" ");_
_
Serial.println("Clave INCORRECTA");_
_
Serial.println(" ");_
_
break; //si uno de los caracteres no coincide, salimos del bucle*_
* } *
* }*
* if (coincide)*
* {*
* Serial.println(" ");*
* Serial.println("Usuario Autorizado. Bienvenido");*
* Serial.println(" "); *
* //Activa el Relé durante X segundos*
* digitalWrite(7, LOW);*
* delay(x);*
* digitalWrite(7, HIGH);*
* }*
----------------------------------------------
Primero declara un "bool coincide" que inicializa con "true" que se mantiene, salvo si se cumple esta condición clave_!=introducida*, si esto es así el bool cambia a "false" e indica que la clave es incorrecta, si es que no es así el acceso es correcto y autoriza el ingreso... espero haber podido aportar en algo amigos :)*_

DE CASUALIDAD NO TENDRAS EL DIAGRAMA DE CONEXION, TENGO UN RFID Y HE UTILIZADO TU CODIGO PERO NO ME ENVIA NINGUN DATO

hola oye vi tu codigo y me parece muy interesanto lo unico que veo es que utilizas la libreria RFID.h.... y pero no la encuentro por ningun lado no se si gustes pasarme esa libreria seria de mucha ayuda gracias

pones en google : Arduino RFID.h y te aparece.
Hay que esforzarse, no decir que la busqué y no la encuentro.

En este sitio de Arduino (este mismo blog) estan todas las librerias. Justamente esta que buscas no esta ahi, pero si en otro sitio de este mismo blog.

Cuando respondas mensajes VIEJOS como este, puede ser que el autor o los interlocutores del momento no respondan. Las notificaciones no estan funcionando bien y esta gente ha dejado (creo yo de estar atenta).

hola a todos el codigo de jukar esta muy bueno no estoy muy puesto en esto estoy empezando pero despues de varias pruebas intento modificar el programa para que registre varias targetas pero no lo consigo.
podria alguien de ustedes decirme como lo hago.
muchas gracias

Buen dia. Tengo un proyecto parecido que me ha costado mucho. Ojala alguien pudiera ayudarme.
Tengo que validar primero el tag y si es valido se debe teclear la contraseña para poder activar el relevador. Si el tag es valido pero la contraseña no, no se activa y cuenta como intento fallido, a los 3 intentos debe salir para validar de nuevo un tag.

#include <SPI.h>
#include <MFRC522.h>
#include <Password.h> //Incluimos la libreria Password
#include <Keypad.h> //Incluimos la libreria Keypad
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define RST_PIN  9    //Pin 9 para el reset del RC522
#define SS_PIN  53   //Pin 10 para el SS (SDA) del RC522
MFRC522 mfrc522(SS_PIN, RST_PIN); ///Creamos el objeto para el RC522

Password password = Password("1A2B3");  //Definimos el Password
int dlugosc = 5;                        //Largo del Password

LiquidCrystal_I2C lcd(0x3F,16,2); //Definimos los pines del LCD
//Creamos las Variables de salida
int buzzer = 10; //Buzzer para clicks
int chicharra =11; //Chicharra de Alarma
int ledVerde = 12; //Led para indicar que es incorrecto
int ledRojo = 13; //Led para indicar que es correcto

int ilosc; //Numero de Clicks
int intento=0;//Numero de intentos

const byte ROWS = 4; // Cuatro Filas
const byte COLS = 4; // Cuatro Columnas

// Definimos el Keymap
char keys[ROWS][COLS] = {
 {'1','2','3','A'},
 {'4','5','6','B'},
 {'7','8','9','C'},
 {'*','0','#','D'}
};

byte rowPins[ROWS] = { 29,28,27,26 };// Conectar los keypads ROW1, ROW2, ROW3 y ROW4 a esos Pines de Arduino.
byte colPins[COLS] = { 25,24,23,22 };// Conectar los keypads COL1, COL2, COL3 y COL4 a esos Pines de Arduino.

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
 Serial.begin(9600); //Iniciamos La comunicacion serial
 SPI.begin();        //Iniciamos el Bus SPI
 mfrc522.PCD_Init(); // Iniciamos el MFRC522
 Serial.println("Control de acceso:");

 keypad.addEventListener(keypadEvent); //Variable con listener con teclado
 
 //Variables de Salida
 pinMode(ledVerde, OUTPUT);
 pinMode(ledRojo, OUTPUT);
 pinMode(buzzer, OUTPUT);
 pinMode(chicharra,OUTPUT);

 digitalWrite(ledRojo, HIGH);
 digitalWrite(ledVerde, LOW);

 lcd.init();
 lcd.backlight();
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Esperando");
 lcd.setCursor(0,1);
 lcd.print("TAG");
}

byte ActualUID[4]; //almacenará el código del Tag leído
byte Usuario1[4]= {0x93, 0x18, 0x7D, 0x9B} ; //código del usuario 1
byte Usuario2[4]= {0x65, 0x0A, 0x9A, 0xC5} ; //código del usuario 2


void loop() {
 int a=0;
 if(a==0){
   keypad.getKey(); //Variable para obtener tecla que se ha presionado
   a++;
   }
 
 // Revisamos si hay nuevas tarjetas  presentes
 if ( mfrc522.PICC_IsNewCardPresent()) 
       {
     //Seleccionamos una tarjeta
           if ( mfrc522.PICC_ReadCardSerial()) 
           {
                 // Enviamos serialemente su UID
                 Serial.print(F("Card UID:"));
                 for (byte i = 0; i < mfrc522.uid.size; i++) {
                         Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
                         Serial.print(mfrc522.uid.uidByte[i], HEX);   
                         ActualUID[i]=mfrc522.uid.uidByte[i];          
                 } 
                 Serial.print("     ");                 
                 //comparamos los UID para determinar si es uno de nuestros usuarios  
                 if(compareArray(ActualUID,Usuario1)){
                   Serial.println("Teclea Pass");
                   a++;
                   checkPassword();
                   return;
                   }
                 else if(compareArray(ActualUID,Usuario2))
                   Serial.println("Acceso concedido...");
                 else
                   Serial.println("Acceso denegado...");
                 
                 // Terminamos la lectura de la tarjeta tarjeta  actual
                 mfrc522.PICC_HaltA();
         
           }
 }
}
void keypadEvent(KeypadEvent eKey)//Se almacenan las teclas presionadas
{
 
 switch (keypad.getState())
 {
   case PRESSED:
  
   int i;
   for( i = 1; i <= 1; i++ )
     {
       digitalWrite(buzzer, HIGH); //Cada que se presiona un tecla suena buzzer 
       delay(200);            
       digitalWrite(buzzer, LOW);  
       delay(100);      
     }    

   switch (eKey)
     {
       //Simula esconder el numero presionado
       default:
       ilosc=ilosc+1;//Incrementa el numero de digitos
       password.append(eKey);
     }
     //Serial.println(ilosc);

     if(ilosc == 1)
       {
         lcd.clear();
         lcd.setCursor(1,0);
         lcd.print("   < NIP >");
         lcd.setCursor(0,1);
         lcd.print("*_");
       }
     if(ilosc == 2)
       {
       lcd.clear();
       lcd.setCursor(1,0);
       lcd.print("   < NIP >");
       lcd.setCursor(0,1);
       lcd.print("**_");
       } 
     if(ilosc == 3)
       {
       lcd.clear();
       lcd.setCursor(1,0);
       lcd.print("   < NIP >");
       lcd.setCursor(0,1);
       lcd.print("***_");
       }
     if(ilosc == 4)
       {
       lcd.clear();
       lcd.setCursor(1,0);
       lcd.print("   < NIP >");
       lcd.setCursor(0,1);
       lcd.print("****_");
       }
     if(ilosc == 5)
       {
       lcd.clear();
       lcd.setCursor(1,0);
       lcd.print("   < NIP >");
       lcd.setCursor(0,1);
       lcd.print("*****_");
       }
     if(ilosc == dlugosc)
       {
       delay(250);
       checkPassword();
       ilosc = 0;
       }
   }
}

void checkPassword()
{
 if(intento>=3)
   {//Si alcanza los 3 intentos fallidos
   digitalWrite(chicharra,HIGH);
   lcd.clear();
   lcd.setCursor(0,1);
   lcd.print("<<NIP INCORRECTO>>");
   lcd.setCursor(1,0);
   lcd.print("ACCESO DENEGADO");
   delay(20000);
   intento=0;
   }
   
 if (password.evaluate())//Si el password es correcto
 {
   int i;
   for( i = 1; i <= 3; i++ )//Suena 3 veces el buzzer
   {
     digitalWrite(buzzer, HIGH);  
     delay(120);            
     digitalWrite(buzzer, LOW);  
     delay(70);      
   }    
   ilosc = 0;
   password.reset();
   
   digitalWrite(ledRojo, LOW);//Led verde enciende indicando que es correcto el password
   digitalWrite(ledVerde, HIGH);

   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("<<NIP CORRECTO>>");
   lcd.setCursor(0,1);
   lcd.print("PUEDE INGRESAR");
   digitalWrite(chicharra, LOW);    

   delay(20000);
   digitalWrite(ledVerde, LOW);
   digitalWrite(ledRojo, HIGH);    
      
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("  **");
   lcd.setCursor(0,1);
   lcd.print("Ingrese NIP");
   intento=0;   

 }  
 else  
 {
   int i;
   for( i = 1; i <= 1; i++ )
   {
     digitalWrite(buzzer, HIGH);  
     delay(300);            
     digitalWrite(buzzer, LOW);  
     delay(100);      
   }  
   ilosc = 0;  
   password.reset();


   digitalWrite(ledVerde, LOW);
   digitalWrite(ledRojo, HIGH);    
            
   lcd.clear();
   lcd.setCursor(0,1);
   lcd.print("<<NIP INCORRECTO>>");
   lcd.setCursor(1,0);
   lcd.print("ACCESO DENEGADO");
   intento++;
   delay(2000);
  
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("  **");
   lcd.setCursor(0,1);
   lcd.print("Ingrese NIP");    
 }
}
//Función para comparar dos vectores
boolean compareArray(byte array1[],byte array2[])
{
 if(array1[0] != array2[0])return(false);
 if(array1[1] != array2[1])return(false);
 if(array1[2] != array2[2])return(false);
 if(array1[3] != array2[3])return(false);
 return(true);
}