RFID Cat Door Project

Dependencies:   EthernetNetIf TextLCD mbed HTTPServer ID12RFID

Committer:
sbobyr
Date:
Mon Aug 22 10:23:21 2011 +0000
Revision:
0:de1f8e99ef60
Child:
1:25a4acc15210

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sbobyr 0:de1f8e99ef60 1 // RFID Cat Door Project
sbobyr 0:de1f8e99ef60 2
sbobyr 0:de1f8e99ef60 3 #include "mbed.h"
sbobyr 0:de1f8e99ef60 4 #include "ID12RFID.h"
sbobyr 0:de1f8e99ef60 5 #include "TextLCD.h"
sbobyr 0:de1f8e99ef60 6 #include "EthernetNetIf.h"
sbobyr 0:de1f8e99ef60 7 #include "HTTPServer.h"
sbobyr 0:de1f8e99ef60 8 #include "HTTPRequestHandler.h"
sbobyr 0:de1f8e99ef60 9 #include "dbg/dbg.h"
sbobyr 0:de1f8e99ef60 10 #include <string>
sbobyr 0:de1f8e99ef60 11
sbobyr 0:de1f8e99ef60 12 TextLCD lcd(p24, p26, p27, p28, p29, p30);
sbobyr 0:de1f8e99ef60 13
sbobyr 0:de1f8e99ef60 14 EthernetNetIf eth;
sbobyr 0:de1f8e99ef60 15 HTTPServer svr;
sbobyr 0:de1f8e99ef60 16
sbobyr 0:de1f8e99ef60 17 enum Event {DoorOpenEvent, DoorClosedEvent, ProximityEvent, AuthTagReadEvent, DoorUnlockedTimeoutEvent, None};
sbobyr 0:de1f8e99ef60 18 Event event;
sbobyr 0:de1f8e99ef60 19
sbobyr 0:de1f8e99ef60 20 struct cat {
sbobyr 0:de1f8e99ef60 21 int tag;
sbobyr 0:de1f8e99ef60 22 string name;
sbobyr 0:de1f8e99ef60 23 bool bIsIn;
sbobyr 0:de1f8e99ef60 24 };
sbobyr 0:de1f8e99ef60 25
sbobyr 0:de1f8e99ef60 26 cat cats_list[] = {
sbobyr 0:de1f8e99ef60 27 {5454121, "Yellow", true},
sbobyr 0:de1f8e99ef60 28 //{9733970, "Blue", true},
sbobyr 0:de1f8e99ef60 29 //{463733, "Red", true}
sbobyr 0:de1f8e99ef60 30 };
sbobyr 0:de1f8e99ef60 31 int cats_count = sizeof(cats_list)/sizeof(cat);
sbobyr 0:de1f8e99ef60 32
sbobyr 0:de1f8e99ef60 33 class CatDoorHandler : public HTTPRequestHandler
sbobyr 0:de1f8e99ef60 34 {
sbobyr 0:de1f8e99ef60 35 public:
sbobyr 0:de1f8e99ef60 36 CatDoorHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) :
sbobyr 0:de1f8e99ef60 37 HTTPRequestHandler(rootPath, path, pTCPSocket){}
sbobyr 0:de1f8e99ef60 38
sbobyr 0:de1f8e99ef60 39 virtual ~CatDoorHandler(){ DBG("\r\nCatDoorHandler destroyed\r\n"); }
sbobyr 0:de1f8e99ef60 40
sbobyr 0:de1f8e99ef60 41 static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocket* pTCPSocket)
sbobyr 0:de1f8e99ef60 42 { return new CatDoorHandler(rootPath, path, pTCPSocket); }
sbobyr 0:de1f8e99ef60 43
sbobyr 0:de1f8e99ef60 44 virtual void doGet()
sbobyr 0:de1f8e99ef60 45 {
sbobyr 0:de1f8e99ef60 46 string name = cats_list[0].name;
sbobyr 0:de1f8e99ef60 47 DBG("\r\nIn CatDoorHandler::doGet()\r\n");
sbobyr 0:de1f8e99ef60 48 string header = "<html><body><h1>RFID Cat Door</h1>";
sbobyr 0:de1f8e99ef60 49 string p1 = "<h2><u>Door Status</u></h2>";
sbobyr 0:de1f8e99ef60 50 string p2 = (event == DoorOpenEvent) ? "Open" : "Closed";
sbobyr 0:de1f8e99ef60 51 string p3 = "<p>Door Status: " + p2 + "</p>";
sbobyr 0:de1f8e99ef60 52 string p4 = "<h2><u>Cat Status</u></h2>";
sbobyr 0:de1f8e99ef60 53 string p5 = (cats_list[0].bIsIn) ? "Yes" : "No";
sbobyr 0:de1f8e99ef60 54 string p6 = "<p>Is " + name + " Inside:" + p5 + "</p>";
sbobyr 0:de1f8e99ef60 55 string p7 = "<p><form id='SubmitButton' method='post' action=''>";
sbobyr 0:de1f8e99ef60 56 string p8 = "<input type='submit' name='lock' value='Lock System'></form></p>";
sbobyr 0:de1f8e99ef60 57 string footer = "</body></html>";
sbobyr 0:de1f8e99ef60 58 string resp = header + p1 + p3 + p4 + p6 + p7 + p8 + footer;
sbobyr 0:de1f8e99ef60 59 setContentLen(resp.length());
sbobyr 0:de1f8e99ef60 60 respHeaders()["Connection"] = "close";
sbobyr 0:de1f8e99ef60 61 writeData(resp.c_str(), resp.length());
sbobyr 0:de1f8e99ef60 62 DBG("\r\nExit CatDoorHandler::doGet()\r\n");
sbobyr 0:de1f8e99ef60 63 }
sbobyr 0:de1f8e99ef60 64
sbobyr 0:de1f8e99ef60 65 virtual void doPost()
sbobyr 0:de1f8e99ef60 66 {
sbobyr 0:de1f8e99ef60 67 // Override the system here
sbobyr 0:de1f8e99ef60 68 printf("\r\ndoPost\r\n");
sbobyr 0:de1f8e99ef60 69 string name = cats_list[0].name;
sbobyr 0:de1f8e99ef60 70 string header = "<html><body><h1>RFID Cat Door</h1>";
sbobyr 0:de1f8e99ef60 71 string p1 = "<p>System Locked</p>";
sbobyr 0:de1f8e99ef60 72 string footer = "</body></html>";
sbobyr 0:de1f8e99ef60 73 string resp = header + p1 + footer;
sbobyr 0:de1f8e99ef60 74 setContentLen(resp.length());
sbobyr 0:de1f8e99ef60 75 respHeaders()["Connection"] = "close";
sbobyr 0:de1f8e99ef60 76 writeData(resp.c_str(), resp.length());
sbobyr 0:de1f8e99ef60 77 DBG("\r\nExit CatDoorHandler::doPost()\r\n");
sbobyr 0:de1f8e99ef60 78 }
sbobyr 0:de1f8e99ef60 79
sbobyr 0:de1f8e99ef60 80 virtual void doHead()
sbobyr 0:de1f8e99ef60 81 {
sbobyr 0:de1f8e99ef60 82 printf("\r\ndoHead\r\n");
sbobyr 0:de1f8e99ef60 83 }
sbobyr 0:de1f8e99ef60 84
sbobyr 0:de1f8e99ef60 85 virtual void onReadable()
sbobyr 0:de1f8e99ef60 86 {
sbobyr 0:de1f8e99ef60 87 printf("\r\nonReadable\r\n");
sbobyr 0:de1f8e99ef60 88 }
sbobyr 0:de1f8e99ef60 89
sbobyr 0:de1f8e99ef60 90 virtual void onWriteable()
sbobyr 0:de1f8e99ef60 91 {
sbobyr 0:de1f8e99ef60 92 DBG("\r\nCatDoorHandler::onWriteable() event\r\n");
sbobyr 0:de1f8e99ef60 93 close(); // Data written, we can close the connection
sbobyr 0:de1f8e99ef60 94 }
sbobyr 0:de1f8e99ef60 95
sbobyr 0:de1f8e99ef60 96 virtual void onClose()
sbobyr 0:de1f8e99ef60 97 {
sbobyr 0:de1f8e99ef60 98 printf("\r\nonClose\r\n");
sbobyr 0:de1f8e99ef60 99 }
sbobyr 0:de1f8e99ef60 100 };
sbobyr 0:de1f8e99ef60 101
sbobyr 0:de1f8e99ef60 102 ID12RFID rfid(p14); // uart rx for ID-12 RFID reader
sbobyr 0:de1f8e99ef60 103 DigitalIn _door_open(p17); // 0 indicates door open
sbobyr 0:de1f8e99ef60 104 DigitalIn _proximity(p16); // 0 indicates an object within 10 cm
sbobyr 0:de1f8e99ef60 105 DigitalOut unlock_door(p21); // 1 will unlock the door
sbobyr 0:de1f8e99ef60 106
sbobyr 0:de1f8e99ef60 107 DigitalOut door_unlocked_led(LED1);
sbobyr 0:de1f8e99ef60 108 DigitalOut door_open_led(LED2);
sbobyr 0:de1f8e99ef60 109 DigitalOut proximity_led(LED3);
sbobyr 0:de1f8e99ef60 110 PwmOut rfid_read_led(LED4); // dim = unauthorized tag read; bright = authorized tag read
sbobyr 0:de1f8e99ef60 111
sbobyr 0:de1f8e99ef60 112 const float LED_DIM = 0.05;
sbobyr 0:de1f8e99ef60 113 const float LED_BRIGHT = 1;
sbobyr 0:de1f8e99ef60 114
sbobyr 0:de1f8e99ef60 115 bool IsAuthTagReadEvent() {
sbobyr 0:de1f8e99ef60 116 if(rfid.readable()) {
sbobyr 0:de1f8e99ef60 117 int tag = rfid.read();
sbobyr 0:de1f8e99ef60 118 rfid_read_led = LED_DIM;
sbobyr 0:de1f8e99ef60 119
sbobyr 0:de1f8e99ef60 120 lcd.cls();
sbobyr 0:de1f8e99ef60 121 lcd.locate(0, 0);
sbobyr 0:de1f8e99ef60 122 lcd.printf("Tag: %08d", tag);
sbobyr 0:de1f8e99ef60 123
sbobyr 0:de1f8e99ef60 124 for (int i = 0; i < cats_count; ++i) {
sbobyr 0:de1f8e99ef60 125 if (cats_list[i].tag == tag) {
sbobyr 0:de1f8e99ef60 126 lcd.locate(0, 1);
sbobyr 0:de1f8e99ef60 127 lcd.printf("%s", cats_list[i].name.c_str());
sbobyr 0:de1f8e99ef60 128 rfid_read_led = LED_BRIGHT;
sbobyr 0:de1f8e99ef60 129 return true;
sbobyr 0:de1f8e99ef60 130 }
sbobyr 0:de1f8e99ef60 131 }
sbobyr 0:de1f8e99ef60 132 }
sbobyr 0:de1f8e99ef60 133 return false;
sbobyr 0:de1f8e99ef60 134 }
sbobyr 0:de1f8e99ef60 135
sbobyr 0:de1f8e99ef60 136 bool IsProximityEvent() {
sbobyr 0:de1f8e99ef60 137 bool result = false;
sbobyr 0:de1f8e99ef60 138 static bool wasProximity = false;
sbobyr 0:de1f8e99ef60 139 bool bProximity = !_proximity.read();
sbobyr 0:de1f8e99ef60 140 proximity_led = bProximity;
sbobyr 0:de1f8e99ef60 141 if (bProximity & !wasProximity)
sbobyr 0:de1f8e99ef60 142 result = true;
sbobyr 0:de1f8e99ef60 143 wasProximity = bProximity;
sbobyr 0:de1f8e99ef60 144 return result;
sbobyr 0:de1f8e99ef60 145 }
sbobyr 0:de1f8e99ef60 146
sbobyr 0:de1f8e99ef60 147 bool IsDoorOpenEvent() {
sbobyr 0:de1f8e99ef60 148 bool result = false;
sbobyr 0:de1f8e99ef60 149 static bool wasOpen = false;
sbobyr 0:de1f8e99ef60 150 bool bDoorOpen = !_door_open.read();
sbobyr 0:de1f8e99ef60 151 door_open_led = bDoorOpen;
sbobyr 0:de1f8e99ef60 152 if (bDoorOpen & !wasOpen)
sbobyr 0:de1f8e99ef60 153 result = true;
sbobyr 0:de1f8e99ef60 154 wasOpen = bDoorOpen;
sbobyr 0:de1f8e99ef60 155 return result;
sbobyr 0:de1f8e99ef60 156 }
sbobyr 0:de1f8e99ef60 157
sbobyr 0:de1f8e99ef60 158 Timer doorClosedTimer;
sbobyr 0:de1f8e99ef60 159 bool IsDoorClosedEvent() {
sbobyr 0:de1f8e99ef60 160 bool result = false;
sbobyr 0:de1f8e99ef60 161 static bool wasClosed = true;
sbobyr 0:de1f8e99ef60 162 bool bDoorClosed = _door_open.read();
sbobyr 0:de1f8e99ef60 163 if (bDoorClosed & !wasClosed) {
sbobyr 0:de1f8e99ef60 164 doorClosedTimer.reset();
sbobyr 0:de1f8e99ef60 165 doorClosedTimer.start();
sbobyr 0:de1f8e99ef60 166 }
sbobyr 0:de1f8e99ef60 167 if (bDoorClosed & doorClosedTimer.read() > 1.0) {
sbobyr 0:de1f8e99ef60 168 doorClosedTimer.stop();
sbobyr 0:de1f8e99ef60 169 doorClosedTimer.reset();
sbobyr 0:de1f8e99ef60 170 result = true;
sbobyr 0:de1f8e99ef60 171 }
sbobyr 0:de1f8e99ef60 172 wasClosed = bDoorClosed;
sbobyr 0:de1f8e99ef60 173 return result;
sbobyr 0:de1f8e99ef60 174 }
sbobyr 0:de1f8e99ef60 175
sbobyr 0:de1f8e99ef60 176 Timer doorUnlockedTimer;
sbobyr 0:de1f8e99ef60 177 void UnlockDoor(bool req) {
sbobyr 0:de1f8e99ef60 178 unlock_door = (req) ? 1 : 0;
sbobyr 0:de1f8e99ef60 179 door_unlocked_led = unlock_door;
sbobyr 0:de1f8e99ef60 180 if (req) {
sbobyr 0:de1f8e99ef60 181 doorUnlockedTimer.reset();
sbobyr 0:de1f8e99ef60 182 doorUnlockedTimer.start();
sbobyr 0:de1f8e99ef60 183 }
sbobyr 0:de1f8e99ef60 184 }
sbobyr 0:de1f8e99ef60 185
sbobyr 0:de1f8e99ef60 186 bool IsDoorUnlockedTimeoutEvent() {
sbobyr 0:de1f8e99ef60 187 if (doorUnlockedTimer.read() > 5.0) {
sbobyr 0:de1f8e99ef60 188 doorUnlockedTimer.stop();
sbobyr 0:de1f8e99ef60 189 doorUnlockedTimer.reset();
sbobyr 0:de1f8e99ef60 190 return true;
sbobyr 0:de1f8e99ef60 191 }
sbobyr 0:de1f8e99ef60 192 return false;
sbobyr 0:de1f8e99ef60 193 }
sbobyr 0:de1f8e99ef60 194
sbobyr 0:de1f8e99ef60 195 enum State { DoorLockedClosed, DoorUnlockedClosed, DoorUnlockedOpen };
sbobyr 0:de1f8e99ef60 196 enum Approach { Inside, Outside };
sbobyr 0:de1f8e99ef60 197
sbobyr 0:de1f8e99ef60 198 void CatDoorStateMachine(Event event) {
sbobyr 0:de1f8e99ef60 199 static Approach approach = Inside;
sbobyr 0:de1f8e99ef60 200 static State state = DoorLockedClosed;
sbobyr 0:de1f8e99ef60 201 printf("state: %d, event: %d\n", state, event);
sbobyr 0:de1f8e99ef60 202
sbobyr 0:de1f8e99ef60 203 switch(state)
sbobyr 0:de1f8e99ef60 204 {
sbobyr 0:de1f8e99ef60 205 case DoorLockedClosed :
sbobyr 0:de1f8e99ef60 206 switch(event)
sbobyr 0:de1f8e99ef60 207 {
sbobyr 0:de1f8e99ef60 208 case ProximityEvent :
sbobyr 0:de1f8e99ef60 209 UnlockDoor(true);
sbobyr 0:de1f8e99ef60 210 state = DoorUnlockedClosed;
sbobyr 0:de1f8e99ef60 211 approach = Inside;
sbobyr 0:de1f8e99ef60 212 break;
sbobyr 0:de1f8e99ef60 213 case AuthTagReadEvent :
sbobyr 0:de1f8e99ef60 214 UnlockDoor(true);
sbobyr 0:de1f8e99ef60 215 state = DoorUnlockedClosed;
sbobyr 0:de1f8e99ef60 216 approach = Outside;
sbobyr 0:de1f8e99ef60 217 break;
sbobyr 0:de1f8e99ef60 218 default :
sbobyr 0:de1f8e99ef60 219 break;
sbobyr 0:de1f8e99ef60 220 }
sbobyr 0:de1f8e99ef60 221 break;
sbobyr 0:de1f8e99ef60 222 case DoorUnlockedClosed :
sbobyr 0:de1f8e99ef60 223 switch(event)
sbobyr 0:de1f8e99ef60 224 {
sbobyr 0:de1f8e99ef60 225 case DoorUnlockedTimeoutEvent :
sbobyr 0:de1f8e99ef60 226 UnlockDoor(false);
sbobyr 0:de1f8e99ef60 227 state = DoorLockedClosed;
sbobyr 0:de1f8e99ef60 228 break;
sbobyr 0:de1f8e99ef60 229 case DoorOpenEvent :
sbobyr 0:de1f8e99ef60 230 state = DoorUnlockedOpen;
sbobyr 0:de1f8e99ef60 231 break;
sbobyr 0:de1f8e99ef60 232 default :
sbobyr 0:de1f8e99ef60 233 break;
sbobyr 0:de1f8e99ef60 234 }
sbobyr 0:de1f8e99ef60 235 break;
sbobyr 0:de1f8e99ef60 236 case DoorUnlockedOpen :
sbobyr 0:de1f8e99ef60 237 switch(event)
sbobyr 0:de1f8e99ef60 238 {
sbobyr 0:de1f8e99ef60 239 case DoorClosedEvent :
sbobyr 0:de1f8e99ef60 240 UnlockDoor(false);
sbobyr 0:de1f8e99ef60 241 state = DoorLockedClosed;
sbobyr 0:de1f8e99ef60 242 cats_list[0].bIsIn = (approach == Inside) ? false : true;
sbobyr 0:de1f8e99ef60 243 break;
sbobyr 0:de1f8e99ef60 244 default :
sbobyr 0:de1f8e99ef60 245 break;
sbobyr 0:de1f8e99ef60 246 }
sbobyr 0:de1f8e99ef60 247 break;
sbobyr 0:de1f8e99ef60 248 default :
sbobyr 0:de1f8e99ef60 249 break;
sbobyr 0:de1f8e99ef60 250 }
sbobyr 0:de1f8e99ef60 251 }
sbobyr 0:de1f8e99ef60 252
sbobyr 0:de1f8e99ef60 253 int main() {
sbobyr 0:de1f8e99ef60 254 lcd.cls();
sbobyr 0:de1f8e99ef60 255
sbobyr 0:de1f8e99ef60 256 printf("Setting up...\n");
sbobyr 0:de1f8e99ef60 257 EthernetErr ethErr = eth.setup();
sbobyr 0:de1f8e99ef60 258 if (ethErr) {
sbobyr 0:de1f8e99ef60 259 printf("Error %d in setup.\n", ethErr);
sbobyr 0:de1f8e99ef60 260 return -1;
sbobyr 0:de1f8e99ef60 261 }
sbobyr 0:de1f8e99ef60 262 printf("Setup OK\n");
sbobyr 0:de1f8e99ef60 263
sbobyr 0:de1f8e99ef60 264 svr.addHandler<CatDoorHandler>("/");
sbobyr 0:de1f8e99ef60 265 svr.bind(80);
sbobyr 0:de1f8e99ef60 266
sbobyr 0:de1f8e99ef60 267 printf("Listening...\n");
sbobyr 0:de1f8e99ef60 268
sbobyr 0:de1f8e99ef60 269 Timer tm;
sbobyr 0:de1f8e99ef60 270 tm.start();
sbobyr 0:de1f8e99ef60 271
sbobyr 0:de1f8e99ef60 272 while(1) {
sbobyr 0:de1f8e99ef60 273 Net::poll();
sbobyr 0:de1f8e99ef60 274 if (tm.read() > 0.5) {
sbobyr 0:de1f8e99ef60 275 tm.start();
sbobyr 0:de1f8e99ef60 276 }
sbobyr 0:de1f8e99ef60 277
sbobyr 0:de1f8e99ef60 278 if (IsAuthTagReadEvent()) {
sbobyr 0:de1f8e99ef60 279 event = AuthTagReadEvent;
sbobyr 0:de1f8e99ef60 280 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 281 }
sbobyr 0:de1f8e99ef60 282
sbobyr 0:de1f8e99ef60 283 if (IsProximityEvent()) {
sbobyr 0:de1f8e99ef60 284 event = ProximityEvent;
sbobyr 0:de1f8e99ef60 285 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 286 }
sbobyr 0:de1f8e99ef60 287
sbobyr 0:de1f8e99ef60 288 if (IsDoorOpenEvent()) {
sbobyr 0:de1f8e99ef60 289 event = DoorOpenEvent;
sbobyr 0:de1f8e99ef60 290 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 291 }
sbobyr 0:de1f8e99ef60 292
sbobyr 0:de1f8e99ef60 293 if (IsDoorClosedEvent()) {
sbobyr 0:de1f8e99ef60 294 event = DoorClosedEvent;
sbobyr 0:de1f8e99ef60 295 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 296 }
sbobyr 0:de1f8e99ef60 297
sbobyr 0:de1f8e99ef60 298 if (IsDoorUnlockedTimeoutEvent()) {
sbobyr 0:de1f8e99ef60 299 event = DoorUnlockedTimeoutEvent;
sbobyr 0:de1f8e99ef60 300 CatDoorStateMachine(event);
sbobyr 0:de1f8e99ef60 301 }
sbobyr 0:de1f8e99ef60 302 }
sbobyr 0:de1f8e99ef60 303 }