Table of Contents

BerryLocky2_(BYKY2)




By:
Jeilin Crawford Warren.
Pablo Hurtado Granados.

Description

The present project seeks to build an electric latchkey, based on the BYKY prototype realized last semester by Apú, Eduarte and Rincón. This new proposal is divided in two stages. Stage one consist in the foreground analysis of BYKY original version, where the system will access a database through a barcode lector, in addition to that this method will also realize facial recognition (by using open.cv) and RFID. On the other hand, stage two consist in creating graphical applications for computers and cellphones, by using ARCOS-Lab server with internet protocol TCP to enable the data base, additionally a watchdog will be implemented to guard the correct functioning of the system.

Objectives

General

Study access methods and determine which one is more reliable and apply that system to develop a robust final product to comply with requirements requested.

Specifics

Justification

The realization of this project will provide a modern, reliable and effective opening system for the ARCOS-Lab of Escuela de Ingeniería Eléctrica of Universidad de Costa Rica.

What is RapberryPi?

Raspberry Pi is a credit card size computer that can connect to a TV or a keyboard. It is a miniature PC with ARM processor that can be used for many of the things that a desktop PC can do, such as spreadsheets, word processor and video games. In addition, you can play high definition videos. Models A and B are provided solely as plates and exclude OS, power supply, keyboard, casing or cables. The Raspberry Pi has a Broadcom BCM2835 system on a chip (SoC), which includes an ARM1176JZF-S 700 MHz processor (The firmware includes a number of “Turbo” modes so that the user can attempt overclocking, up to 1 GHz, without affecting the warranty), VideoCore IV GPU, and was originally shipped with 256 megabytes of RAM, later upgraded to 512 MB. It does not include a built-in hard disk or solid-state drive, but uses an SD card for booting and long-term storage.
The Raspberry Pi has a 26-pin General Purpose Input/Output (GPIO) connector and this carries a set of signals and buses. There are 8 general purpose digital I/O pins – these can be programmed as either digital outputs or inputs. One of these pins can be designated for PWM output too. Additionally there is a 2-wire I2C interface and a 4-wire SPI interface (with a 2nd select line, making it 5 pins in total) and the serial UART with a further 2 pins.

Installing Raspbian

unzip ~/Downloads/2012-12-16-wheezy-raspbian.zip
umount / dev/sdd1  
sudo dd bs = 4M if = ~ / Downloads/2012-12-16-wheezy-raspbian.img of = / dev / sdd  

RaspberryPi Settings

The configuration of the raspberrypi is very simple if you have already install raspbian, when you start your Pi the display shows the output from each of the start-up scripts. If starting for the first time using a new image you are logged in as a root user, and the raspi-config menu will then appear. It can also be started at any time from the command line:

 $ sudo raspi-config 
info                Information about this tool 
expand_rootfs       Expand root partition to fill SD card 
overscan            Change overscan 
configure_keyboard  Set keyboard layout 
change_pass         Change password for 'pi' user 
change_locale       Set locale 
change_timezone     Set timezone 
memory_split        Change memory split 
ssh                 Enable or disable ssh server 
boot_behaviour      Start desktop on boot? 
update              Try to upgrade raspi-config 
 
    <Select>                    <Finish>

We will focus on four options in this menu, which are described below:

Expand root partition to fill SD card

The usual distribution images are 2 GB. When you copy the image to a larger SD card you have a portion of that card unused. This option expands the initial image to expand to fill the rest of the SD card, giving you more space. You need to reboot the Raspberry Pi to make this available.

Set locale

This option selects the characters and other symbols being displayed on the screen, and is important if you want to use the non-english ones. It is slow to display, while it reads all the locale information. Changes usually take effect immediately, but may require a reboot.
You usually select only the one(s) you want (by pressing space); this will generate the configuration data for all those you select. The default setting is en_GB UTF-8 UTF-8.

Set timezone

This is where you setup your system clock; if it’s wrong it just means the date and time assigned to files you create (automatically when you make them) will be wrong. It is slow to display as there are lots of selections. First you select the continent, then select a City from that continent. You may have to select the one nearest to you.
The Raspberry Pi does not have an onboard clock, so the “clock” stops when you power it off. If you are connected to the internet the Raspberry Pi can be set up to get the time from an online time signal.

Enable or disable ssh server

Enabling ssh will allow you to connect to your Raspberry Pi from another device on your network and use a terminal window remotely. You do not need a monitor or keyboard connected to your Raspberry Pi if you do this.

Software, packages, libraries and dependencies

Zbar

ZBar is an open source software suite for reading bar codes from various sources, such as video streams, image files and raw intensity sensors. It supports many popular symbologies (types of bar codes) including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code. ZBar is licensed under the GNU LGPL 2.1 to enable development of both open source and commercial projects. Some applications are retail, automated document processing, inventory tracking and mobile applications.
It can be installed easily using apt-get install:

