RFID Cat Door Project

Dependencies:   EthernetNetIf TextLCD mbed HTTPServer ID12RFID

Files at this revision

API Documentation at this revision

Comitter:
sbobyr
Date:
Tue Aug 23 19:09:20 2011 +0000
Parent:
0:de1f8e99ef60
Child:
2:9cc95c486c7b
Commit message:
Internet control implemented. System can be locked down remotely

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Aug 22 10:23:21 2011 +0000
+++ b/main.cpp	Tue Aug 23 19:09:20 2011 +0000
@@ -1,104 +1,42 @@
 // RFID Cat Door Project
 
+//#define NO_HW
+
 #include "mbed.h"
 #include "ID12RFID.h"
 #include "TextLCD.h"
 #include "EthernetNetIf.h"
 #include "HTTPServer.h"
 #include "HTTPRequestHandler.h"
-#include "dbg/dbg.h"
 #include <string>
 
-TextLCD lcd(p24, p26, p27, p28, p29, p30);
-
 EthernetNetIf eth; 
 HTTPServer svr;
-
-enum Event {DoorOpenEvent, DoorClosedEvent, ProximityEvent, AuthTagReadEvent, DoorUnlockedTimeoutEvent, None};
-Event event;
+class CatDoorHandler;
 
-struct cat {
-    int tag;
-    string name;
-    bool bIsIn;
-};
+enum Event { DoorOpenEvent, DoorClosedEvent, ProximityEvent, AuthTagReadEvent, DoorUnlockedTimeoutEvent, None };
+string eventNames[] = { "DoorOpen", "DoorClosed", "Proximity", "AuthTagRead", "DoorUnlockedTimeout", "None" };
+Event event = None;
 
-cat cats_list[] = {
-    {5454121, "Yellow", true},
-    //{9733970, "Blue", true},
-    //{463733, "Red", true}
-};
-int cats_count = sizeof(cats_list)/sizeof(cat); 
+enum State { DoorLockedClosed, DoorUnlockedClosed, DoorUnlockedOpen };
+string stateNames[] = { "Door Locked & Closed", "Door Unlocked & Closed", "Door Unlocked & Open" };
+State state = DoorLockedClosed;
 
-class CatDoorHandler : public HTTPRequestHandler
-{
-public:
-    CatDoorHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) :
-        HTTPRequestHandler(rootPath, path, pTCPSocket){}
-
-    virtual ~CatDoorHandler(){ DBG("\r\nCatDoorHandler destroyed\r\n"); }
-
-    static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTCPSocket)
-    { return new CatDoorHandler(rootPath, path, pTCPSocket); }
+bool bLockdown = false;
 
-    virtual void doGet()
-    {
-        string name = cats_list[0].name;
-        DBG("\r\nIn CatDoorHandler::doGet()\r\n");
-        string header = "<html><body><h1>RFID Cat Door</h1>";
-        string p1 = "<h2><u>Door Status</u></h2>";
-        string p2 = (event == DoorOpenEvent) ? "Open" : "Closed";
-        string p3 = "<p>Door Status: " + p2 + "</p>";
-        string p4 = "<h2><u>Cat Status</u></h2>";
-        string p5 = (cats_list[0].bIsIn) ? "Yes" : "No";
-        string p6 = "<p>Is " + name + " Inside:" + p5 + "</p>";
-        string p7 = "<p><form id='SubmitButton' method='post' action=''>";
-        string p8 = "<input type='submit' name='lock' value='Lock System'></form></p>";
-        string footer = "</body></html>";
-        string resp = header + p1 + p3 + p4 + p6 + p7 + p8 + footer;
-        setContentLen(resp.length());
-        respHeaders()["Connection"] = "close";
-        writeData(resp.c_str(), resp.length());
-        DBG("\r\nExit CatDoorHandler::doGet()\r\n");
-    }
+enum Location { Inside, Outside, Unknown };
+string locationNames[] = { "Inside", "Outside", "Unknown" };
 
-    virtual void doPost()
-    {
-        // Override the system here
-        printf("\r\ndoPost\r\n");
-        string name = cats_list[0].name;
-        string header = "<html><body><h1>RFID Cat Door</h1>";
-        string p1 = "<p>System Locked</p>";
-        string footer = "</body></html>";
-        string resp = header + p1 + footer;
-        setContentLen(resp.length());
-        respHeaders()["Connection"] = "close";
-        writeData(resp.c_str(), resp.length());
-        DBG("\r\nExit CatDoorHandler::doPost()\r\n");
-    }
+struct cat { int tag; string name; Location location; };
+cat cats[] = {
+    5454121, "Yellow", Unknown,
+    //9733970, "Blue", Unknown,
+    //463733, "Red", Unknown
+};
+int catsN = sizeof(cats)/sizeof(cat);
+int catId = 0;
 
-    virtual void doHead()
-    {
-        printf("\r\ndoHead\r\n");
-    }
-
-    virtual void onReadable()
-    {
-        printf("\r\nonReadable\r\n");
-    }
-    
-    virtual void onWriteable()
-    {
-        DBG("\r\nCatDoorHandler::onWriteable() event\r\n");
-        close(); // Data written, we can close the connection
-    }
-    
-    virtual void onClose()
-    {
-        printf("\r\nonClose\r\n");
-    }
-};
-
+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
@@ -111,24 +49,32 @@
 
 const float LED_DIM = 0.05;
 const float LED_BRIGHT = 1;
