Control de acceso, Arduino + wifi + php + javascript + MySql - chujalt - 05-03-2021
Saludos....
Os voy a mostrar como hacer un control de acceso vía Wifi utilizando la placa arduino, mas un poco de código php, javascript y base de datos Mysql. De esta manera podemos loguearnos desde cualquier dispositivo que este conectado a internet, un pc, una tablet, un teléfono, etc, sin necesidad de que nuestra placa Arduino este conectada por cable a nuestro PC.
Materiales utilizados:
- Una Placa Arduino (yo he utilizado la nano)
- Un módulo wifi HLK-RM04
- 12 cables dupont
- Una pantalla lcd I2C 16X2
- Un módulo led rgb
Conexiones:
- Pin SCL del lcd --> Pin A5 de Arduino
- Pin SDA del lcd --> Pin A4 de Arduino
- Pin VCC del lcd --> Pin 5 voltios de Arduino
- Pin GND del lcd --> Pin GND de Arduino
- Pin V-G del led -->Pin GND de Arduino
- Pin R del led --> Pin 11 de Arduino
- Pin G del led --> Pin 10 de arduino
- Pin B del led --> Pin 9 de Arduino
- Pin Rx del módulo HLK-RM04 --> Pin Tx de Arduino
- Pin Tx del módulo HLK-RM04 --> Pin Rx de Arduino
- Pin GND del módulo HLK-RM04 --> Pin GND de Arduino
- Pin 5v del módulo HLK-RM04 --> Pin 5v de Arduino
Software necesario:
- El código para Arduino (se mostrará mas abajo).
- Una página php para introducir el código y verificarlo (se mostrará mas abajo).
- Una página php para conectar con la base de datos donde están los usuarios y los códigos de acceso (se mostrará mas abajo).
- Una base de datos Mysql donde se guardarán los usuarios y los códigos de acceso (se explicará mas abajo).
El sistema lo que hace es mostrar en la pantalla del lcd la frase "ESPERANDO DATOS" mientras el led está en color azul parpadeante.
Cuando ponemos desde la página web el código, si éste es correcto la pantalla lcd muestra "Saludos + nombre de usuario" y el led se pone de color verde. Si el código es incorrecto, no existe, la pantalla muestra "Sin acceso. Código erroneo" y muestra el led de color rojo. A los 5 segundos se reseatea y vuelve a mostrar "ESPERANDO DATOS" con led azul parpadeante.
Cabe decir que se puede ampliar para que, por ejemplo, accione un relé para abrir una puerta o lo que se os ocurra.
Código para la placa arduino:
Código: #include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
void setup()
{
Serial.begin(57600);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
lcd.begin(16,2);
lcd.backlight();
lcd.setCursor(4,0);
lcd.print("ESPERANDO");
lcd.setCursor(6,1);
lcd.print("DATOS");
while(!Serial.available()) {
digitalWrite(bluePin, HIGH);
delay(500);
digitalWrite(bluePin, LOW);
delay(500);
}
}
String f = "";
void loop()
{
boolean has_request = false;
String in = "";
if (Serial.available()) {
in = "";
while (true) {
while (Serial.available() == false) {}
in += (char)(Serial.read());
if (in.endsWith("\r\n")) {
has_request = true; break;
}
}
}
if (has_request) {
char i1 = in.indexOf("GET /mensaje?f="), i2;
if (i1 != -1) {
i2 = in.indexOf(" ", i1+15);
f = in.substring(i1+15, i2);
}
if (f == "aaa")
{
lcd.clear();
lcd.setCursor(3,0);
lcd.print("SIN ACCESO");
lcd.setCursor(1,1);
lcd.write("CODIGO ERRONEO");
digitalWrite(bluePin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(redPin, HIGH);
pagina();
}
else
{
lcd.clear();
lcd.setCursor(4,0);
lcd.print("SALUDOS");
lcd.setCursor(1,1);
f.replace("+", " ");
lcd.print(f);
digitalWrite(bluePin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(redPin, LOW);
pagina();
}
has_request = false;
}
delay(5000);
digitalWrite(greenPin, LOW);
digitalWrite(redPin, LOW);
software_Reset() ;
}
void pagina()
{
Serial.println("HTTP/1.1 200 OK");
Serial.println("Content-Type: text/html");
String sr = "<!DOCTYPE HTML>\n";
sr += "<html>\n";
sr += "<head>\n";
sr += "<meta http-equiv='Refresh' content='0;url=http://192.168.1.11/arduino/wifi/acceso/index.php'>\n";
sr += "</head>\n";
sr += "<body>\n";
sr += "</body>";
sr += "</html>";
Serial.print("Content-Length: ");
Serial.print(sr.length());
Serial.print("\r\n\r\n");
Serial.print(sr);
}
void software_Reset()
{
asm volatile (" jmp 0");
}
Comentario del código:
- Incluimos las librerías necesarias para que todo funcione correctamente.
- Indicamos todos los pines necesarios.
- Iniciamos la comunicación a 57600 baudios.
- Apagamos todos los colores del led y encendemos el lcd.
- Le decimos al lcd que muestre en pantalla "ESPERANDO DATOS" y que el led parpadee en color azul cada medio segundo.
- Si se inicia la comunicación serial y ésta envía "aaa" (previamente enviada por la página php) el lcd imprime "Sin acceso. Código erroneo" y el led se pone en rojo fijo.
- Si la página php no envía ese carácter y envía otra cadena, ésta sera el nombre de usuario, que previamente ha sido confirmada desde la base de datos al meter el código, entonces la pantalla de lcd mostrará "Saludos (nombre del usuario)" y el led se pondrá en color verde fijo.
- Una vez recibida la información la placa Arduino mando unos comandos (página web) para que se vuelva a mostrar el teclado (mas abajo imagen).
- Tanto como si el código es bueno o erróneo, a los 5 segundos se resetea y vuelve a mostrar en pantalla "ESPERANDO DATOS" y el led de color azul parpadeante.
Código pagina principal php:
Código PHP: <html> <head> <title>teclado en pantalla</title> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <META name="robots" content="NOINDEX,NOFOLLOW"> <script language="JavaScript" type="text/javascript"> // Comprueba Navegador y Plataforma del pc var clientPC = navigator.userAgent.toLowerCase(); // Coge info cliente var clientVer = parseInt(navigator.appVersion); // Coge versión navegador var is_ie = ((clientPC.indexOf("msie") != -1) && (clientPC.indexOf("opera") == -1)); var is_nav = ((clientPC.indexOf('mozilla')!=-1) && (clientPC.indexOf('spoofer')==-1) && (clientPC.indexOf('compatible') == -1) && (clientPC.indexOf('opera')==-1) && (clientPC.indexOf('webtv')==-1) && (clientPC.indexOf('hotjava')==-1)); var is_moz = 0; var is_win = ((clientPC.indexOf("win")!=-1) || (clientPC.indexOf("16bit") != -1)); var is_mac = (clientPC.indexOf("mac")!=-1); function imprm(bot) { var txtarea = document.getElementById('ta'); var tecla = new Array('1','2','3','4','5','6','7','8','9','0'); txtarea.value+=tecla[bot]; txtarea.focus(); return; } function imprM(bot) { var txtarea = document.getElementById('ta'); var teclaM = new Array txtarea.value+=teclaM[bot]; txtarea.focus(); return; } var capa1 var capa2 var ns4 = (document.layers)? true:false var ie4 = (document.all)? true:false var ns6 = (document.getElementById)? true:false function teclado() { if (ns4) { capa1 = document.c1 capa2 = document.c2 } if (ie4) { capa1 = c1.style capa2 = c2.style } if (ns6) { capa1 = document.getElementById('c1').style capa2 = document.getElementById('c2').style } } function muestra(obj) { if (ns4) obj.visibility = "show" else if (ie4) obj.visibility = "visible" else if (ns6) obj.visibility = "visible" } function oculta(obj) { if (ns4) obj.visibility = "hide" else if (ie4) obj.visibility = "hidden" else if (ns6) obj.visibility = "hidden" } function borrar() { var txtarea = document.getElementById('ta'); if ((clientVer >= 4) && is_ie && is_win) { var txtSeleccion = document.selection.createRange().text; if (document.selection) { if (!txtSeleccion) { txtarea.focus(); var Sel = document.selection.createRange(); Sel.moveStart ('character', -txtarea.value.length); curPos = Sel.text.length; txtarea.value=txtarea.value.substr(0,txtarea.value.length-1); return(curPos); } txtarea.focus(); var Sel = document.selection.createRange(); document.selection.createRange().text = ""; Sel.moveStart ('character', -txtarea.value.length); curPos = Sel.text.length; return(curPos); } } else if (txtarea.selectionEnd && (txtarea.selectionEnd - txtarea.selectionStart > 0)) { var selLargo = txtarea.textLength; var selEmpz = txtarea.selectionStart; var selFin = txtarea.selectionEnd; var s1 = (txtarea.value).substring(0,selEmpz); var s2 = (txtarea.value).substring(selFin, selLargo); txtarea.value = s1 + s2; return(selEmpz); } else { var selLargo = txtarea.textLength; txtarea.value = txtarea.value.substr(0,txtarea.value.length-1); var Cursor = txtarea.textLength; return(Cursor); } almznaCursor(txtarea); } function almznaCursor(textEl) { if (textEl.createTextRange) textEl.caretPos = document.selection.createRange().duplicate(); } function PosicionCursor(pos) { var txtarea = document.getElementById('ta'); //Firefox if (txtarea .setSelectionRange) { txtarea .focus(); txtarea .setSelectionRange(pos,pos); } else if (txtarea .createTextRange) { var rango = txtarea .createTextRange(); rango.collapse(true); rango.moveEnd('character', pos); rango.moveStart('character', pos); rango.select(); } } function EliminarCaracter() { PosicionCursor(borrar()); } </script> <style type="text/css"> #juan { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); } #andres { position: absolute; left: 50%; top: 70%; transform: translate(-50%, -70%); -webkit-transform: translate(-50%, -70%); } </style> </head> <body onLoad="teclado();"> <div id="juan"> <form method="POST" action=""> <input type="password" id="ta" name="pepe" size="9"><br><br> <div id="c1"> <input type="button" id="1" value="1" onclick="imprm(0);" /> <input type="button" id="2" value="2" onclick="imprm(1);" /> <input type="button" id="3" value="3" onclick="imprm(2);" /><br> <input type="button" id="4" value="4" onclick="imprm(3);" /> <input type="button" id="5" value="5" onclick="imprm(4);" /> <input type="button" id="6" value="6" onclick="imprm(5);" /><br> <input type="button" id="7" value="7" onclick="imprm(6);" /> <input type="button" id="8" value="8" onclick="imprm(7);" /> <input type="button" id="9" value="9" onclick="imprm(8);" /><br> <input type="button" id="10" value="0" onclick="imprm(9);" /> <input type="button" id="eliminar_caracter" value="Borrar" onclick="EliminarCaracter()" style="width:58px; height:20px; text-align:center; font-size:10px;" /> <br><br><input type="submit" id="60" value="ENVIAR" style="width:90px; height:20px; text-align:center; font-size:10px;"/> </div>
</form> </div> <div id="andres"> <? $password = $_POST['pepe']; if(!isset($password)) { echo ""; } else { include("conex.php"); $cons = "select * from usuarios where contraseña='$password'"; $datos = mysql_query($cons,$link); if ($row = mysql_fetch_array($datos,1)) { ?> <SCRIPT LANGUAGE="JavaScript"> window.onload = function() { alert("Enhorabuena <? echo $row["usuario"]; ?>. Tu código es correcto"); }; </SCRIPT> <form name='acceso' action='http://192.168.1.254:8080/mensaje' method='GET'> <input type='hidden' name='f' value= '<? echo $row["usuario"]; ?>'> </form> <SCRIPT LANGUAGE="JavaScript">window.setTimeout(function() { document.acceso.submit(); });</SCRIPT> <? } else { ?> <SCRIPT LANGUAGE="JavaScript"> window.onload = function() { alert("El código de acceso no es correcto."); }; </SCRIPT> <form name='acceso' action='http://192.168.1.254:8080/mensaje' method='GET'> <input type='hidden' name='f' value='aaa'> </form> <SCRIPT LANGUAGE="JavaScript">window.setTimeout(function() { document.acceso.submit(); });</SCRIPT> <? } } ?> </div> </body> </html>
Comentario del código:
- Se crea un teclado numérico para introducir el código de acceso.
- Compara ese código en la base de datos.
- Si existe ese código envía a la placa Arduino el usuario asociado a ese código, mostrando en un alert "Enhorabuena (usuario) tu código es correcto"
- Si no existe ese código envía a la placa Arduino la cadena aaa , mostrando en un alert "El código de acceso no es correcto".
Código pagina conex.php:
Código PHP: <? $link = mysql_connect("localhost" ,"usuario","contraseña") or die("no se da conectado"); mysql_select_db("acceso",$link) or die("no se da seleccionado"); ?>
Este código no necesita comentario.
En relación a la base de datos... se deberá crear una con el nombre "acceso", con una única tabla llamada "usuarios" compuesta por tres campos "id" "usuario" y "contraseña".
Bueno ya está... espero que le sirva a alguien.... Saludos
|