$ sudo apt-get install zbartool 

to start zbar just type:

$ zbarcam 

RPi.GPIO

This package provides a class to control the GPIO on a Raspberry Pi. The RPi.GPIO module is installed by default in Raspbian. Any Python script that controls GPIO must be run as root, installing the library is almost as simple, either at a text console or using LXTerminal enter the following 1).

$ wget http://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-0.1.0.tar.gz
$ tar zxf RPi.GPIO-0.1.0.tar.gz
$ cd RPi.GPIO-0.1.0
$ sudo python setup.py install

Pin numbering

There are two ways of numbering the IO pins on a Raspberry Pi within RPi.GPIO. The first is using the BOARD numbering system. This refers to the pin numbers on the P1 header of the Raspberry Pi board. The advantage of using this numbering system is that your hardware will always work, regardless of the board revision of the RPi. You will not need to rewire your connector or change your code.

The second numbering system is the BCM numbers. This is a lower level way of working - it refers to the channel numbers on the Broadcom SOC. You have to always work with a diagram of which channel number goes to which pin on the RPi board. Your script could break between revisions of Raspberry Pi boards.

To specify which you are using using (mandatory):

GPIO.setmode(GPIO.BOARD)
or
GPIO.setmode(GPIO.BCM)

OpenCV (Open Source Computer Vision)

OpenCV (Open Source Computer Vision Library) is an open source computer vision and machine learning software library. OpenCV was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in the commercial products 2). You can use the latest stable OpenCV version available in sourceforge or you can grab the latest snapshot from this Git repository. Getting the Cutting-edge OpenCV from the Git Repository:

cd ~/<my_working _directory>
git clone https://github.com/Itseez/opencv.git

Building OpenCV from Source Using CMake, Using the Command Line:

Create a temporary directory, which we denote as <cmake_binary_dir>, where you want to put the generated Makefiles, project files as well the object files and output binaries.

Enter the <cmake_binary_dir> and type

cmake [<some optional parameters>] <path to the OpenCV source directory>

For example:

cd ~/opencv
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..

Enter the created temporary directory (<cmake_binary_dir>) and proceed with:

make
sudo make install

For the face recognition we used:

 Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>.
 
#include "opencv2/core/core.hpp"
 
#include "opencv2/highgui/highgui.hpp"
 
#include "opencv2/contrib/contrib.hpp"
 
#include <iostream>
 
#include <fstream>
 
#include <sstream>
 
using namespace cv;
 
using namespace std;
 
static Mat toGrayscale(InputArray _src) {
 
Mat src = _src.getMat();
 
if(src.channels() != 1) {
 
CV_Error(CV_StsBadArg, "Only Matrices with one channel are supported");
 
}
 
Mat dst;
 
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
 
return dst;
 
}
 
static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
 
std::ifstream file(filename.c_str(), ifstream::in);
 
if (!file) {
 
string error_message = "No valid input file was given, please check the given filename.";
 
CV_Error(CV_StsBadArg, error_message);
 
}
 
string line, path, classlabel;
 
while (getline(file, line)) {
 
stringstream liness(line);
 
getline(liness, path, separator);
 
getline(liness, classlabel);
 
if(!path.empty() && !classlabel.empty()) {
 
images.push_back(imread(path, 0));
 
labels.push_back(atoi(classlabel.c_str()));
 
}
 
}
 
}
 
int main(int argc, const char *argv[]) {
 
if (argc != 2) {
 
cout << "usage: " << argv[0] << " <csv.ext>" << endl;
 
exit(1);
 
}
 
string fn_csv = string(argv[1]);
 
vector<Mat> images;
 
vector<int> labels;
 
try {
 
read_csv(fn_csv, images, labels);
 
} catch (cv::Exception& e) {
 
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
 
exit(1);
 
}
 
if(images.size() <= 1) {
 
string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
 
CV_Error(CV_StsError, error_message);
 
}
 
int height = images[0].rows;
 
Mat testSample = images[images.size() - 1];
 
int testLabel = labels[labels.size() - 1];
 
images.pop_back();
 
labels.pop_back();
 
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
 
model->train(images, labels);
 
int predictedLabel = model->predict(testSample);
 
string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
 
cout << result_message << endl;
 
model->set("threshold", 0.0);
 
predictedLabel = model->predict(testSample);
 
cout << "Predicted class = " << predictedLabel << endl;
 
Mat eigenvalues = model->getMat("eigenvalues");
 
Mat W = model->getMat("eigenvectors");
 
for (int i = 0; i < min(10, W.cols); i++) {
 
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
 
cout << msg << endl;
 
Mat ev = W.col(i).clone();
 
Mat grayscale = toGrayscale(ev.reshape(1, height));
 
Mat cgrayscale;
 
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
 
imshow(format("%d", i), cgrayscale);
 
}
 
waitKey(0);
 
return 0;
 
} 

