Add RFID card scanning off a list of card numbers

This commit is contained in:
Tanner Collin 2018-11-10 14:56:50 -07:00
parent 506f286990
commit a8331ab798

View File

@ -6,7 +6,22 @@
const char* WIFI_SSID = "Protospace"; const char* WIFI_SSID = "Protospace";
const char* WIFI_PASS = "yycmakers"; const char* WIFI_PASS = "yycmakers";
char wifiMACAddr[18]; char wifiMACAddr[18];
const String API_ROUTE = String("http://tools-socket.protospace.ca/api/lockout/"); const String SOCKET_URL = String("http://tools-socket.protospace.ca/api/lockout/");
const String CARD_URL = String("http://tools-auth.protospace.ca/cards/");
#define CARD_BUFFER_LENGTH 14
char cardBuffer[CARD_BUFFER_LENGTH];
#define CARD_DATA_LENGTH 10
#define CARD_CHECK_LENGTH 2
typedef struct __attribute__((packed)) cardData {
char head;
char data[CARD_DATA_LENGTH];
char checksum[CARD_CHECK_LENGTH];
char tail;
} cardData_t;
String authorizedCards = String("00000C5123,00000D1234,00000C5999,00000C5998,00000C5666");
#define RELAY_PIN D1 #define RELAY_PIN D1
#define GREEN_BUTTON_PIN D3 #define GREEN_BUTTON_PIN D3
@ -23,8 +38,10 @@ const String API_ROUTE = String("http://tools-socket.protospace.ca/api/lockout/"
#define LOGGING true #define LOGGING true
#define DELAY_TIME 10 #define ONE_SECOND 1000
#define COMM_IDLE_TIME 500 / DELAY_TIME #define DELAY_TIME ONE_SECOND / 100
#define COMM_LOCK_IDLE_TIME ONE_SECOND / 2
#define COMM_CARD_IDLE_TIME ONE_SECOND * 60 * 5
enum wifiStates enum wifiStates
{ {
@ -38,7 +55,7 @@ enum lockStates
LOCK_OFF, LOCK_OFF,
LOCK_PREARM, LOCK_PREARM,
LOCK_ARMED, LOCK_ARMED,
LOCK_ON_PRESSED, LOCK_ON_PRESSED, // to wait until button is released
LOCK_ON, LOCK_ON,
} lockState = LOCK_OFF; } lockState = LOCK_OFF;
@ -46,12 +63,13 @@ enum commStates
{ {
COMM_INIT, COMM_INIT,
COMM_IDLE, COMM_IDLE,
COMM_SEND, COMM_GET_LOCK,
COMM_GET_CARD,
} commState = COMM_INIT; } commState = COMM_INIT;
void setup() void setup()
{ {
if (LOGGING) Serial.begin(115200); Serial.begin(9600);
if (LOGGING) Serial.println("[INFO] Serial started."); if (LOGGING) Serial.println("[INFO] Serial started.");
pinMode(RELAY_PIN, OUTPUT); pinMode(RELAY_PIN, OUTPUT);
@ -67,14 +85,88 @@ void loop()
processLockState(); processLockState();
processCommState(); processCommState();
if (Serial.available() >= CARD_BUFFER_LENGTH) {
uint8_t bufPos = 0;
while (true) {
char readChar = Serial.read();
if (readChar == -1) {
break;
} else if (readChar == 0x2) {
bufPos = 0;
}
if (bufPos >= CARD_BUFFER_LENGTH) {
break;
}
cardBuffer[bufPos++] = readChar;
if (readChar == 0x3 && bufPos == CARD_BUFFER_LENGTH) {
checkCard();
break;
}
}
}
delay(DELAY_TIME); delay(DELAY_TIME);
} }
int8_t charToNum(char input) {
return String("0123456789ABCDEF").indexOf(input);
}
bool checksum(cardData_t *cardData) {
// checksum is each hex data byte xord'd together.
// each char is a hex nibble, so we have to work in pairs.
int8_t even = 0, odd = 0;
for (int i = 0; i < CARD_DATA_LENGTH; i++) {
int8_t num = charToNum(cardData->data[i]);
if (num == -1) return false;
if (i % 2 == 0) even ^= num;
if (i % 2 == 1) odd ^= num;
}
int8_t checksum_even = charToNum(cardData->checksum[0]);
int8_t checksum_odd = charToNum(cardData->checksum[1]);
if (even == checksum_even && odd == checksum_odd) {
return true;
} else {
return false;
}
}
void checkCard() {
cardData_t *cardData = (cardData_t *) cardBuffer;
if (cardData->head == 0x2 && cardData->tail == 0x3 && checksum(cardData)) {
String cardStr = String();
for (int i = 0; i < CARD_DATA_LENGTH; i++)
cardStr += cardData->data[i];
if (LOGGING) Serial.println("[INFO] Good scan from card: " + cardStr);
if (authorizedCards.indexOf(cardStr) >= 0) {
if (LOGGING) Serial.println("[INFO] Card is authorized on machine.");
if (lockState == LOCK_OFF) {
lockState = LOCK_PREARM;
}
} else {
if (LOGGING) Serial.println("[INFO] Card not authorized or machine.");
}
}
}
void processWifiState() void processWifiState()
{ {
switch(wifiState) { switch(wifiState) {
case WIFI_DISCONNECTED: case WIFI_DISCONNECTED:
lockState = LOCK_OFF;
commState = COMM_INIT; commState = COMM_INIT;
if (LOGGING) Serial.println("[INFO] Wifi is disconnected. Attempting to connect..."); if (LOGGING) Serial.println("[INFO] Wifi is disconnected. Attempting to connect...");
@ -83,7 +175,6 @@ void processWifiState()
wifiState = WIFI_CONNECTING; wifiState = WIFI_CONNECTING;
break; break;
case WIFI_CONNECTING: case WIFI_CONNECTING:
lockState = LOCK_OFF;
commState = COMM_INIT; commState = COMM_INIT;
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
@ -148,7 +239,7 @@ void processLockState()
if (redButton()) { if (redButton()) {
if (LOGGING) Serial.println("[INFO] Unarming interlock."); if (LOGGING) Serial.println("[INFO] Unarming interlock.");
lockState = LOCK_OFF_PRESSED; lockState = LOCK_OFF;
} else if (greenButton()) { } else if (greenButton()) {
if (LOGGING) Serial.println("[INFO] On button pressed."); if (LOGGING) Serial.println("[INFO] On button pressed.");
lockState = LOCK_ON_PRESSED; lockState = LOCK_ON_PRESSED;
@ -157,7 +248,7 @@ void processLockState()
case LOCK_ON_PRESSED: case LOCK_ON_PRESSED:
if (redButton()) { if (redButton()) {
if (LOGGING) Serial.println("[ERROR] Off button pressed, aborting."); if (LOGGING) Serial.println("[ERROR] Off button pressed, aborting.");
lockState = LOCK_OFF_PRESSED; lockState = LOCK_OFF;
} else if (!greenButton()) { } else if (!greenButton()) {
if (LOGGING) Serial.println("[INFO] Turning machine on."); if (LOGGING) Serial.println("[INFO] Turning machine on.");
lockState = LOCK_ON; lockState = LOCK_ON;
@ -182,20 +273,20 @@ void processLockState()
} }
// JSON functions to prevent memory leaking // JSON functions to prevent memory leaking
String serializeJson(int lockState) { String serializeLockJson(uint8_t lockState) {
// Generated with: https://arduinojson.org/assistant/ // Generated with: https://arduinojson.org/assistant/
const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50; const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50;
DynamicJsonBuffer jsonBuffer(bufferSize); DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.createObject(); JsonObject& root = jsonBuffer.createObject();
root["lockState"] = (int) lockState; root["lockState"] = (uint8_t) lockState;
String postData = String(); String postData = String();
root.printTo(postData); root.printTo(postData);
return postData; return postData;
} }
String deserializeJson(String input) { String deserializeLockJson(String input) {
// Generated with: https://arduinojson.org/assistant/ // Generated with: https://arduinojson.org/assistant/
const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50; const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50;
DynamicJsonBuffer jsonBuffer(bufferSize); DynamicJsonBuffer jsonBuffer(bufferSize);
@ -208,30 +299,37 @@ String deserializeJson(String input) {
void processCommState() void processCommState()
{ {
static int commIdleCount = 0; static uint16_t commLockIdleCount = 0;
static uint16_t commCardIdleCount = 0;
switch (commState) { switch (commState) {
case COMM_INIT: case COMM_INIT:
commIdleCount = 0; commLockIdleCount = 0;
commCardIdleCount = 0;
commState = COMM_IDLE; commState = COMM_IDLE;
break; break;
case COMM_IDLE: case COMM_IDLE:
commIdleCount++; commLockIdleCount++;
if (commIdleCount >= COMM_IDLE_TIME) { commCardIdleCount++;
commState = COMM_SEND;
if (commLockIdleCount >= COMM_LOCK_IDLE_TIME / DELAY_TIME) {
commState = COMM_GET_LOCK;
} else if (commCardIdleCount >= COMM_CARD_IDLE_TIME / DELAY_TIME) {
commState = COMM_GET_CARD;
} }
break; break;
case COMM_SEND: case COMM_GET_LOCK:
if (LOGGING) Serial.println("[INFO] HTTP begin."); if (LOGGING) Serial.println("[INFO] Lock state HTTP begin.");
HTTPClient http; HTTPClient http;
//http.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS //http.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin(API_ROUTE + wifiMACAddr); http.begin(SOCKET_URL + wifiMACAddr);
http.addHeader("Content-Type", "application/json"); http.addHeader("Content-Type", "application/json");
if (LOGGING) Serial.print("[INFO] HTTP POST: "); if (LOGGING) Serial.print("[INFO] HTTP POST: ");
String postData = serializeJson(lockState); String postData = serializeLockJson(lockState);
if (LOGGING) Serial.println(postData); if (LOGGING) Serial.println(postData);
int httpCode = http.POST(postData); uint16_t httpCode = http.POST(postData);
if (httpCode > 0) { if (httpCode > 0) {
if (LOGGING) Serial.printf("[INFO] POST success, code: %d\n", httpCode); if (LOGGING) Serial.printf("[INFO] POST success, code: %d\n", httpCode);
@ -240,10 +338,10 @@ void processCommState()
if (LOGGING) Serial.print("[INFO] Resource found, parsing response: "); if (LOGGING) Serial.print("[INFO] Resource found, parsing response: ");
String payload = http.getString(); String payload = http.getString();
if (LOGGING) Serial.println(payload); if (LOGGING) Serial.println(payload);
String action = deserializeJson(payload); String action = deserializeLockJson(payload);
if (action == "arm" && lockState == LOCK_OFF) { if (action == "arm" && lockState == LOCK_OFF) {
lockState = LOCK_PREARMED; lockState = LOCK_PREARM;
} else if (action == "disarm") { } else if (action == "disarm") {
lockState = LOCK_OFF; lockState = LOCK_OFF;
} }
@ -256,7 +354,9 @@ void processCommState()
if (LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", http.errorToString(httpCode).c_str()); if (LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", http.errorToString(httpCode).c_str());
} }
commState = COMM_INIT; commLockIdleCount = 0;
commState = COMM_IDLE;
break; break;
} }
} }