- 
+
+Timer tagReadTimer;
 bool IsAuthTagReadEvent() {
     if(rfid.readable()) {
         int tag = rfid.read();
-        rfid_read_led = LED_DIM;
+        tagReadTimer.reset();
+        tagReadTimer.start();
         
-        lcd.cls();
-        lcd.locate(0, 0);
-        lcd.printf("Tag: %08d", tag);
-
-        for (int i = 0; i < cats_count; ++i) {
-            if (cats_list[i].tag == tag) {
-                lcd.locate(0, 1);
-                lcd.printf("%s", cats_list[i].name.c_str());
+        lcd.cls(); lcd.locate(0, 0); lcd.printf("Tag: %08d", tag);
+        for (int i = 0; i < catsN; ++i) {
+            if (cats[i].tag == tag) {
+                catId = i;
+                lcd.locate(0, 1); lcd.printf("Cat: %s", cats[i].name.c_str());
                 rfid_read_led = LED_BRIGHT;
                 return true;
             }
         }
+        
+        lcd.locate(0, 1); lcd.printf("Cat: Unknown");
+        rfid_read_led = LED_DIM;
+    }
+    if (tagReadTimer.read() > 5.0) {
+        tagReadTimer.stop();
+        tagReadTimer.reset();
+        rfid_read_led = 0;
+        lcd.cls();
     }
     return false;
 }
@@ -164,7 +110,7 @@
         doorClosedTimer.reset();
         doorClosedTimer.start();
     }
-    if (bDoorClosed & doorClosedTimer.read() > 1.0) {
+    if (bDoorClosed & doorClosedTimer.read() > 1.2) {
         doorClosedTimer.stop();
         doorClosedTimer.reset();
         result = true;
@@ -192,28 +138,25 @@
     return false;
 }
 
-enum State { DoorLockedClosed, DoorUnlockedClosed, DoorUnlockedOpen };
-enum Approach { Inside, Outside };
-
 void CatDoorStateMachine(Event event) {
-    static Approach approach = Inside;
-    static State state = DoorLockedClosed;
-    printf("state: %d, event: %d\n", state, event); 
+    static Location destination = Outside;
+    printf("State: %s\t Event: %s\n", stateNames[state].c_str(), eventNames[event].c_str()); 
     
     switch(state)
     {
         case DoorLockedClosed :
+            if (bLockdown) break;
             switch(event)
             {
                 case ProximityEvent :
                     UnlockDoor(true);                 
                     state = DoorUnlockedClosed;
-                    approach = Inside;
+                    destination = Outside;
                     break;
                 case AuthTagReadEvent :
                     UnlockDoor(true);
                     state = DoorUnlockedClosed;
-                    approach = Outside;
+                    destination = Inside;
                     break;
                 default :
                     break;
@@ -239,7 +182,7 @@
                 case DoorClosedEvent :
                     UnlockDoor(false);
                     state = DoorLockedClosed;
-                    cats_list[0].bIsIn = (approach == Inside) ? false : true;
+                    cats[catId].location = destination;
                     break;
                 default :
                     break;
@@ -251,35 +194,39 @@
 }
 
 int main() {
-    lcd.cls();
-
-    printf("Setting up...\n");
+    bool bEthPresent = true;
+    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();
     if (ethErr) {
-        printf("Error %d in setup.\n", ethErr);
-        return -1;
+        printf("Error %d in Ethernet setup\n", ethErr);
+        printf("Operating in offline mode ^..^\n");
+        lcd.cls(); lcd.printf("Offline mode");
+        bEthPresent = false;
     }
-    printf("Setup OK\n");
-  
-    svr.addHandler<CatDoorHandler>("/");
-    svr.bind(80);
-  
-    printf("Listening...\n");
-    
-    Timer tm;
-    tm.start();
+    else {
+        printf("Ethernet setup OK\n");
+        printf("Operating in online mode ^..^\n");
+        IpAddr ip = eth.getIp();
+        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);
+    }
 
     while(1) {
-        Net::poll();
-        if (tm.read() > 0.5) {
-            tm.start();
-        }
-        
+        if (bEthPresent)
+            Net::poll();
+
+#ifndef NO_HW        
         if (IsAuthTagReadEvent()) {
             event = AuthTagReadEvent;
             CatDoorStateMachine(event);
         }
-        
+#endif    
         if (IsProximityEvent()) {
             event = ProximityEvent;
             CatDoorStateMachine(event);
@@ -301,3 +248,46 @@
         }
     }
 }
+
+class CatDoorHandler : public HTTPRequestHandler
+{
+public:
+    CatDoorHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) :
+        HTTPRequestHandler(rootPath, path, pTCPSocket){}
+
+    virtual ~CatDoorHandler(){}
+
+    static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTCPSocket)
+    { return new CatDoorHandler(rootPath, path, pTCPSocket); }
+
+    virtual void doGet()
+    {
+        string _path = path();
+        printf("doGet path: %s\n", _path.c_str());
+        bLockdown = (_path.find("lockdown=yes") == string::npos) ? false : true;
+        if (bLockdown) {
+            lcd.cls(); lcd.printf("System Lockdown!");
+        }
+        else {
+            lcd.cls();
+        }
+        
+        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 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()); 
+    }
+
+    virtual void doPost() {}
+    virtual void doHead() {}
+    virtual void onReadable() {}
+    virtual void onWriteable() {}
+    virtual void onClose() {}
+};