RFID Cat Door Project
Dependencies: EthernetNetIf TextLCD mbed HTTPServer ID12RFID
Revision 2:9cc95c486c7b, committed 2011-08-30
- Comitter:
- sbobyr
- Date:
- Tue Aug 30 04:59:24 2011 +0000
- Parent:
- 1:25a4acc15210
- Commit message:
- Final commented version
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 25a4acc15210 -r 9cc95c486c7b main.cpp --- 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() {}