APACHE

The Apache HTTP Server Project is an effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows NT. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services in sync with the current HTTP standards, to install do this:

apt-get install apache2
etc/init.d/apache restart

PHP

PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. Instead of lots of commands to output HTML (as seen in C or Perl), PHP pages contain HTML with embedded code that does “something”. The PHP code is enclosed in special start and end processing instructions <?php and ?> that allow you to jump into and out of “PHP mode.” Install:

apt-get install libapache2-mod-php5 php5-cli php5-common php-cgi

MySQL

MySQL is the world's most popular open source database. Whether you are a fast growing web property, technology ISV or large enterprise, MySQL can cost-effectively help you deliver high performance, scalable database applications.MySQL Community Edition is the freely downloadable version of the world's most popular open source database. Install:

apt-get install mysql-client mysql-common mysql-server php5-mysql

MySQL Database

Open a terminal and access MySQL by typing3):

mysql -u nombre_de_usuario_de_mysql -p contraseña_de_mysql

To create a new database, type:

CREATE DATABASE database_name;
CREATE TABLE table_name(data1 not null auto_increment, data2 varchar(100), PRIMARY KEY (data1));
USE table_name;
INSERT INTO table_name (data1,data2) VALUES (value1,value2);

MySQL in Python

MySQLdb

MySQLdb is an interface for working with MySQL databases from Python. To interact with MySQL from Python through MySQLdb, you must install the module. The package name is python-mysqldb:

$ sudo apt-get install python-mysqldb
baseconnect.py
#! /usr/bin/env python
 
import MySQLdb
from pylab import *
 
def CrearBasedeDatos():
    global Cursor
    global Base
    global Acceso_Paso
    Desea=raw_input("Enter para crear la base\n")   
    if Desea == "":
       Base=MySQLdb.connect("localhost","root","something") 
       Cursor=Base.cursor()
       BaseCreada="CREATE DATABASE EFPEM"
       Cursor.execute(BaseCreada)
       Seleccion = "USE efpem"
       Cursor.execute(Seleccion)
       Conexion=True
       if Conexion==True:
          CrearTabla=raw_input("Enter para crear tabla\n")
          if CrearTabla.lower() == "":
             sqlCrearTabla = "CREATE TABLE Alumnos (Carnet varchar(16), \
                                 Nombre varchar(15), Apellido varchar(15),\
                                 Clase1 integer,Clase2 integer,Clase3 integer,\
                                 Clase4 integer,Clase5 integer)" 
             Cursor.execute(sqlCrearTabla)
          print "Base de Datos y Tabla creada con exito!"
          print "Conexion Establecida"
          Acceso_Paso = True: 
    else:
          print "Conexion no establecida"
 
def Conectar():      
    global Cursor
    global Base
    global Acceso_Paso
    Base =MySQLdb.connect("localhost","root","efpem") 
    Cursor=Base.Cursor()
    print "Conectar a la babse EFPEM"
    Acceso_Paso = True 
 
def AgregarDatos():
    if Acceso_Paso == True:
       CantidadAlumnos=int(raw_input("Cuantos alumnos ingresara?"))
       x = 0
       while x < CantidadAlumnos:
           CarneAlumnoint=(raw_input("Ingrese el carne del alumno"))  
           NombreAlumno=(raw_input("Ingrese el nombre del alumno"))
           ApellidoAlumno=(raw_input("Ingrese el apellido del alumno"))
           Nota1=(raw_input("Ingrese la primera nota"))
           Nota2=(raw_input("Ingrese la segunda nota"))
           Nota3=(raw_input("Ingrese la tercera nota"))
           Nota4=(raw_input("Ingrese la cuarta nota"))
           Nota5=(raw_input("Ingrese la quinta nota"))
           sqlInsertar = "INSERT INTO Alumnos(Carne, Nombre, Apellido, Clase1, Clase2, Clase3, Clase4, Clase5)\
                          VALUES('%s','%s','%s','%s','%s','%s','%s','%s')" %\
                          (CarneAlumno, NombreAlumno, ApellidoAlumno, Nota1, Nota2, Nota3, Nota4, Nota5)
           Cursor.execute(sqlInsertar)
           Base.commit()
           x = x+1
    else:
        print "No esta conectado a MySQL"
 
def EliminarBade():
    Base = MySQLdb.connect("localhost","root","")
    Cursor = Base.Cursor()
    NombreBaseGlobal = raw_input("Nombre de la base a eliminar")
    Eliminar = "DROP DATABASE" + str(NombreBaseGlobal)
    Cursor.execute(Eliminar)
    print "base eliminada"
 
