Outline:
  • Concepts
  • Demonstration
  • Working flow
  • Things used in this project
  • Wiring Diagram between PHPoC and Adafruit PN532
  • Source codes
    • A normal lock using RFID
    • Simple IoT Lock
    • Database design
    • Libraries


Concepts
  • Normal RFID Lock: a device which prevents something such as a door being opened and which you can only open with some specific RFID Tags.
  • Simple IoT Lock: a RFID lock connected to internet with some additional features:
    • Access permission is managed by a server which allows flexibility in managing the system especially with multi-door and multi-user.
    • The accessed history is stored in database


Demonstration

This video introduces a demonstration of unlocking the door of manager’s room.





Working flow

A normal lock using RFID

Click image for larger version  Name:	iot_lock_normal_lock.PNG Views:	1 Size:	37.0 KB ID:	575


IoT Lock

Click image for larger version  Name:	IoT_lock_IoT_lock.PNG Views:	1 Size:	56.7 KB ID:	576

Normal RFID lock is simple to implement. It does not require internet connection and database query as well. However, it has some drawbacks. Memory of embedded system is limited. The number keys are, therefore, limited. In the other hand, it’s inflexible to add/remove a key to/from the system (when loosing key, changing key or adding new key for new user) and change the privilege as well.
In comparison with the normal RFID Lock, the simple IoT lock is a little more complicated. However, it overcomes all drawbacks of the normal RFID lock. Additionally, history of access is stored, allowing to monitor/check who opens the door when needed.


Things Used In This Project
  • PHPoC Blue or Black
  • PN532 NFC/RFID controller (in my case, I used Adafruit PN532 RFID/NFC Breakout)
  • Some NFC/RFID tags
  • PHPoC bread board (Optional)
Click image for larger version  Name:	IoT_lock_Things.jpg Views:	1 Size:	115.0 KB ID:	577



Wiring Diagram between PHPoC and Adafruit PN532
  • PHPoC------------- Adafruit PN532
  • 3V----------------3.3V (Red wire)
  • SCK ----------------SCK (Yellow wire)
  • MISO---------------MISO (Green wire)
  • MOSI---------------MOSI (Blue wire)
  • 4 ------------------SSEL (White wire)
  • GND---------------GND (Gray wire)


Source codes

A normal lock using RFID
<task0.php>
PHP Code:
<?php

if(_SERVER("REQUEST_METHOD"))
    exit; 
// avoid php execution via http request

include_once "/lib/sd_340.php";
include_once 
"vd_pcd_pn532.php";
include_once 
"vd_mifare_classic.php";

$uid "";
$pre_uid "";

$access_list = array("FE65B0AB"); //add more Key here

function access_list_look_up($uid)
{
    global 
$access_list;

    
$count count($access_list);

    for(
$i 0$i $count$i++)
        if(
$access_list[$i] == $uid)
            return 
true;

    return 
false;
}

reader_init(); //RFID reader init

