RFID Cat Door Project

Dependencies:   EthernetNetIf TextLCD mbed HTTPServer ID12RFID

Revision:
2:9cc95c486c7b
Parent:
1:25a4acc15210
--- a/main.cpp	Tue Aug 23 19:09:20 2011 +0000
+++ b/main.cpp	Tue Aug 30 04:59:24 2011 +0000
@@ -1,64 +1,74 @@
 // RFID Cat Door Project
-
-//#define NO_HW
+// The code runs on mbed and implements RFID Cat Door system. System comprises 3 sensors (RFID Reader, Proximity sensor, Reed sensor)
+// and 1 actuator (Solenoid door lock). System operates either in offline or online mode (if IP address is acquired). In online mode
+// a web page is created describing system's state. A lockdown override is available in online mode locking down the system.
+// The system is controlled by a state machine and provides RFID-based entry control. Exit is allowed without authorization.
 
-#include "mbed.h"
-#include "ID12RFID.h"
-#include "TextLCD.h"
-#include "EthernetNetIf.h"
-#include "HTTPServer.h"
-#include "HTTPRequestHandler.h"
+//#define NO_HW // uncomment if there's no HW attached to mbed
+
+#include "mbed.h"                   // mbed library
+#include "ID12RFID.h"               // ID12 RFID Reader library
+#include "TextLCD.h"                // OrangeBoard LCD library
+#include "EthernetNetIf.h"          // Ethernet library
+#include "HTTPServer.h"             // HTTP Server library
+#include "HTTPRequestHandler.h"     // HTTP Request Handler library
 #include <string>
 
-EthernetNetIf eth; 
+EthernetNetIf eth;
 HTTPServer svr;
 class CatDoorHandler;
 
+// State Machine Events
 enum Event { DoorOpenEvent, DoorClosedEvent, ProximityEvent, AuthTagReadEvent, DoorUnlockedTimeoutEvent, None };
 string eventNames[] = { "DoorOpen", "DoorClosed", "Proximity", "AuthTagRead", "DoorUnlockedTimeout", "None" };
 Event event = None;
 
+// State Machine States
 enum State { DoorLockedClosed, DoorUnlockedClosed, DoorUnlockedOpen };
 string stateNames[] = { "Door Locked & Closed", "Door Unlocked & Closed", "Door Unlocked & Open" };
 State state = DoorLockedClosed;
 
-bool bLockdown = false;
+bool bLockdown = false; // variable indicating a lockdown from the web page
 
+// Cat's possible locations
 enum Location { Inside, Outside, Unknown };
 string locationNames[] = { "Inside", "Outside", "Unknown" };
 
+// Each cat has tag, name, and location
 struct cat { int tag; string name; Location location; };
+// List of authorized cats
 cat cats[] = {
     5454121, "Yellow", Unknown,
     //9733970, "Blue", Unknown,
     //463733, "Red", Unknown
 };
 int catsN = sizeof(cats)/sizeof(cat);
-int catId = 0;
+int catId = 0; // current cat ID
 
-TextLCD lcd(p24, p26, p27, p28, p29, p30);
-ID12RFID rfid(p14); // uart rx for ID-12 RFID reader
-DigitalIn _door_open(p17); // 0 indicates door open
-DigitalIn _proximity(p16); // 0 indicates an object within 10 cm
-DigitalOut unlock_door(p21); // 1 will unlock the door
+TextLCD lcd(p24, p26, p27, p28, p29, p30);  // OrangeBoard LCD
+ID12RFID rfid(p14);                         // uart rx for ID12 RFID reader
+DigitalIn _door_open(p17);                  // reed sensor, 0 indicates door open
+DigitalIn _proximity(p16);                  // proximity sensor, 0 indicates an object within 10 cm
+DigitalOut unlock_door(p21);                // solenoid, 1 will unlock the door
 
-DigitalOut door_unlocked_led(LED1);
-DigitalOut door_open_led(LED2);
-DigitalOut proximity_led(LED3);
-PwmOut rfid_read_led(LED4); // dim = unauthorized tag read; bright = authorized tag read
+DigitalOut door_unlocked_led(LED1);         // ON when door is unlocked
+DigitalOut door_open_led(LED2);             // ON when door is open
+DigitalOut proximity_led(LED3);             // ON when proximity sensor is triggered
+PwmOut rfid_read_led(LED4);                 // DIM = unauthorized tag read; BRIGHT = authorized tag read
 
 const float LED_DIM = 0.05;
 const float LED_BRIGHT = 1;
 