def Consulta():
    if Acceso_Paso == True:
       ConsultarAll = "SELECT + FROM Alumnos"
       Cursor.execute(ConsultarAll)
       Datos=Cursor.ferchall()
       if len(Datos) == 0:
           print "Tabla vacia"
       else:   
           for x in range(8):
               for registro in Datos:
                   print "**********", registro[x]
    else:
        print "Solicitud rechazada, no esta conectado a MySQL"
 
def ConsultarPorDato():
    if Acceso_Paso == True:
        CarneNumero = int(raw_input("Ingrese el numero de carne"))
        ConsultarCarne = "SELECT * FROM Alumnos WHERE carne=" + str(CarneNumero) 
        Cursor.execute(ConsultarCarne)
        DatosCarne = Cursor.fetchall()
        for x in range (1):
            for registro in DatosCarne:
                print "Numero de carne", registro[0]
                print "Nombre", registro[1]
                print "Apellido", registro[2]
                print "Nota1:", registro[3]
                print "Nota2:", registro[4]
                print "Nota3:", registro[5]
                print "Nota4:", registro[6]
                print "Nota5:", registro[7]
    else:
        print "Solicitud rechazada, no esta conectado a MySQL"
 
def ConsultarPorNombre():
    if Acceso_Paso == True:
        NombreConsulta = int(raw_input("Ingrese el nombre del alumno"))
        ConsultarNombre = "SELECT * FROM Alumnos WHERE Nombre LIKE=" + "'"+ str(NombreConsulta)+ "%'"
        Cursor.execute(ConsultaNombre)
        DatosNombre = Cursor.fetchall()
        for x in range (1):
            for registro in DatosNombre:
                print "Numero de carne", registro[0]
                print "Nombre", registro[1]
                print "Apellido", registro[2]
                print "Nota1:", registro[3]
                print "Nota2:", registro[4]
                print "Nota3:", registro[5]
                print "Nota4:", registro[6]
                print "Nota5:", registro[7]
    else:
        print "Solicitud rechazada, no esta conectado a MySQL"
 
def ModificarDatos():
    if Acceso_Paso == True:
        CarneAlumnosModificado= raw_input("Ingrese el carne alumno")
        x=1
        Numero=1
        NuevoDato=int(raw_input("Ingrese la nueva nota"))
        modificar='UPDATE Alumnos SET clase'+str(Numero)+'='+str(NuevoDato)+'WHERE Carne='+str(CarneAlumnosModificado)
        Cursor.execute(modificar)
        Numero=Numero+1
        x=x+1
    else:
        print "Solicitud rechazada, no esta conectado a MySQL"   
 
 
def main():
    Eleccion = raw_input('ingrese \n1 \n2 \n3 \n4 \n5 \n6 \n7 \n')
    if Eleccion == "1":
       CrearBasedeDatos()
       main()
    if Eleccion == "2":
       Conectar()
       main()
    if Eleccion == "3":
       AgregarDatos()
       main()
    if Eleccion == "4":
       Consulta()
       main()
    if Eleccion == "5":
       CosultaPorDato()
       main()
    if Eleccion == "6":
       CosultaPorNombre()
       main()
    if Eleccion == "7":
       ModificarDatos()
       main()
    if Eleccion == "":
        print "Fin!"
 
Acceso_Paso = False
main()

Access method using web

In this part of the work we focus on how to authenticate users in php and MySql4), for that you will need to install some tools:

Login

This file allows you to display the Login window, the user enters his username and his password and press send:

index.php
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>.:: Login ::. Autenticar usuarios</title>
 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" href="estilos.css" type="text/css">
    <script src="jquery171.js" type="text/javascript"></script>
    <script src="jquery.validate.js" type="text/javascript"></script>
    <script type="text/javascript" src="jquery.alerts.js"></script>
    <link href="jquery.alerts.css" rel="stylesheet" type="text/css" />
 
    <script type="text/javascript">
    <!--
        $().ready(function() {
            $("#frmlogin").validate();
            $("#usuario").focus();
        });
    // -->
    </script>
    <style>
    body
{
background-image:url('/images/bg4.jpg');
background-repeat:true;
background-attachment:fixed;
background-position:left center;
} 
div.transbox
  {
  width:400px;
  height:200px;
  margin:30px 50px;
  background-color:#ffffff;
  border:1px solid black;
  opacity:0.9;
  filter:alpha(opacity=90); /* For IE8 and earlier */
  }
 
</style>
 
