alle Locker öffnen gleichzeitig, Hardcodes implementiert
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
// Hardware configuration
|
||||
const int RELAY_PINS[6] = {13, 12, 14, 27, 26, 25}; // Relay pins for doors 1-6
|
||||
const int DOOR_OPEN_TIME = 5000; // 5 seconds in milliseconds
|
||||
const int DOOR_OPEN_TIME = 10000;
|
||||
|
||||
// I2C devices
|
||||
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD with I2C address 0x27
|
||||
@@ -22,6 +22,15 @@ unsigned long lockoutEndTime = 0;
|
||||
const int MAX_FAILED_ATTEMPTS = 3;
|
||||
const unsigned long LOCKOUT_DURATION = 30000; // 30 seconds in milliseconds
|
||||
|
||||
// Door control state
|
||||
struct DoorState {
|
||||
bool isOpen;
|
||||
unsigned long openedAt;
|
||||
int doorNumber;
|
||||
};
|
||||
DoorState doorStates[6] = {{false, 0, 0}};
|
||||
bool doorsActive = false;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
@@ -82,11 +91,14 @@ void loop() {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle door timers (non-blocking)
|
||||
handleDoorTimers();
|
||||
|
||||
// Check if keypad button was pressed
|
||||
keypad.updateFIFO();
|
||||
char button = keypad.getButton();
|
||||
|
||||
if (button != 0 && !processingLoan) {
|
||||
if (button != 0 && !processingLoan && !doorsActive) {
|
||||
handleKeypadInput(button);
|
||||
}
|
||||
|
||||
@@ -101,8 +113,11 @@ void handleKeypadInput(char button) {
|
||||
// Submit code
|
||||
if (currentCode.length() == 6) {
|
||||
processLoanCode(currentCode);
|
||||
} else if (currentCode.length() == 8) {
|
||||
// Check for hardcode
|
||||
checkHardcode(currentCode);
|
||||
} else {
|
||||
showError("Code muss 6-stellig sein!");
|
||||
showError("Code: 6 oder 8 Ziffern!");
|
||||
currentCode = "";
|
||||
updateCodeDisplay();
|
||||
}
|
||||
@@ -114,7 +129,7 @@ void handleKeypadInput(char button) {
|
||||
lcd.print("Code eingeben: ");
|
||||
} else {
|
||||
// Add digit to code
|
||||
if (currentCode.length() < 6) {
|
||||
if (currentCode.length() < 8) {
|
||||
currentCode += button;
|
||||
updateCodeDisplay();
|
||||
}
|
||||
@@ -125,7 +140,7 @@ void updateCodeDisplay() {
|
||||
lcd.setCursor(0, 1);
|
||||
// Display asterisks for entered digits
|
||||
String display = "";
|
||||
for (int i = 0; i < currentCode.length(); i++) {
|
||||
for (unsigned int i = 0; i < currentCode.length(); i++) {
|
||||
display += "*";
|
||||
}
|
||||
// Pad with spaces
|
||||
@@ -198,15 +213,16 @@ void processLoanCode(String code) {
|
||||
lcd.print("Ausleihe");
|
||||
}
|
||||
|
||||
// Open doors one by one
|
||||
// Collect all door numbers to open
|
||||
JsonArray lockerArray = doc.as<JsonArray>();
|
||||
int doorNumbers[6];
|
||||
int doorCount = 0;
|
||||
|
||||
for (JsonVariant locker : lockerArray) {
|
||||
int doorNumber = locker.as<int>();
|
||||
if (doorNumber >= 1 && doorNumber <= 6) {
|
||||
if (doorNumber >= 1 && doorNumber <= 6 && doorCount < 6) {
|
||||
doorNumbers[doorCount] = doorNumber;
|
||||
doorCount++;
|
||||
openDoor(doorNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,19 +232,96 @@ void processLoanCode(String code) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open all doors simultaneously (non-blocking)
|
||||
openDoorsSimultaneous(doorNumbers, doorCount);
|
||||
|
||||
// Update loan status in backend
|
||||
if (isReturn) {
|
||||
setReturnDate(code);
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Rueckgabe OK!");
|
||||
} else {
|
||||
setTakeDate(code);
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Ausleihe OK!");
|
||||
}
|
||||
|
||||
// Wait for all doors to close, then show completion message
|
||||
// This will be handled by handleDoorTimers() and finishLoanProcess()
|
||||
processingLoan = false;
|
||||
}
|
||||
|
||||
void openDoorsSimultaneous(int doorNumbers[], int count) {
|
||||
doorsActive = true;
|
||||
unsigned long now = millis();
|
||||
|
||||
// Display which doors are opening
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Fach: ");
|
||||
|
||||
// Show door numbers
|
||||
for (int i = 0; i < count && i < 4; i++) { // Max 4 doors shown due to LCD width
|
||||
lcd.print(doorNumbers[i]);
|
||||
if (i < count - 1) lcd.print(",");
|
||||
}
|
||||
if (count > 4) {
|
||||
lcd.print("...");
|
||||
}
|
||||
|
||||
// Pad with spaces
|
||||
String padding = "";
|
||||
for (int i = 0; i < (10 - count * 2); i++) {
|
||||
padding += " ";
|
||||
}
|
||||
lcd.print(padding);
|
||||
|
||||
// Open all doors at the same time
|
||||
for (int i = 0; i < count; i++) {
|
||||
int doorNumber = doorNumbers[i];
|
||||
if (doorNumber >= 1 && doorNumber <= 6) {
|
||||
int pinIndex = doorNumber - 1;
|
||||
|
||||
// Activate relay (LOW = on for most relay modules)
|
||||
digitalWrite(RELAY_PINS[pinIndex], LOW);
|
||||
|
||||
// Track door state
|
||||
doorStates[pinIndex].isOpen = true;
|
||||
doorStates[pinIndex].openedAt = now;
|
||||
doorStates[pinIndex].doorNumber = doorNumber;
|
||||
|
||||
Serial.println("Opened door " + String(doorNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleDoorTimers() {
|
||||
if (!doorsActive) return;
|
||||
|
||||
unsigned long now = millis();
|
||||
bool anyDoorOpen = false;
|
||||
|
||||
// Check each door
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (doorStates[i].isOpen) {
|
||||
// Check if door should be closed
|
||||
if (now - doorStates[i].openedAt >= DOOR_OPEN_TIME) {
|
||||
// Close door
|
||||
digitalWrite(RELAY_PINS[i], HIGH);
|
||||
doorStates[i].isOpen = false;
|
||||
Serial.println("Closed door " + String(doorStates[i].doorNumber));
|
||||
} else {
|
||||
anyDoorOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no doors are open anymore, finish the process
|
||||
if (!anyDoorOpen) {
|
||||
doorsActive = false;
|
||||
finishLoanProcess();
|
||||
}
|
||||
}
|
||||
|
||||
void finishLoanProcess() {
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Vorgang OK!");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Vielen Dank!");
|
||||
|
||||
@@ -246,6 +339,7 @@ bool getLoanInfo(String loanCode, String &lockers, bool &isReturn) {
|
||||
String url = String(BACKEND_URL) + "/get-loan-by-code/" + API_KEY + "/" + loanCode;
|
||||
|
||||
http.begin(url);
|
||||
http.setTimeout(10000); // 10 second timeout
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode != 200) {
|
||||
@@ -298,32 +392,6 @@ bool getLoanInfo(String loanCode, String &lockers, bool &isReturn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void openDoor(int doorNumber) {
|
||||
if (doorNumber < 1 || doorNumber > 6) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pinIndex = doorNumber - 1;
|
||||
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Oeffne Fach ");
|
||||
lcd.print(doorNumber);
|
||||
lcd.print(" ");
|
||||
|
||||
Serial.println("Opening door " + String(doorNumber));
|
||||
|
||||
// Activate relay (LOW = on for most relay modules)
|
||||
digitalWrite(RELAY_PINS[pinIndex], LOW);
|
||||
|
||||
// Keep door open for specified time
|
||||
delay(DOOR_OPEN_TIME);
|
||||
|
||||
// Deactivate relay (close door)
|
||||
digitalWrite(RELAY_PINS[pinIndex], HIGH);
|
||||
|
||||
Serial.println("Door " + String(doorNumber) + " closed");
|
||||
}
|
||||
|
||||
bool setReturnDate(String loanCode) {
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
return false;
|
||||
@@ -333,6 +401,7 @@ bool setReturnDate(String loanCode) {
|
||||
String url = String(BACKEND_URL) + "/set-return-date/" + API_KEY + "/" + loanCode;
|
||||
|
||||
http.begin(url);
|
||||
http.setTimeout(10000); // 10 second timeout
|
||||
int httpCode = http.POST("");
|
||||
|
||||
bool success = (httpCode == 200);
|
||||
@@ -351,6 +420,7 @@ bool setTakeDate(String loanCode) {
|
||||
String url = String(BACKEND_URL) + "/set-take-date/" + API_KEY + "/" + loanCode;
|
||||
|
||||
http.begin(url);
|
||||
http.setTimeout(10000); // 10 second timeout
|
||||
int httpCode = http.POST("");
|
||||
|
||||
bool success = (httpCode == 200);
|
||||
@@ -373,6 +443,7 @@ void showError(String message) {
|
||||
void resetState() {
|
||||
currentCode = "";
|
||||
processingLoan = false;
|
||||
doorsActive = false;
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Code eingeben:");
|
||||
@@ -413,4 +484,59 @@ void connectToWiFi() {
|
||||
lcd.print("WiFi Fehler!");
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void checkHardcode(String code) {
|
||||
Serial.println("Checking hardcode: " + code);
|
||||
|
||||
// Check each door's hardcode
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (code == String(DOOR_HARDCODES[i])) {
|
||||
// Hardcode matched for door i+1
|
||||
Serial.println("Hardcode match for door " + String(i + 1));
|
||||
|
||||
// Reset failed attempts on successful hardcode
|
||||
failedAttempts = 0;
|
||||
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Notcode erkannt");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Fach: ");
|
||||
lcd.print(i + 1);
|
||||
|
||||
delay(1000);
|
||||
|
||||
// Open only this door
|
||||
int doorNumber = i + 1;
|
||||
openDoorsSimultaneous(&doorNumber, 1);
|
||||
|
||||
// Don't update backend (emergency access)
|
||||
processingLoan = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No hardcode matched
|
||||
failedAttempts++;
|
||||
|
||||
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
|
||||
lockoutEndTime = millis() + LOCKOUT_DURATION;
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("Zu viele Fehler!");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Gesperrt 30s");
|
||||
delay(2000);
|
||||
} else {
|
||||
showError("Ungueltiger Code!");
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("Versuch ");
|
||||
lcd.print(failedAttempts);
|
||||
lcd.print("/");
|
||||
lcd.print(MAX_FAILED_ATTEMPTS);
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
resetState();
|
||||
}
|
||||
Reference in New Issue
Block a user