+// Authorized RFID Tag Read Event
 Timer tagReadTimer;
 bool IsAuthTagReadEvent() {
     if(rfid.readable()) {
-        int tag = rfid.read();
+        int tag = rfid.read();  // read the tag
         tagReadTimer.reset();
-        tagReadTimer.start();
+        tagReadTimer.start();   // start 5 sec timer
         
         lcd.cls(); lcd.locate(0, 0); lcd.printf("Tag: %08d", tag);
-        for (int i = 0; i < catsN; ++i) {
+        for (int i = 0; i < catsN; ++i) { // find if tag is authorized
             if (cats[i].tag == tag) {
                 catId = i;
                 lcd.locate(0, 1); lcd.printf("Cat: %s", cats[i].name.c_str());
@@ -67,10 +77,10 @@
             }
         }
         
-        lcd.locate(0, 1); lcd.printf("Cat: Unknown");
+        lcd.locate(0, 1); lcd.printf("Cat: Unknown"); // unknown tag
         rfid_read_led = LED_DIM;
     }
-    if (tagReadTimer.read() > 5.0) {
+    if (tagReadTimer.read() > 5.0) { // each tag is shown for 5 sec
         tagReadTimer.stop();
         tagReadTimer.reset();
         rfid_read_led = 0;
@@ -79,37 +89,41 @@
     return false;
 }
 
+// Proximity Event
 bool IsProximityEvent() {
     bool result = false;
-    static bool wasProximity = false;
-    bool bProximity = !_proximity.read();
+    static bool wasProximity = false;       // last state
+    bool bProximity = !_proximity.read();   // 0 indicates an object within 10 cm
     proximity_led = bProximity;
-    if (bProximity & !wasProximity)
+    if (bProximity & !wasProximity)         // create event on transition only
         result = true;
     wasProximity = bProximity;
     return result;
 }
 
+// Door Open Event
 bool IsDoorOpenEvent() {
     bool result = false;
-    static bool wasOpen = false;
-    bool bDoorOpen = !_door_open.read();
+    static bool wasOpen = false;            // last state
+    bool bDoorOpen = !_door_open.read();    // 0 indicates door open
     door_open_led = bDoorOpen;
-    if (bDoorOpen & !wasOpen)
+    if (bDoorOpen & !wasOpen)               // create event on transition only
         result = true;
     wasOpen = bDoorOpen;
     return result;
 }
 
+// Door Closed Event
 Timer doorClosedTimer;
 bool IsDoorClosedEvent() {
     bool result = false;
-    static bool wasClosed = true;
+    static bool wasClosed = true;           // last state
     bool bDoorClosed = _door_open.read();
-    if (bDoorClosed & !wasClosed) {
+    if (bDoorClosed & !wasClosed) {         // start timer when door closes
         doorClosedTimer.reset();
         doorClosedTimer.start();
     }
+    // event is only created if door has been closed for more than 1.2 sec
     if (bDoorClosed & doorClosedTimer.read() > 1.2) {
         doorClosedTimer.stop();
         doorClosedTimer.reset();
@@ -119,6 +133,7 @@
     return result;
 }
 
+// Door locking/unlocking code
 Timer doorUnlockedTimer;
 void UnlockDoor(bool req) {
     unlock_door = (req) ? 1 : 0;
@@ -129,8 +144,9 @@
     }
 }
 
+// Door Unlocked Timeout Event
 bool IsDoorUnlockedTimeoutEvent() {
-    if (doorUnlockedTimer.read() > 5.0) {
+    if (doorUnlockedTimer.read() > 5.0) { // fires if door has been unlocked for more than 5 sec
         doorUnlockedTimer.stop();
         doorUnlockedTimer.reset();
         return true;
@@ -138,25 +154,26 @@
     return false;
 }
 
+// State Machine Logic
 void CatDoorStateMachine(Event event) {
-    static Location destination = Outside;
-    printf("State: %s\t Event: %s\n", stateNames[state].c_str(), eventNames[event].c_str()); 
+    static Location destination = Outside; // destination variable helps determine location of a cat
+    printf("State: %s\t Event: %s\n", stateNames[state].c_str(), eventNames[event].c_str());
     
     switch(state)
     {
         case DoorLockedClosed :
-            if (bLockdown) break;
+            if (bLockdown) break; // bLockdown doesn't let state machine exit DoorLockedClosed state
             switch(event)
             {
                 case ProximityEvent :
-                    UnlockDoor(true);                 
+                    UnlockDoor(true);                   // unlock door
                     state = DoorUnlockedClosed;
-                    destination = Outside;
+                    destination = Outside;              // cat's coming outside
                     break;
                 case AuthTagReadEvent :
-                    UnlockDoor(true);
+                    UnlockDoor(true);                   // unlock door
                     state = DoorUnlockedClosed;
-                    destination = Inside;
+                    destination = Inside;               // cat's coming inside
                     break;
                 default :
                     break;
@@ -165,8 +182,8 @@
         case DoorUnlockedClosed :
             switch(event)
             {
-                case DoorUnlockedTimeoutEvent :
-                    UnlockDoor(false);
+                case DoorUnlockedTimeoutEvent :         // lock door after 5 sec
+                    UnlockDoor(false);                  // lock door
                     state = DoorLockedClosed;
                     break;
                 case DoorOpenEvent :
@@ -179,10 +196,10 @@
         case DoorUnlockedOpen :
             switch(event)
             {
-                case DoorClosedEvent :
-                    UnlockDoor(false);
+                case DoorClosedEvent :                  // door closed, can lock it now
+                    UnlockDoor(false);                  // lock door
                     state = DoorLockedClosed;
-                    cats[catId].location = destination;
+                    cats[catId].location = destination; // cat's location determined
                     break;
                 default :
                     break;
@@ -194,61 +211,62 @@
 }
 
 int main() {
-    bool bEthPresent = true;
+    bool bEthPresent = true; // online/offline mode variable
     lcd.cls(); lcd.locate(0, 0); lcd.printf("RFID Cat Door");
     lcd.locate(0, 1); lcd.printf("Setting up ^..^");
     printf("RFID Cat Door\n");
     printf("Setting up Ethernet ^..^\n");
-    EthernetErr ethErr = eth.setup();
+    EthernetErr ethErr = eth.setup(); // Ethernet setup
     if (ethErr) {
         printf("Error %d in Ethernet setup\n", ethErr);
         printf("Operating in offline mode ^..^\n");
         lcd.cls(); lcd.printf("Offline mode");
-        bEthPresent = false;
+        bEthPresent = false; // offline mode set
     }
     else {
         printf("Ethernet setup OK\n");
         printf("Operating in online mode ^..^\n");
-        IpAddr ip = eth.getIp();
+        IpAddr ip = eth.getIp(); // IP address
         lcd.cls(); lcd.locate(0, 0); lcd.printf("Online mode, IP:");
         lcd.locate(0, 1); lcd.printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
       
-        svr.addHandler<CatDoorHandler>("/");
-        svr.bind(80);
+        svr.addHandler<CatDoorHandler>("/");    // our HTTP handler added
+        svr.bind(80);                           // port 80 bound
     }
 
     while(1) {
         if (bEthPresent)
-            Net::poll();
+            Net::poll();                        // service HTTP requests
 
 #ifndef NO_HW        
         if (IsAuthTagReadEvent()) {
-            event = AuthTagReadEvent;
+            event = AuthTagReadEvent;           // Authorized Tag Read Event
             CatDoorStateMachine(event);
         }
 #endif    
         if (IsProximityEvent()) {
-            event = ProximityEvent;
+            event = ProximityEvent;             // Proximity Event
             CatDoorStateMachine(event);
         }
         
         if (IsDoorOpenEvent()) {
-            event = DoorOpenEvent;
+            event = DoorOpenEvent;              // Door Open Event
             CatDoorStateMachine(event);
         }
         
         if (IsDoorClosedEvent()) {
-            event = DoorClosedEvent;
+            event = DoorClosedEvent;            // Door Closed Event
             CatDoorStateMachine(event);
         }
         
         if (IsDoorUnlockedTimeoutEvent()) {
-            event = DoorUnlockedTimeoutEvent;
+            event = DoorUnlockedTimeoutEvent;   // Door Unlocked Timeout Event
             CatDoorStateMachine(event);
         }
     }
 }
 
+// Cat Door HTTP Handler will handle HTTP GET requests
 class CatDoorHandler : public HTTPRequestHandler
 {
 public:
@@ -260,9 +278,9 @@
     static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTCPSocket)
     { return new CatDoorHandler(rootPath, path, pTCPSocket); }
 
-    virtual void doGet()
+    virtual void doGet() // handles HTTP GET requests
     {
-        string _path = path();
+        string _path = path(); // path will have "lockdown=yes" if lockdown checkbox was checked
         printf("doGet path: %s\n", _path.c_str());
         bLockdown = (_path.find("lockdown=yes") == string::npos) ? false : true;
         if (bLockdown) {
@@ -272,17 +290,18 @@
             lcd.cls();
         }
         
+        // Create HTML page with status information, lockdown checkbox, and submit/refresh button
         string rs = "<html><head><title>RFID Cat Door</title></head><body><h3>RFID Cat Door</h3>";
         string ds = "Door Status: <i>" + stateNames[state] + "</i><br>";
         string cs = "Cat Status: <i>" + locationNames[cats[catId].location] + "</i><p>";
-        string ld = (bLockdown) ? " checked" : "";
+        string ld = (bLockdown) ? " checked" : ""; // lockdownn checkbox reflects system lockdown state
         string fr = "<form method='get' action=''>"
         "<input type='checkbox' name='lockdown' value='yes'" + ld + "> Lockdown System <p>"
         "<input type='submit' value='Submit/Refresh Data'></form></body></html>";
         rs += ds + cs + fr;
         setContentLen(rs.length());
         respHeaders()["Connection"] = "close";
-        writeData(rs.c_str(), rs.length()); 
+        writeData(rs.c_str(), rs.length());
     }
 
     virtual void doPost() {}