</head>
<body>
<br /><br />
<div class="transbox" style="position: absolute; top: 45%; left: 50%;">
<form id="frmlogin" name="frmlogin"  method="POST" action="validarUsuario.php">
<table align="center" width="200px">
<tr>
    <td colspan="2" align="center"><h3 ">Iniciar sesi&oacute;n</h3></td>
</tr>
<tr>
    <td >Usuario</td>
    <td>
        <input type="text" name="usuario" id="usuario" class="required" maxlength="50">
    </td>
</tr>
 
<tr>
    <td >Password</td>
    <td>
        <input type="password" name="password" id="password" class="required"  maxlength="50">
    </td>
</tr>
<tr >
    <td colspan="2" >
        <a href="recuperarPassword.php">
            Olvide mi contrase&ntilde;a
        </a>
    </td>
</tr>
 
<tr>
    <td colspan="2" align="right">
        <input type="submit" name="enviar" value="Enviar" >
    </td>
 
</tr>
 
<tr>
    <td colspan="2" align="right" >
        <br/><a href="registro.php">Deseo registrarme</a>
    </td>
</tr>
    <?php
 
    //Mostrar errores de validacion de usuario, en caso de que lleguen
 
        if( isset( $_POST['msg_error'] ) )
        {
            switch( $_POST['msg_error'] )
            {
                case 1:
            ?>
            <script type="text/javascript">
                jAlert("El usuario o password son incorrectos.", "Seguridad");
                $("#password").focus();
            </script>
            <?php
                break;         
                case 2:
            ?>
            <script type="text/javascript">
                jAlert("La seccion a la que intentaste entrar esta restringida.\n Solo permitida para usuarios registrados.", "Seguridad");
            </script>
            <?php       
                break;
            }       //Fin switch
        }
 
        //Mostrar mensajes del estado del registro
 
        if( isset( $_POST['status_registro'] ) )
        {
            switch( $_POST['status_registro'] )
            {
                case 1:
                if( $_POST['i_EmailEnviado'] ==1) {
                ?>
                    <script type="text/javascript">
                        jAlert("Gracias, ha sido registrado exitosamente.\n Se le ha enviado un correo electronico de bienvenida, \npor favor, NO LO CONTESTE pues solo es informativo.", 'Registro');
                    </script>
                    <?php
                } else {
                    ?>
                    <script type="text/javascript">
                        jAlert("Gracias, ha sido registrado exitosamente.\n No se le ha podido enviar correo electronico de bienvenida, \nsin embargo, ya puede utilizar sus datos de acceso para iniciar sesion..", 'Registro');
                    </script>
                <?php
                }
 
                    break;         
 
                default:
            ?>
                <script type="text/javascript">
                    jAlert("Temporalmente NO se ha podido registrar, intente de nuevo mas tarde.", "Registro");
                </script>
            <?php       
            }       //Fin switch
        }
    ?>
 
</table>
</form>
</div>
</body>
<img src="../montajemora.png" alt="BerryLocky2" title="BerryLocky2" height="220" width="170" style="position: absolute; top: 5%; left: 10%;">
</html>

Te result of the previous code is show in the next image:

Validate user

This file is in charge of receiving data from the index.php file and compares them against those who are in the database:

validarUsuario.php
<?php
 
    //conectar BD
    include("conectar_bd.php"); 
    conectar_bd();
 
    $usr = $_POST['usuario'];
    $pw = $_POST['password'];
    //Obtengo la version encriptada del password
    $pw_enc = md5($pw);
 
    $sql = "SELECT id_usuario FROM tbl_users
            INNER JOIN ctg_tiposusuario
            ON tbl_users.id_TipoUsuario = ctg_tiposusuario.id_TipoUsuario
            WHERE tx_username = '".$usr."'
            AND tx_password = '".$pw_enc."' "; 
    $result     =mysql_query($sql,$conexio);
 
    $uid = "";
 
    //Si existe al menos una fila
    if( $fila=mysql_fetch_array($result) )
    {      
        //Obtener el Id del usuario en la BD       
        $uid = $fila['id_usuario'];
        //Iniciar una sesion de PHP
        session_start();
        //Crear una variable para indicar que se ha autenticado
        $_SESSION['autenticado']    = 'SI';
        //Crear una variable para guardar el ID del usuario para tenerlo siempre disponible
        $_SESSION['uid']            = $uid;
        //CODIGO DE SESION
 
        //Crear un formulario para redireccionar al usuario y enviar oculto su Id
?>
        <form name="formulario" method="post" action="principal.php">
            <input type="hidden" name="idUsr" value='<?php echo $uid ?>' />
        </form>
<?php
    }
    else {
        //En caso de que no exista una fila...
        //..Crear un formulario para redireccionar al usuario a la pagina de login
        //enviandole un codigo de error
?>
        <form name="formulario" method="post" action="index.php">
            <input type="hidden" name="msg_error" value="1">
        </form>
<?php
    }
