Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Reads cards from HID reader UART
- * and outputs access denied/granted.
- */
- /* Pins */
- UNLOCKPIN <- hardware.pin5;
- LOCKPIN <- hardware.pin7;
- LEDPIN <- hardware.pin8;
- DOORSWITCH <- hardware.pin9;
- /* Constants */
- const DEADBOLTSELFLOCKDELAY = 5000; /* Used in state 5 of deadboltSM */
- /* States for Deadbolt SM */
- enum Deadbolt {
- state0dummystate, /* To make debugging not start from zero*/
- state1DLDC, /* Deadbolt locked Door closed */
- state2Unlocking,
- state3Locking,
- state4DUDO, /* Deadbolt unlocked Door open */
- state5DUDC, /* Deadbolt unlocked Door closed */
- state6DLDO /* Deadbolt locked Door open */
- }
- /* Variables*/
- currentCard <- 0; /* Card byte buffer */
- currentCardBytessReceived <- 0; /* Number of bytes read by UART */
- accessGranted <- 0; /* Read and reset by deadboltSM */
- ledState <- 0; /* For LED blink*/
- deadboltState <- Deadbolt.state1DLDC;
- /* Times */
- timeLastByteReceived <- 0;
- timeLastDeadboltSMChange <- 0;
- /** OutputPorts */
- /** For reporting events like "Access granted/denied to ..." */
- local accessLog = OutputPort("AccessLog");
- /** For reporting "0" for locked and "1" for unlocked.
- * This could be either an entrance or exit. */
- local unlockedLog = OutputPort("UnlockedLog");
- /* 32-bit tag containers for 26-bit tags including parity bits */
- allowedIDs <- blob(24);
- allowedIDs.writen(0x00000000, 'i'); /* Andrew */
- allowedIDs.writen(0x00000000, 'i'); /* Person 2 */
- allowedIDs.writen(0x00000000, 'i'); /* Person 3 */
- allowedIDs.writen(0x00000000, 'i'); /* Person 4 */
- allowedIDs.writen(0x00000000, 'i'); /* Person 5 */
- allowedIDs.writen(0x00000000, 'i'); /* Person 6 */
- /* String array that corresponds to the card numbers */
- allowedNames <- [
- "Andrew Ong",
- "Person 2",
- "Person 3",
- "Person 4",
- "Person 5"
- "Person 6"
- ];
- /** More IDs for people who I've identified but are not on the allowed list.
- * This is so that when they walk through the door, instead of seeing
- * "Access Denied: 99648 0x04170A80", you see
- * "Access Denied: Martin"
- */
- otherIDs <- blob(28);
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person1 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person2 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person3 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person4 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person5 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person6 */
- otherIDs.writen(0x00000000, 'i'); /* AccessDenied Person7 */
- otherNames <- [
- "AccessDenied Person1",
- "AccessDenied Person2",
- "AccessDenied Person3",
- "AccessDenied Person4",
- "AccessDenied Person5",
- "AccessDenied Person6",
- "AccessDenied Person7"
- ];
- function deadboltSM(){
- /* Actions */
- /* Transitions */
- switch(deadboltState){
- case Deadbolt.state1DLDC: /* Deadbolt locked Door closed */
- if(DOORSWITCH.read()){
- deadboltState = Deadbolt.state4DUDO;
- onDeadboltSMTransition();
- }
- else if(accessGranted == 1){
- deadboltState = Deadbolt.state2Unlocking;
- onDeadboltSMTransition();
- UNLOCKPIN.write(1);
- }
- else if(accessGranted == 0){
- /* Loopback transition */
- }
- break;
- case Deadbolt.state2Unlocking:
- if(hardware.millis() - timeLastDeadboltSMChange < 2000){
- /* Loopback transition */
- }
- else if(DOORSWITCH.read() == 1){
- deadboltState = Deadbolt.state4DUDO;
- onDeadboltSMTransition();
- UNLOCKPIN.write(0);
- }
- else if(DOORSWITCH.read() == 0){
- deadboltState = Deadbolt.state5DUDC;
- onDeadboltSMTransition();
- UNLOCKPIN.write(0);
- }
- break;
- case Deadbolt.state3Locking:
- if(hardware.millis() - timeLastDeadboltSMChange < 2000){
- /* Loopback transition */
- }
- else if(DOORSWITCH.read() == 1){
- deadboltState = Deadbolt.state6DLDO;
- onDeadboltSMTransition();
- LOCKPIN.write(0);
- accessGranted = 0;
- }
- else if(DOORSWITCH.read() == 0){
- deadboltState = Deadbolt.state1DLDC;
- onDeadboltSMTransition();
- LOCKPIN.write(0);
- accessGranted = 0;
- }
- break;
- case Deadbolt.state4DUDO: /* Deadbolt unlocked Door open */
- if(DOORSWITCH.read() == 1){
- /* Loopback transition */
- }
- else if(DOORSWITCH.read() == 0){
- deadboltState = Deadbolt.state3Locking;
- onDeadboltSMTransition();
- LOCKPIN.write(1);
- }
- break;
- case Deadbolt.state5DUDC: /* Deadbolt unlocked Door closed */
- if(DOORSWITCH.read() == 1){
- deadboltState = Deadbolt.state4DUDO;
- onDeadboltSMTransition();
- }
- else if(hardware.millis() - timeLastDeadboltSMChange > DEADBOLTSELFLOCKDELAY){
- deadboltState = Deadbolt.state3Locking;
- onDeadboltSMTransition();
- LOCKPIN.write(1);
- }
- // else if(hardware.millis() - timeLastDeadboltSMChange > DEADBOLTSELFLOCKDELAY){
- // /* Loopback transition */
- // }
- break;
- case Deadbolt.state6DLDO: /* Deadbolt locked Door open */
- deadboltState = Deadbolt.state2Unlocking;
- onDeadboltSMTransition();
- UNLOCKPIN.write(1);
- break;
- }
- imp.wakeup(0.05, deadboltSM);
- }
- /**
- * Called when deadboltSM transitions. You have to
- * remember to put this in the SM transitions.
- */
- function onDeadboltSMTransition(){
- timeLastDeadboltSMChange = hardware.millis();
- // server.log(format("%s %i", "State: ", deadboltState));
- }
- /**
- * Blinks an LED
- */
- function blink(){
- /* Change State */
- ledState = ledState?0:1;
- /* Reflect state to pin */
- LEDPIN.write(ledState);
- /* Schedule the next state change */
- imp.wakeup(1, blink);
- }
- /**
- * Searches through card list and if match found, grants access.
- * In both cases reports to server.
- */
- function grantOrDeny(){
- local foundCard = 0;
- /* Iterate through the array and try to find scanned card */
- allowedIDs.seek(0); /* Move read/write head to beginning */
- for(local i = 0; !allowedIDs.eos(); i++){
- local id = allowedIDs.readn('i');
- if(id == currentCard){
- local s = format("Access Granted: %s", allowedNames[i]);
- server.log(s);
- agent.send("accessLog",s);
- accessGranted = 1;
- foundCard = 1;
- break;
- }
- }
- /* If access denied */
- if(foundCard == 0){
- /* Look for them in the known cards list (but don't grand access) */
- otherIDs.seek(0); /* Move read/write head to beginning */
- for(local i = 0; !otherIDs.eos(); i++){
- local id = otherIDs.readn('i');
- if(id == currentCard){
- local s = format("Access Denied: %s", otherNames[i]);
- server.log(s);
- agent.send("accessLog", s);
- foundCard = 1;
- break;
- }
- }
- /* If they are not on either list */
- if(foundCard == 0){
- /* Show number on back of card as well as full card with parity bits */
- local s = format("Access Denied: %i 0x%08X", (currentCard & 0x03FFFE) >> 1 , currentCard);
- server.log(s);
- agent.send("accessLog", s);
- }
- }
- }
- /**
- * Event handler for UART data ready flag.
- * Reads UART (RS-232) output from HID reader.
- * Puts data in buffer until buffer has a full card.
- */
- function readSerial() {
- local result;
- do {
- result = hardware.uart12.read();
- /* Ignore lack of data */
- if(result != -1){
- currentCardBytessReceived++;
- timeLastByteReceived = hardware.millis();
- /* Only record bytes 5-12 from the reader */
- if(currentCardBytessReceived >= 5
- && currentCardBytessReceived <= 12){
- /* Shift by four to make room for new nibble */
- currentCard = currentCard << 4;
- /** Decode the "ASCII" byte and add to card */
- /* If ASCII-encoded 0-9, subtract 0 (hex 0x30) */
- if(result >= 0x30 && result <= 0x39){
- result -= 0x30;
- }
- /* If ASCII-encoded A-F, subtract ('A'-10) (hex 0x41-0x0A) */
- else if(result <= 0x46){
- result -= 0x41-0x0A;
- }
- else{
- server.log("Invalid character read from UART");
- }
- /* Add the nibble to the card buffer */
- currentCard += result;
- }
- /* When enough card data appears, grant or deny access*/
- if(currentCardBytessReceived == 12){
- grantOrDeny();
- }
- }
- } while (result != -1);
- }
- function monitorBits(){
- server.log(format("%08X", currentCard));
- // server.log(format("%i",currentCardBitsReceived));
- imp.wakeup(1, monitorBits);
- }
- /**
- * Clears card buffer after a certain amount of time.
- * Redundancy to remove any stray bytes on UART.
- */
- function clearBits(){
- if(hardware.millis() - timeLastByteReceived > 1000){
- currentCard = 0;
- currentCardBytessReceived = 0;
- }
- imp.wakeup(3, clearBits);
- }
- /**
- * Logs all door opens/closes. (callback function for switch pin)
- */
- function switchChanged(){
- local status = DOORSWITCH.read();
- if(status == 0){
- server.log("Door locked");
- }
- else{
- server.log("Door unlocked");
- agent.send("unlockedLog", status);
- }
- }
- /**
- * Periodically logs whether door open/closed.
- *
- * It makes the log look nicer if you constantly output correct data
- so that when a new open/close comes, there is not a giant ramp as
- the graph tries to linearly interpolate between "open" and "closed".
- * Schdules itself to repeat. This
- * needs to be a seperate function from the callback, otherwise the callback
- * would schedule itself and there would be too many callbacks.
- */
- function logSwitch(){
- agent.send("unlockedLog", DOORSWITCH.read());
- imp.wakeup(180.0, logSwitch);
- }
- /* Configure a pin pair for UART TX/RX */
- hardware.uart12.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS, readSerial);
- /* Configure pins */
- UNLOCKPIN.configure(DIGITAL_OUT);
- LOCKPIN.configure(DIGITAL_OUT);
- LEDPIN.configure(DIGITAL_OUT);
- DOORSWITCH.configure(DIGITAL_IN_PULLUP, switchChanged);
- blink();
- //monitorBits();
- clearBits();
- deadboltSM();
- //logSwitch();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement