diff --git a/firmware/firmware.ino b/firmware/firmware.ino index e50cc71..7a1d820 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -37,12 +37,13 @@ typedef struct __attribute__((packed)) cardData { #define RELAY_OPEN !RELAY_CLOSED #define BUTTON_CLOSED LOW #define BUTTON_OPEN !BUTTON_CLOSED -#define LED_ON HIGH -#define LED_OFF !LED_ON +#define LED_PIN_ON HIGH +#define LED_PIN_OFF !LED_PIN_ON #define DELAY_TIME 10 #define COMM_LOCK_IDLE_TIME 50 #define COMM_CARD_IDLE_TIME 1000 +#define LED_DENIED_IDLE_TIME 30 #define EEPROM_SIZE 4095 #define EEPROM_START 0 @@ -54,6 +55,15 @@ enum wifiStates WIFI_CONNECTED, } wifiState = WIFI_DISCONNECTED; +enum LEDStates +{ + LED_OFF, + LED_ARMED, + LED_ON, + LED_DENIED, + LED_DENIED_IDLE, +} LEDState = LED_OFF; + enum lockStates { LOCK_OFF, @@ -91,6 +101,7 @@ void setup() void tickerLoop() { processLockState(); + processLEDState(); if (Serial.available() >= CARD_BUFFER_LENGTH) { uint8_t bufPos = 0; @@ -111,7 +122,7 @@ void tickerLoop() cardBuffer[bufPos++] = readChar; if (readChar == 0x3 && bufPos == CARD_BUFFER_LENGTH) { - if (lockState == LOCK_OFF) checkCard(); + if (lockState == LOCK_OFF && LEDState == LED_OFF) checkCard(); break; } } @@ -183,6 +194,7 @@ void checkCard() } } else { if (LOGGING) Serial.println("[INFO] Card not authorized on machine."); + LEDState = LED_DENIED; } } } @@ -230,11 +242,6 @@ void processWifiState() bool greenButton() { return digitalRead(GREEN_BUTTON_PIN) == BUTTON_CLOSED; } bool redButton() { return digitalRead(RED_BUTTON_PIN) == BUTTON_CLOSED; } -void greenLEDOn() { digitalWrite(GREEN_LED_PIN, LED_ON); } -void greenLEDOff() { digitalWrite(GREEN_LED_PIN, LED_OFF); } -void redLEDOn() { digitalWrite(RED_LED_PIN, LED_ON); } -void redLEDOff() { digitalWrite(RED_LED_PIN, LED_OFF); } - void relayOn() { digitalWrite(RELAY_PIN, RELAY_CLOSED); } void relayOff() { digitalWrite(RELAY_PIN, RELAY_OPEN); } @@ -242,8 +249,7 @@ void processLockState() { switch (lockState) { case LOCK_OFF: - greenLEDOff(); - redLEDOff(); + if (LEDState < LED_DENIED) LEDState = LED_OFF; relayOff(); break; @@ -256,8 +262,7 @@ void processLockState() } break; case LOCK_ARMED: - greenLEDOn(); - redLEDOff(); + if (LEDState < LED_DENIED) LEDState = LED_ARMED; relayOff(); @@ -279,8 +284,7 @@ void processLockState() } break; case LOCK_ON: - greenLEDOff(); - redLEDOn(); + if (LEDState < LED_DENIED) LEDState = LED_ON; relayOn(); @@ -296,6 +300,56 @@ void processLockState() } } +void greenLEDOn() { digitalWrite(GREEN_LED_PIN, LED_PIN_ON); } +void greenLEDOff() { digitalWrite(GREEN_LED_PIN, LED_PIN_OFF); } +void redLEDOn() { digitalWrite(RED_LED_PIN, LED_PIN_ON); } +void redLEDOff() { digitalWrite(RED_LED_PIN, LED_PIN_OFF); } + +void processLEDState() +{ + static uint16_t LEDDeniedIdleCount = 0; + + switch (LEDState) { + case LED_OFF: + greenLEDOff(); + redLEDOff(); + + break; + case LED_ARMED: + greenLEDOn(); + redLEDOff(); + + break; + case LED_ON: + greenLEDOff(); + redLEDOn(); + + break; + case LED_DENIED: + LEDDeniedIdleCount = 0; + + LEDState = LED_DENIED_IDLE; + break; + case LED_DENIED_IDLE: + LEDDeniedIdleCount++; + + if (LEDDeniedIdleCount < LED_DENIED_IDLE_TIME) { + greenLEDOff(); + redLEDOn(); + } else if (LEDDeniedIdleCount < LED_DENIED_IDLE_TIME * 2) { + greenLEDOff(); + redLEDOff(); + } else { + LEDState = LED_OFF; + } + break; + default: + if (LOGGING) Serial.println("[ERROR] Invalid lock state."); + LEDState = LED_OFF; + break; + } +} + // JSON functions to prevent memory leaking String serializeLockJson(uint8_t lockState) {