?>
 
<script type="text/javascript">
    //Redireccionar con el formulario creado
    document.formulario.submit();
</script>

Database conection

Connection data local variables defined in the conectar_bd () function and then these variables are used as parameters to call the mysql_connect () function, which is what makes the request to connect to the dbms. the function mysql_connect () returns a link that represents the established connection to dbms with this link saved in the variable $conexio the DB to use is selected.

conectar_bd.php
<?php
 
$conexio;
function conectar_bd()
{
    global $conexio;
    //Definir datos de conexion con el servidor MySQL
    $elUsr = "root";
    $elPw  = "password";
    $elServer ="localhost";
    $laBd = "Database";
 
    //Conectar
    $conexio = mysql_connect($elServer, $elUsr , $elPw) or die (mysql_error());
 
    //Seleccionar la BD a utilizar
    mysql_select_db($laBd, $conexio ) or die (mysql_error());
}  
?>

Homepage

This file is the screen that the user sees when logging correctly.

principal.php
 <?php
 
//Inicializar una sesion de PHP
session_start();
 
//Validar que el usuario este logueado y exista un UID
if ( ! ($_SESSION['autenticado'] == 'SI' && isset($_SESSION['uid'])) )
{
    //En caso de que el usuario no este autenticado, crear un formulario y redireccionar a la
    //pantalla de login, enviando un codigo de error
?>
        <form name="formulario" method="post" action="index.php">
            <input type="hidden" name="msg_error" value="2">
        </form>
        <script type="text/javascript">
            document.formulario.submit();
        </script>
<?php
}
 
    //Conectar BD
    include("conectar_bd.php"); 
    conectar_bd();
 
    //Sacar datos del usuario que ha iniciado sesion
    $sql = "SELECT  tx_nombre,tx_apellidoPaterno,tx_TipoUsuario,id_usuario
            FROM tbl_users
            LEFT JOIN ctg_tiposusuario
            ON tbl_users.id_TipoUsuario = ctg_tiposusuario.id_TipoUsuario
            WHERE id_usuario = '".$_SESSION['uid']."'";        
    $result     =mysql_query($sql);
 
    $nombreUsuario = "";
 
    //Formar el nombre completo del usuario
    if( $fila = mysql_fetch_array($result) )
        $nombreUsuario = $fila['tx_nombre']." ".$fila['tx_apellidoPaterno'];
 
//Cerrrar conexion a la BD
mysql_close($conexio);
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>.:: Inicio ::. Pagina Principal</title>
    <link rel="stylesheet" href="estilos.css" type="text/css">
</head>
<style>
    body
{
background-image:url('/images/bg4.jpg');
background-repeat:true;
background-attachment:fixed;
background-position:left center;;
} 
</style>
 
<body topmargin="0" >
<table align="right" width="350px" border="0">
<tr>                                              <!-- Dar Bienvenida al usuario -->
    <td  width="100px" align="right">Bienvenido <b><?php echo $nombreUsuario ?></b></td>
    <td  width="15px" align="center">
        <!-- Proporcionar Link para cerrar sesion -->
        <a href="cerrarSesion.php">Cerrar sesi&oacute;n</a>
    </td>
</tr>
</table>
<br /><br />
<h2 align="center">Bienvenido</h2>
 
<p align="center"> Recuerde cerrar su sesi&oacute;n!</p>
 
<body>
<img src="../montajemora.png" alt="BerryLocky2" title="BerryLocky2" height="220" width="170" style="position: absolute; top: 5%; left: 10%;">
</html> 

The result is shown in the picture below:

Close Session

This file is pointed to by the link “Cerrar Sesión” that is beside the user name (once you have logged). This file will destroy all session variables and end the session, all this is done with PHP functions.

cerrarSesion.php
<?php
 
session_start();
// Destruye todas las variables de la sesion
session_unset();
// Finalmente, destruye la sesion
session_destroy();
 
//Redireccionar a la pagina de login
header ("Location: index.php");
 
?>

Forgot My Password

On the login page the link that says “Olvidé mi contraseña” sends us to recuperarPassword.php file. This file allows you to send a new password to the user, the user should only write the email address and a new nine characters password automatically will be generated and will be sent to this email.

recuperarPassword.php
<?php
 
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>.:: Recuperar Password ::. </title>
 
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <link rel="stylesheet" href="estilos.css" type="text/css">
    <script src="jquery171.js" type="text/javascript"></script>
    <script src="jquery.validate.js" type="text/javascript"></script>
    <script type="text/javascript" src="jquery.alerts.js"></script>
    <link href="jquery.alerts.css" rel="stylesheet" type="text/css" />
 
    <script type="text/javascript">
    <!--
        $().ready(function() {
        $("#recPassword").validate({
        rules: {
        /*A continuacion los nombres de los campos y sus reglas a cumplir */
            correo2: {
            required: true,
            email: true,
            equalTo: "#correo"
            },
            correo: {
            required: true,
            email: true
            }
 
 
        }
        });
        $("#correo").focus();
        });
    // -->
    </script>
 