while(1)
{
    if(
reader_ISO14443A_is_present($uid))
    {
        if(
$pre_uid == $uid)
            continue;

        
$pre_uid $uid;    
        
$uid bin2hex($uid);

        
//lookup in access list
        
$result access_list_look_up($uid);

        if(
$result == false//Not found in access list
        
{
            echo 
"IoT Lock: Access is denied\r\n";
            
// TODO: add alert function here
        
}
        else
        {
            echo 
"IoT Lock: Access is authorized, door is openning\r\n";
            
//TODO: open the door.
        
}        
    }
}
?>



IoT Lock
<task0.php>
PHP Code:
<?php

if(_SERVER("REQUEST_METHOD"))
    exit; 
// avoid php execution via http request

include_once "/lib/sd_340.php";
include_once 
"/lib/sn_dns.php";
include_once 
"/lib/sn_mysql.php";
include_once 
"vd_pcd_pn532.php";
include_once 
"vd_mifare_classic.php";

define("PRIVILEGE_UNAUTHORIZED",   0);
define("PRIVILEGE_EMPLOYEE",   1);
define("PRIVILEGE_MANAGER",   2);

//Check and print error messages from DB server
function chk_error($result)
{
    if(
$result !== false)
    {
        
$error mysql_error($result);
        if(
strlen($error) != 0)
            echo 
"Error: $error\r\n";
    }
}

//Enter your DB Server's hostname or IP address!
$server_addr "192.168.0.3";

//Enter your account information!
$user_name "your_username";
$password "your_password";

$uid "";
$pre_uid "";

$door_id "00000001"// Change door id here.
$allow_privilege PRIVILEGE_MANAGER// mininum privilege level is required to open door. Change it according to each access permision of each door.

reader_init(); //RFID reader init

//Connect to DB Server
if(mysql_connect($server_addr$user_name$password))
{
    
$result mysql_select_db("iot_lock");
    
chk_error($result);
}

while(
1)
{
    if(
reader_ISO14443A_is_present($uid))
    {
        if(
$pre_uid == $uid)
            continue;

        
$pre_uid $uid;    
        
$uid bin2hex($uid);

        
/**
        Note: In this code, I use Tag's UID as key ID.
        To make it more flexible, You can wire your own design key ID to user memory.
        And then read it to update to database as key ID.
        **/

        //Inquiry the last record
        
$result mysql_query("SELECT * FROM tbl_key WHERE key_id='$uid';");
        
chk_error($result);

        
//get result of the inquiry
        
$result_arr mysql_fetch_row($result);

        if(
$result_arr === false//Not found in database
        
{
            echo 
"IoT Lock: Unknown key\r\n";
            
// TODO: add alert function here
            
continue;
        }

        
$user_privilege = (int)$result_arr[1];

        if(
$user_privilege $allow_privilege)    
            echo 
"IoT Lock: Access is denied. The key doesn't have privilege\r\n";
        else
        {
            
//TODO: open the door.
            
echo "IoT Lock: Access is authorized, door is openning\r\n";
            
//create a history record
            
$result mysql_query("INSERT INTO tbl_history(key_id, door_id, date_time) VALUES ('$uid', '$door_id', NOW());");
            
chk_error($result);
        }        
    }
}

mysql_close();
?>




Database design

For the sake of simplicity, I design only two simple tables in database without any FOREIGN KEY constraint.
  • Key table: to store key id and privilege. Key id in this example has a dual role: key identification and user identification. (It had better to divide this table into key table and user table). The privilege is to specify
  • -|----Field-----|-----Type----------|
  • | key_id | VARCHAR(20) |
  • | privilege | INTEGER |
  • History table: to keep history of opening door.
  • -|----Field-----|-----Type----------|
  • | index_ | INTEGER |
  • | key_id | VARCHAR(20) |
  • | door_id | VARCHAR(20)|
  • | date_time |DATETIME |


Mysql script for creating database and tables.

Code:
CREATE DATABASE iot_lock;
USE iot_lock;
CREATE TABLE tbl_key (key_id VARCHAR(20) NOT NULL PRIMARY KEY, privilege INTEGER NOT NULL);
CREATE TABLE tbl_history (index_ INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, key_id VARCHAR(20) NOT NULL, door_id VARCHAR(20) NOT NULL, date_time DATETIME(0) NOT NULL);




Mysql script for adding the key. In my case, I have two keys:
  • a RFID tag with UID: FE65B0AB is set as a key of manager (privilege = 2)
  • a RFID tag with UID: BD1E1D00 is set as a key of normal employee (privilege = 1)
    Code:
    SET @key_id='FE65B0AB', @privilege=2; /*This is a key of manager. change it according to UID of your card */
    	INSERT INTO tbl_key (key_id, privilege) VALUES (@key_id,  @privilege);
    
    	SET @key_id='BD1E1D00', @privilege=1; /*This is a key of normal employee. change it according to UID of your card */
    	INSERT INTO tbl_key (key_id, privilege) VALUES (@key_id,  @privilege);


Libraries

If you have any questions or something to discuss, don’t hesitate to leave a comment!