すべてのペースト #2FwN4njwWF Raw 編集

Fence Lock INO

公開 cpp v1 · 不変
·公開済み 2026-10-23 04:13 UTC
レンダリング済みのペースト本文
#include <Keypad.h>#include <SPI.h>#include <TFT_eSPI.h>#include <FS.h>#include <LittleFS.h>// --- Configurable Constants ---#define PASSCODE_FILE "/pass.txt"#define DEFAULT_CODE "#D36"#define HOLD_TIME_MS 2500 #define RELAY_PIN 5            // Relay successfully moved to safe GPIO 5#define RELAY_ON_TIME_MS 3000  // Relay trigger duration (3 seconds)// --- Keypad Setup ---const byte ROWS = 4; const byte COLS = 4; char keys[ROWS][COLS] = {  {'1','2','3','A'},  {'4','5','6','B'},  {'7','8','9','C'},  {'*','0','#','D'}};byte rowPins[ROWS] = {13, 12, 14, 27}; byte colPins[COLS] = {26, 25, 33, 32}; Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);// --- TFT Setup ---TFT_eSPI tft = TFT_eSPI(); // --- State Machine ---enum SystemState {   STATE_IDLE,   STATE_ENTER_PASSCODE,   STATE_AUTH_FOR_CHANGE,   STATE_CHANGE_PASSCODE,   STATE_VERIFY_PASSCODE };SystemState currentState = STATE_IDLE;String currentPasscode = DEFAULT_CODE;String enteredInput = "";String newPasscodeAttempt = "";// Timing variables for holding '#'unsigned long hashPressStartTime = 0;bool isHashBeingHeld = false;void setup() {  Serial.begin(115200);    // Set up the hardware relay pin control  pinMode(RELAY_PIN, OUTPUT);  digitalWrite(RELAY_PIN, LOW); // Start with relay deactivated (Locked)    tft.init();  tft.setRotation(0);    if (!LittleFS.begin(true)) {    Serial.println("LittleFS Mount Failed!");  } else {    loadPasscode();  }  showIdleScreen();}void loop() {  char key = customKeypad.getKey();  KeyState kstate = customKeypad.getState();  // --- 1. SPECIAL '#' HANDLING IN IDLE STATE ---  if (currentState == STATE_IDLE) {    if (key == '#' && kstate == PRESSED) {      isHashBeingHeld = true;      hashPressStartTime = millis();    }        if (isHashBeingHeld && (kstate == HOLD || kstate == PRESSED)) {      if (millis() - hashPressStartTime >= HOLD_TIME_MS) {        isHashBeingHeld = false;         enteredInput = "";        currentState = STATE_AUTH_FOR_CHANGE;         updateDisplay();         return;       }    }        if (kstate == RELEASED && isHashBeingHeld) {      isHashBeingHeld = false;      currentState = STATE_ENTER_PASSCODE;      enteredInput = "#";       updateDisplay();       return;    }  }  // --- 2. PROCESS NORMAL KEYPRESSES ---  if (key != NO_KEY) {        if (currentState == STATE_IDLE && key != '#') {      currentState = STATE_ENTER_PASSCODE;      enteredInput = String(key);       updateDisplay();      return;     }    if (currentState == STATE_ENTER_PASSCODE || currentState == STATE_AUTH_FOR_CHANGE ||         currentState == STATE_CHANGE_PASSCODE || currentState == STATE_VERIFY_PASSCODE) {            if (enteredInput.length() < 4) {        enteredInput += key;        updateDisplay();       }      if (enteredInput.length() == 4) {        delay(400);                 if (currentState == STATE_ENTER_PASSCODE) {          if (enteredInput == currentPasscode) {            triggerRelay();          } else {            flashMessage("WRONG PASSCODE", TFT_RED);          }          resetToIdle();        }         else if (currentState == STATE_AUTH_FOR_CHANGE) {          if (enteredInput == currentPasscode) {            enteredInput = "";            currentState = STATE_CHANGE_PASSCODE;            updateDisplay();          } else {            flashMessage("WRONG PASSCODE", TFT_RED);            resetToIdle();          }        }        else if (currentState == STATE_CHANGE_PASSCODE) { // Safe local matching string          newPasscodeAttempt = enteredInput;          enteredInput = "";          currentState = STATE_VERIFY_PASSCODE;          updateDisplay();        }         else if (currentState == STATE_VERIFY_PASSCODE) {          if (enteredInput == newPasscodeAttempt) {            currentPasscode = newPasscodeAttempt;            savePasscode(currentPasscode);                        tft.fillScreen(TFT_BLACK);            tft.setTextColor(TFT_GREEN, TFT_BLACK);            tft.setTextDatum(MC_DATUM);            tft.drawString("Passcode Changed", 120, 100, 4);            tft.drawString(currentPasscode, 120, 140, 4);            delay(2500);            resetToIdle();          } else {            flashMessage("MISMATCH! TRY AGAIN", TFT_RED);            enteredInput = "";            currentState = STATE_CHANGE_PASSCODE;             updateDisplay();          }        }      }    }  }}// --- 3. Hardware Interfacing Actions ---void triggerRelay() {  tft.fillScreen(TFT_BLACK);  tft.setTextColor(TFT_GREEN, TFT_BLACK);  tft.setTextDatum(MC_DATUM);  tft.drawString("ACCESS GRANTED", 120, 120, 4);    digitalWrite(RELAY_PIN, HIGH); // Turn relay ON (Unlock fence)  delay(RELAY_ON_TIME_MS);        // Hold for 3 seconds  digitalWrite(RELAY_PIN, LOW);  // Turn relay OFF (Lock fence)}// --- 4. Screen Drawing ---void showIdleScreen() {  tft.fillScreen(TFT_BLACK);  tft.setTextColor(TFT_WHITE, TFT_BLACK);  tft.setTextDatum(MC_DATUM);  tft.drawString("10:08", 120, 120, 7); }void updateDisplay() {  tft.fillScreen(TFT_BLACK);  tft.setTextColor(TFT_WHITE, TFT_BLACK);  tft.setTextDatum(TC_DATUM);  if (currentState == STATE_ENTER_PASSCODE) {    tft.drawString("Enter Passcode", 120, 50, 4);  } else if (currentState == STATE_AUTH_FOR_CHANGE) {    tft.drawString("Enter Passcode", 120, 35, 4);    tft.drawString("To Change Passcode", 120, 65, 2);  } else if (currentState == STATE_CHANGE_PASSCODE) {    tft.drawString("Change Passcode", 120, 50, 4);  } else if (currentState == STATE_VERIFY_PASSCODE) {    tft.drawString("Re-enter Passcode", 120, 50, 4);  }  int startX = 60;  int spacing = 40;  tft.setTextDatum(MC_DATUM);  for (int i = 0; i < 4; i++) {    int currentX = startX + (i * spacing);    if (i < enteredInput.length()) {      tft.drawString("*", currentX, 130, 4);      } else {      tft.drawString("_", currentX, 130, 4);      }  }}void flashMessage(String msg, uint16_t color) {  tft.fillScreen(TFT_BLACK);  tft.setTextColor(color, TFT_BLACK);  tft.setTextDatum(MC_DATUM);  tft.drawString(msg, 120, 120, 4);  delay(2000);}void resetToIdle() {  enteredInput = "";  newPasscodeAttempt = "";  isHashBeingHeld = false;   currentState = STATE_IDLE;  showIdleScreen();}// --- 5. Storage Persistence Layer ---void loadPasscode() {  if (LittleFS.exists(PASSCODE_FILE)) {    File file = LittleFS.open(PASSCODE_FILE, "r");    if (file) {      String saved = file.readStringUntil('\n');      saved.trim();      if (saved.length() == 4) {        currentPasscode = saved;        Serial.println("Loaded custom passcode: " + currentPasscode);      }      file.close();    }  }}void savePasscode(String newCode) {  File file = LittleFS.open(PASSCODE_FILE, "w");  if (file) {    file.println(newCode);    file.close();    Serial.println("Saved custom passcode to LittleFS: " + newCode);  }}