</head>
<body>
<br /><br />
 
 
<form id="recPassword" name="recPassword"  method="POST" action="recuperarPassword.php">
 
<table align="center" width="400px">
 
<tr>
    <td colspan="2" align="center"><h3><b>Recuperar Password</b></h3></td>
</tr>
 
<?php
//Si llega el parametro correo y no viene vacio
if( isset( $_POST['correo'] ) && $_POST['correo'] != '' )
{
    //Conectar la BD
    include("conectar_bd.php"); 
    conectar_bd();
 
    //Recuperar la direccion de email que llega
    $elcorreo   = $_POST['correo'];
 
    //Verificar si existe el correo en la BD
    $sql = "SELECT  id_usuario,tx_username,tx_nombre,tx_apellidoPaterno
            FROM tbl_users
            WHERE tx_correo = '".$elcorreo."'";        
    $rs_sql = mysql_query($sql);
 
    //Si no existe el correo...
    if ( !( $fila   = mysql_fetch_object($rs_sql) )  )
    {
    //Mostrar msg de error al usuario (en esta misma pagina)
?>
    <input type="hidden" id="error" value="1">           
    <script type="text/javascript">
    location.href="recuperarPassword.php?error="+document.getElementById('error').value;
    </script>
<?php
    }
 
    //En caso de que si exista un email como el k llega, leer de la BD los datos del usuario
    $idusr  = $fila->id_usuario;     //Servira para actualizar el pw
    $nombre = $fila->tx_nombre." ".$fila->tx_apellidoPaterno;
    $nick   = $fila->tx_username;
 
    // Generacion de un nuevo Password
    $pasw = "";
    $abecedario = array("A","B","C","D","E","F","G","H","J","K","L","M","N","O","P","Q","R","S","T",
"U","V","W","a","b","c","d","e","f","g","h","j","k","l","m","n","o","p","q","r","s","t","u","v","w");
    $simbolos   = array(",","}","{","-","|","!","#","$","%","&","/","(",")","=","?","¡",
"*","]","[","_",":",";","+");
    for($i=0;$i<3; $i++)
    {
        $md     = rand(1,2);
        $pasw   .=  (($md%2)==0) ? $abecedario[rand(0,43)] : rand(0,9); 
        $md     = rand(1,2);
        $pasw   .=  (($md%2)==0) ? rand(0,9) :  $simbolos[rand(0,23)]; 
        $md     = rand(1,2);
        $pasw   .=  (($md%2)==0) ?   $simbolos[rand(0,23)] : $abecedario[rand(0,43)] ;     
    }      
 
    // Le  Envio  por correo electronico  su nuevo password
     $seEnvio;          //Para determinar si se envio o no el correo
     $destinatario = $elcorreo;             //A quien se envia
     $nomAdmin          = 'Administración';       //Quien envia
     $mailAdmin         = 'fruiz@eie.ucr.ac.cr';   //Mail de quien envia
     $urlAccessLogin = 'http://localhost/autenticar_usuarios/'; //Url de la pantalla de login
 
     $elmensaje = "";    
     $asunto = "Nueva contraseña para ".$nick;
 
     $cuerpomsg ='
        <h3>.::Recuperar Password::.</h3>
        <p>A peticion de usted; se le ha asignado un nuevo password, utilice los siguientes datos para acceder al sistema</p>
          <table border="0" >
            <tr>
              <td colspan="2" align="center" ><br> Nuevos datos de acceso para <a href="'.$urlAccessLogin.'">'.$urlAccessLogin.'</a><br></td>
            </tr>
            <tr>
              <td> Nombre </td>
              <td> '.$nombre.' </td>
            </tr>
            <tr>
              <td> Username </td>
              <td> '.$nick.' </td>
            </tr>
            <tr>
              <td> Password </td>
              <td> '.$pasw.' </td>
            </tr>
          </table> ';
 
    date_default_timezone_set('America/Mexico_City');
 
    //Establecer cabeceras para la funcion mail()
    //version MIME
    $cabeceras = "MIME-Version: 1.0\r\n";
    //Tipo de info
    $cabeceras .= "Content-type: text/html; charset=iso-8859-1\r\n";
    //direccion del remitente
    $cabeceras .= "From: ".$nomAdmin." <".$mailAdmin.">";
    $resEnvio = 0;
    //Si se envio el email
    if(mail($destinatario,$asunto,$cuerpomsg,$cabeceras))
    {
        //Actualizar el pwd en la BD
        $sql_updt = "UPDATE tbl_users SET tx_password = '".md5($pasw)."'
        WHERE (id_usuario = ".$idusr.")
        AND (tx_correo = '".$elcorreo."')";
        $res_updt = mysql_query($sql_updt);
        $resEnvio = 1;
    }
 
    //Cerrrar conexion a la BD
    mysql_close($conexio);
 
    // Mostrar resultado de envio (en esta misma pagina)
    ?>
        <input type="hidden" id="enviado" value="<?php echo $resEnvio ?>">
        <input type="hidden" id="elcorreo" value="<?php echo $elcorreo ?>">
        <script type="text/javascript">
            location.href="recuperarPassword.php?enviado="+document.getElementById('enviado').value+"&elcorreo="+document.getElementById('elcorreo').value;
        </script>
    <?php   
}
else
{
?>
 
<tr>
    <td colspan="2">Escriba su correo electr&oacute;nico con el que se ha registrado,
        se le enviar&aacute; un nuevo password a su correo electr&oacute;nico:<br /><br />
    </td>
</tr>
 
<tr>
    <td>Correo electr&oacute;nico:</td>
    <td>
        <input type="text" name="correo" id="correo"  maxlength="50" />
    </td>
</tr>
<tr>
    <td>Confirme Correo electr&oacute;nico:</td>
    <td>
        <input type="text" name="correo2" id="correo2" maxlength="50" />
    </td>
</tr>
 
<?php
    //Si llega un codigo de error
    if( isset($_GET['error']) && $_GET['error']==1 )
    {
        echo "<tr><td colspan='2'><br><font color='red'>El correo electronico no pertenece a ningun usuario registrado.</font><br></td></tr>";
    }
    else if( isset($_GET['enviado']) && isset($_GET['elcorreo'])  )
    {
        //Si se envio correctamente el nuevo password
        if( $_GET['enviado']==1 )
            echo "<tr><td colspan='2'><br><font color='green'>Su nueva contrase&ntilde;a ha sido enviada a <strong>".$_GET['elcorreo']."</strong>.</font><br></td></tr>";
        else if( $_GET['enviado']==0 )
            echo "<tr><td colspan='2'><br><font color='red'>Por el momento la nueva contrase&ntilde;a no pudo ser enviada a <strong>".$_GET['elcorreo']."</strong>.<br>
            Intente de nuevo m&aacute;s tarde.</font></td></tr>";
    }
?>
 
<tr>
    <td align="center" colspan="2">
        <br /><br />
        <input type="button" onClick="javascript: location.href='index.php'" name="cancelar" value="Cancelar" >
        &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="submit" name="enviar" value="Enviar" >
    </td>
</tr>
 
<?php
}
?>
 
