Přidání blokace zámku po X špatných pokusů
This commit is contained in:
+100
-9
@@ -33,6 +33,13 @@ bool isOpen = false;
|
|||||||
// enkodér
|
// enkodér
|
||||||
int lastCLK = HIGH;
|
int lastCLK = HIGH;
|
||||||
|
|
||||||
|
// blokace po špatných pokusech
|
||||||
|
constexpr byte MAX_WRONG_ATTEMPTS = 3;
|
||||||
|
constexpr unsigned long LOCKOUT_DURATION_MS = 30000UL;
|
||||||
|
byte wrongAttempts = 0;
|
||||||
|
bool lockedOut = false;
|
||||||
|
unsigned long lockoutStart = 0;
|
||||||
|
|
||||||
// maska – po kolika ms nečinnosti se heslo maskuje
|
// maska – po kolika ms nečinnosti se heslo maskuje
|
||||||
constexpr unsigned long MASK_DELAY_MS = 2000;
|
constexpr unsigned long MASK_DELAY_MS = 2000;
|
||||||
unsigned long lastEncoderMove = 0;
|
unsigned long lastEncoderMove = 0;
|
||||||
@@ -95,6 +102,15 @@ void NeutralLED() {
|
|||||||
analogWrite(RGB_RED_PIN, 0);
|
analogWrite(RGB_RED_PIN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// blikání červené během blokace
|
||||||
|
void BlockedLED() {
|
||||||
|
// bliká každých 500 ms
|
||||||
|
const bool blink = millis() / 500 % 2 == 0;
|
||||||
|
analogWrite(RGB_RED_PIN, blink ? 120 : 0);
|
||||||
|
analogWrite(RGB_GREEN_PIN, 0);
|
||||||
|
analogWrite(RGB_BLUE_PIN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ButtonPressed() {
|
void ButtonPressed() {
|
||||||
if (savedPassword != "")
|
if (savedPassword != "")
|
||||||
{
|
{
|
||||||
@@ -242,6 +258,58 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
// Serial Monitor – příkaz "unblock" zruší blokaci
|
||||||
|
if (Serial.available()) {
|
||||||
|
String cmd = Serial.readStringUntil('\n');
|
||||||
|
cmd.trim();
|
||||||
|
if (cmd == "unblock") {
|
||||||
|
if (lockedOut) {
|
||||||
|
lockedOut = false;
|
||||||
|
wrongAttempts = 0;
|
||||||
|
Serial.println("[SERIAL] Blokace zrusena. Zamek je stale zamcen.");
|
||||||
|
CloseLED();
|
||||||
|
password = 0;
|
||||||
|
masked = false;
|
||||||
|
lastEncoderMove = millis();
|
||||||
|
showEntryScreen(true);
|
||||||
|
} else {
|
||||||
|
Serial.println("[SERIAL] Zamek neni zablokovan.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("[SERIAL] Nezname prikazani. Pouzij: unblock");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blokace – čeká odpočítávání, neblokuje loop
|
||||||
|
if (lockedOut) {
|
||||||
|
if (const unsigned long elapsed = millis() - lockoutStart; elapsed >= LOCKOUT_DURATION_MS) {
|
||||||
|
// konec blokace
|
||||||
|
lockedOut = false;
|
||||||
|
wrongAttempts = 0;
|
||||||
|
Serial.println("Blokace skoncila.");
|
||||||
|
CloseLED();
|
||||||
|
password = 0;
|
||||||
|
masked = false;
|
||||||
|
lastEncoderMove = millis();
|
||||||
|
showEntryScreen(true);
|
||||||
|
} else {
|
||||||
|
// odpočítávání na LCD – aktualizuje jen každou sekundu
|
||||||
|
static unsigned long lastCountdownUpdate = 0;
|
||||||
|
if (millis() - lastCountdownUpdate >= 1000) {
|
||||||
|
lastCountdownUpdate = millis();
|
||||||
|
const int remaining = static_cast<int>((LOCKOUT_DURATION_MS - elapsed + 999) / 1000);
|
||||||
|
lcd.setCursor(0, 0);
|
||||||
|
lcd.printstr("Zablokovano! ");
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
String line = "Zbyva: " + String(remaining) + "s ";
|
||||||
|
line = line.substring(0, 16);
|
||||||
|
lcd.printstr(line.c_str());
|
||||||
|
}
|
||||||
|
BlockedLED();
|
||||||
|
}
|
||||||
|
return; // zbytek loop se přeskočí
|
||||||
|
}
|
||||||
|
|
||||||
// čtení enkodéru – jen pokud je zamčeno
|
// čtení enkodéru – jen pokud je zamčeno
|
||||||
// (při odemčeném stavu enkodér nemá smysl)
|
// (při odemčeném stavu enkodér nemá smysl)
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
@@ -275,6 +343,7 @@ void loop() {
|
|||||||
// pokus o odemčení
|
// pokus o odemčení
|
||||||
if (formatCode(password) == savedPassword) {
|
if (formatCode(password) == savedPassword) {
|
||||||
isOpen = true;
|
isOpen = true;
|
||||||
|
wrongAttempts = 0; // reset po úspěšném odemčení
|
||||||
OpenLock();
|
OpenLock();
|
||||||
OpenLED();
|
OpenLED();
|
||||||
OpenSound();
|
OpenSound();
|
||||||
@@ -284,18 +353,40 @@ void loop() {
|
|||||||
lcd.setCursor(0, 1);
|
lcd.setCursor(0, 1);
|
||||||
lcd.printstr("Stiskni pro zamk");
|
lcd.printstr("Stiskni pro zamk");
|
||||||
} else {
|
} else {
|
||||||
|
// špatné heslo
|
||||||
|
wrongAttempts++;
|
||||||
|
Serial.print("Spatny pokus: ");
|
||||||
|
Serial.print(wrongAttempts);
|
||||||
|
Serial.print("/");
|
||||||
|
Serial.println(MAX_WRONG_ATTEMPTS);
|
||||||
|
|
||||||
CloseSound();
|
CloseSound();
|
||||||
|
|
||||||
lcd.setCursor(0, 0);
|
if (wrongAttempts >= MAX_WRONG_ATTEMPTS) {
|
||||||
lcd.printstr("Spatne heslo! ");
|
// spustit blokaci
|
||||||
lcd.setCursor(0, 1);
|
lockedOut = true;
|
||||||
lcd.printstr(" ");
|
lockoutStart = millis();
|
||||||
delay(1500);
|
Serial.println("Zamek zablokovan na 30 sekund. Pouzij 'unblock' pro zruseni.");
|
||||||
|
|
||||||
// návrat na zadávací obrazovku, hodnota zachována
|
lcd.setCursor(0, 0);
|
||||||
masked = false;
|
lcd.printstr("Zablokovano! ");
|
||||||
lastEncoderMove = millis();
|
lcd.setCursor(0, 1);
|
||||||
showEntryScreen(true);
|
lcd.printstr("Zbyva: 30s ");
|
||||||
|
BlockedLED();
|
||||||
|
} else {
|
||||||
|
lcd.setCursor(0, 0);
|
||||||
|
String warn = "Spatne! (" + String(wrongAttempts) + "/" + String(MAX_WRONG_ATTEMPTS) + ") ";
|
||||||
|
warn = warn.substring(0, 16);
|
||||||
|
lcd.printstr(warn.c_str());
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
lcd.printstr(" ");
|
||||||
|
delay(1500);
|
||||||
|
|
||||||
|
// návrat na zadávací obrazovku, hodnota zachována
|
||||||
|
masked = false;
|
||||||
|
lastEncoderMove = millis();
|
||||||
|
showEntryScreen(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// zamčení
|
// zamčení
|
||||||
|
|||||||
Reference in New Issue
Block a user