Te puede intersar
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
RFID con arduino y raspberry pi + base de datos
Hola en esta entrada mostraremos como hacer un sistema RFID para control de acceso o control de asistencias, para ello haremos uso un arduino con el cual realizaremos la lectura y procesamiento de las tarjetas rfid, una raspberry pi con el cual implementaremos una base de datos en sqlite y recibiremos la información del arduino mediante comunicación serial y un parlante que nos servirá como indicador de acceso.
Vídeo:
Materiales:
- Arduino UNO
- Raspberry pi 3b+
- Modulo RFID RC522
- Parlante con conector rca o para raspberry
- Jumpers
Programando arduino para lectura de RFID:
Empezaremos realizando el código para leer las tarjetas RFID con el modulo RC522 en arduino, pero antes echemos un vistazo a las conexiones necesarios entre el modulo con nuestro arduino.
Primero debemos saber que el modulo RC522 utiliza el protocolo SPI para comunicación, dicho protocolo utiliza 3 pines para su propósito (MOSI , MISO,SCK,SS), de donde el pin SCK define el ciclo de reloj y los pines MOSI y MISO definen la comunicación de maestro a esclavo y de eslavo a maestro respectivamente (en nuestro caso Arduino - modulo RC522) y el pin SS define el dispositivo esclavo.
En arduino los pines descritos en el párrafo anterior se encuentras definidos y los utilizaremos haciendo uso de la librería SPI.h. A continuación mostramos los pines designados para SPI en arduino UNO:
Teniendo claro estos conceptos revisemos las conexiones entre el arduino con el modulo RC522 en la siguiente tabla:
Ahora escribimos el siguiente código en arduino:
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 //Pin 9 para el reset del RC522
#define SS_PIN 10 //Pin 10 para el SS (SDA) del RC522
#define LED 7
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600); //Iniciamos La comunicacion serial
SPI.begin(); //Iniciamos el Bus SPI
mfrc522.PCD_Init(); // Iniciamos el MFRC522
pinMode(7,OUTPUT);
}
byte ActualUID[4]; //almacenará el código del Tag leído
void loop() {
//Enviamos codigo de tarjeta RFID si hay una nueva
enviarCodigoRFID();
//Leemos por el puerto serial valores del raspberry pi
char valor_raspberry = Serial.read();
//Si valor recibido es 'P' encendemos el LED
if(valor_raspberry == 'P' ){
digitalWrite(LED,HIGH);
delay(3000);
digitalWrite(LED,LOW);
}
}
//Envia un codigo RFID en una cadena de 8 caracteres
void enviarCodigoRFID(){ ;
//Limpia la tarjeta rfid anteriormente leiada
limpiarVector();
leerCodigo();
//Si se leyo tarjeta rfid
if(!compararCodigo(ActualUID)){
for(byte i = 0; i < 4; i++){
if(ActualUID[i] <= 15){
Serial.print(0);
Serial.print(ActualUID[i],HEX);
}else{
Serial.print(ActualUID[i],HEX);
}
}
}
}
void limpiarVector(){
for(int i = 0; i<4;i++){
ActualUID[i]=0;
}
}
//Lee el codigo de la tarjeta rfid
void leerCodigo() {
String txt;
// Revisamos si hay nuevas tarjetas presentes
if ( mfrc522.PICC_IsNewCardPresent()){
//Sfeleccionamos una tarjeta
if(mfrc522.PICC_ReadCardSerial()) {
// Enviamos serialemente su UID
for (byte i = 0; i < mfrc522.uid.size; i++){
ActualUID[i]= mfrc522.uid.uidByte[i];
}
//Terminacion de lectura de la tarjeta
mfrc522.PICC_HaltA();
}
}
}
boolean compararCodigo(byte array1[]){
byte array2[]={0,0,0,0};
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);
}
Analizando un poco el código, el arduino se encuentra a la espera de una nueva tarjeta rfid, si se detecta una nueva tarjeta enviara por el puerto serial el código rfid como una cadena de tamaño 8, luego de ello esperara leerá la respuesta del rfid en caso el usuario sea autorizado enviara un carácter 'P' con el cual se encenderá un led en el arduino por 3 segundos.
Creando la base de datos SQLite en raspberry
Continuando con el proyecto necesitamos crear el programa principal que recibira los códigos RFID procesados por el arduino ademas de realizar la validación con la base de datos.
Entonces empezaremos creando la base de datos apoyándonos en DB Browser, el cual instalaremos en nuestra raspberry pi de la ejecutando los siguientes comandos en el CLI :
sudo apt-get update
sudo apt-get install sqlite3
sudo apt-get install sqlite3browser
Una vez finalizada la instalación utilizamos la interfaz gráfica del raspberry OS, si no tienes una pantalla puedes usar un software de escritorio remoto como VNC viewer el cual viene instalado por defecto en raspberry OS por lo que solo debes instalar el programa en tu PC (puedes descargarlo desde AQUI ).
Continuando con el proyecto en nuestro Raspberry OS vamos a inicio > accesorios > DB Browser for SQLITE. Esperamos que cargue el programa y creamos nuestra base de datos en NEW DATABASE, luego vamos a la pestaña de EXECUTE SQL y copiamos el siguiente código:
---Querys de sqlite---
create table usuarios(
rfid varchar(8) not null primary key,
nombre varchar(30) not null,
apellido varchar(40) not null
) ;
create table registro(
evento_id integer not null primary key autoincrement,
user_id varchar(8) not null,
fecha date,
hora time,
constraint fk_usuarios
foreign key (user_id) references usuarios(rfid)
);
También puedes pasar por esta otra ENTRADA en la cual puedes ver como instalar, utilizar y crear bases de datos desde cero de forma simple con DB Browser para SQLITE. O puedes descargar el archivo .db que utilizamos para este proyecto al final en botón de descarga junto con otros archivos.
Continuando ahora volvemos a la linea de comandos y crearemos primero un modulo de python que contendrá el código necesario para interactuar con nuestra base de datos. Primero creamos un nuevo archivo de python con el siguiente comando en la CLI:
sudo nano accesoDB.py
En donde accesoDB.py es el nombre del modulo en mi caso, al ejecutar el comando se nos abrirá el editor de texto en donde escribiremos el código que se muestra a continuación:
import sqlite3
from sqlite3 import Error
from datetime import datetime
def obtenerFecha():
now = datetime.now()
fecha_hoy = str(now.year) + "-" + str(now.month) + "-" + str(now.day)
return fecha_hoy
def obtenerHora():
now = datetime.now()
hora_hoy= str(now.hour) + ":" + str(now.minute)
return hora_hoy
def conectarBD(nombre_db):
conexion = None
try:
conexion = sqlite3.connect(nombre_db)
except Error as e:
print(e)
finally:
if conexion != None:
print('Conexion con base de datos exitosa')
return conexion
def consultarTabla(conexion,tabla='usuarios'):
if conexion != None:
sql = "select * from {0}".format(tabla)
cursor = conexion.cursor()
cursor.execute(sql)
filas = cursor.fetchall()
for fila in filas:
print(fila)
def consultarUsuario(conexion,nombre):
if conexion != None:
try:
sql=("select usuarios.rfid, usuarios.nombre, usuarios.apellido, registro.fecha, registro.hora "
"from usuarios "
"join registro "
"on usuarios.rfid = registro.user_id "
"where usuarios.nombre like \"{0}\"".format(nombre))
cursor = conexion.cursor()
cursor.execute(sql)
filas = cursor.fetchall()
for fila in filas:
print(fila)
except Error as e:
print(e)
def buscarRFID(conexion,rfid):
nombre="Desconocido"
if conexion != None:
cursor = conexion.cursor()
sql = ("select nombre from usuarios"
" where rfid = \"{0}\"".format(rfid))
cursor.execute(sql)
rpta = cursor.fetchone()
nombre = rpta
return nombre
def agregarUsuario(conexion,rfid,nombre,apellido):
if conexion != None:
sql = ("insert into usuarios (rfid,nombre,apellido) "
"values (\"{0}\",\"{1}\",\"{2}\")".format(rfid,nombre,apellido))
cursor = conexion.cursor()
cursor.execute(sql)
conexion.commit()
return True
return False
def agregarRegistro(conexion,user_id,hora,fecha):
if conexion != None:
sql = ("insert into registro (user_id,fecha,hora) "
"values (\"{0}\",\"{1}\",\"{2}\")".format(user_id,hora,fecha))
cursor = conexion.cursor()
cursor.execute(sql)
conexion.commit()
return True
return False
def modificar(conexion,rfid,nombre=' ',apellido=' '):
if conexion != None:
sql = ("update usuarios "
"set nombre = \"{0}\" , apellido=\"{1}\" "
"where rfid = \"{2}\" ".format(nombre,apellido,rfid))
cursor = conexion.cursor()
cursor.execute(sql)
conexion.commit()
return True
return False
#AGREGAR NUEVOS USUARIOS
conn = conectarBD("accesoSSTECH.db")
rpta = agregarUsuario(conn,'rfid','NOMBRE','APELLIDO')
print(rpta)
conn.close()
En este modulo las lineas finales las hemos dejado para ingresar nuevos usuarios, solo debemos cambiar rfid por el tag respectivo al igual que los nombres y apellidos de usuario aunque también podemos hacerlo desde DB BROWSER en browse data.
Ahora crearemos el código principal de nuestro programa con el cual realizaremos la comunicación con el arduino y con la base de datos.Para ello creamos el modulo acceso.py y escribimos el siguiente código:
import serial
import time
import pygame.mixer as mixer
import querysDB as sqliteDB
#Se crea el puerto para comunicacion serial con arduino
arduino = serial.Serial('/dev/ttyACM0',baudrate = 9600)
try:
arduino.open()
except:
print("RFID LISTO")
#Funcion para reproducir archivos de audio. wav
def reproducirAudio(audio):
mixer.init(frequency=22050, size=-16, channels=2, buffer=706)
mixer.music.load(audio)
mixer.music.play()
while mixer.music.get_busy():
continue
# Ciclo principal de ejecucion del programa
while True:
if arduino.inWaiting() > 0:
#Lee si hay un mensaje nuevo por parte del arduino
rpta_rfid = arduino.read(8)
print("TAG RFID: {0}".format(rpta_rfid))
conn = sqliteDB.conectarBD('accesoSSTECH.db')
# Valida el tag rfid
busqueda = sqliteDB.buscarRFID(conn,rpta_rfid)
if(busqueda != None):
#En caso el usuario fue indentificado
print("Usuario reconocido\n")
arduino.write("P")
time.sleep(.5)
reproducirAudio('acceso_permitido.wav')
time.sleep(.5)
fecha = sqliteDB.obtenerFecha()
hora = sqliteDB.obtenerHora()
sqliteDB.agregarRegistro(conn,rpta_rfid,fecha,hora)
time.sleep(.2)
else:
#caso contrario
print("Usuario Desconocido\n")
reproducirAudio('acceso_denegado.wav')
time.sleep(.5)
conn.close()
Adicional mente le agregamos un parlante para reproducir audios de confirmación o denegación al identificar un usuario , esto lo implementamos con la función reproducirAudio() en la cual abrimos un archivo de audio .wav los cuales puedes descargar en el botón de descargar al final de esta entrada. El parlante puede ser cualquiera que tengamos a la mano solo debemos conectarlo al jack 3.5 para audio de nuestra raspberry y listo.
Para finalizar conectamos el puerto serial de nuestro arduino conectado con el modulo RC522 a la raspberry pi al puerto USB, y ejecutamos el comando python acceso.py en la linea de comandos y comenzamos a probar nuestro sistema.
Si queremos ver los registros que valla generando nuestro sistema podemos usar nuevamente DB BROWSER en browse data o podemos crear un nuevo modulo de python y escribir el siguiente codigo:
import querysDB as sqliteDB
conn = sqliteDB.conectarBD('accesoSSTECH.db')
sqliteDB.consultarTabla(conn,'registro')
Listo hemos finalizado por ahora. En este proyecto hemos usado conexión serial entre arduino y raspberry pi aunque no era del todo necesario ya que podríamos a ver usado una raspberry pi solamente para realizar todo el sistema, sin embargo lo realizamos así para poder manejar otros sensores a futuro. En futuras entradas estaremos viendo variantes de este proyecto y algunas mejoras que podemos agregar. Por lo pronto espero que este pequeño proyecto te sirva de ayuda y si tienes alguna duda o sugerencia no dudes en comentarlo, también si tienes alguna variante o mejora a este proyecto que le pueda interesar a los demás también te invito a comentarlo.
Muchas gracias por llegar hasta aquí, hasta la próxima.
DESCARGA DE ARCHIVOS:
Síguenos en nuestras redes:
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Entradas populares
Realizando un interfaz grafica en java para arduino + mq3
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Comentarios
Publicar un comentario