</table>
</form>
</body>
</html>

RFID Access Method

In this case we used RDM6300 125KHz cardreader5), this mini-module is designed for reading code from 125KHz card compatible read-only tags and read/write card . It can be applied in office/home security, personal identification, access control, anti-forgery, interactive toy and production control systems etc. For reading the tags we used te following code

rfid.py
#!/usr/bin/env python
import serial
import re, sys, signal, os, time, datetime
import RPi.GPIO as GPIO
 
BITRATE = 9600
GPIO.setmode(GPIO.BOARD)
 
CARDS = [
'060090840715',
'840034BD3E33',
]
def signal_handler(signal, frame):
	print "Cerrando"
	GPIO.output(7, GPIO.LOW) # Unlock the door on program exit
	GPIO.cleanup()
	ser.close()
	sys.exit(0)
 
if __name__ == '__main__':
	buffer = ''
	ser = serial.Serial('/dev/ttyAMA0', BITRATE, timeout=0)
	rfidPattern = re.compile(b'[\W_]+')
	signal.signal(signal.SIGINT, signal_handler)
 
	while True:
		# Read data from RFID reader
		buffer = buffer + ser.readline()
		if '\n' in buffer:
		lines = buffer.split('\n')
		last_received = lines[-2]
		match = rfidPattern.sub('', last_received)
 
		if match:
			print match
			if match in CARDS:
				print 'card authorized'
			else:
				print 'unauthorized card'
 
		# Clear buffer
		buffer = ''
		lines = ''
 
	time.sleep(0.1) 

Results & Conclusions

1)
The instructions here refer to an early version of RPi.GPIO. Please search the web for the latest version and replace the version numbers in the instructions.
3)
You should change nombre_de_usuario_de_mysql for your username and contraseña_de_mysql for your password
4)
Based on the work done by: Gonzalo Silverio
5)
You can download the datasheet from here: RDM630-Spec