You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino数字密码锁:for循环实现用户锁定功能技术求助

Arduino数字密码锁:修复验证循环与实现多次锁定功能

Hey there! Let's work through your combination lock issues step by step — I'll break down what's wrong with your current code, fix the validation loop, and show you how to add the progressive lock feature you want.

一、当前代码的核心问题分析

Your existing code has a few critical flaws in the validation and locking logic:

  1. 无效的for循环逻辑:当前的for loop runs 3 times instantly, giving you no time to adjust the switches and try again. It doesn't wait for you to press the verify button each time.
  2. 错误的锁定触发:The else { delay(10000); } line triggers a 10-second delay every time i != 3, including on the first or second failed attempt (not just after 3 mistakes).
  3. 缺少用户反馈:There's no visual cue (like the red LED) to tell you when you've entered the wrong password.
  4. 无按钮消抖:Mechanical button jitter might cause multiple unintended validation triggers when you press the verify button.

二、修复后的基础功能代码

Here's revised code that fixes all these issues and makes the lock work as intended:

// Pin and variable definitions
int switchPins[] = {A5, A4, A3, A2, A1, A0}; // Array for switch pins (cleaner than 6 separate variables)
int storedPassword[6]; // Array to store the saved password
const int setPasswordBtn = 8;
const int verifyBtn = 12;
const int greenLed = 2;
const int redLed = 4;

int failedAttempts = 0; // Track number of wrong tries
unsigned long lockExpiryTime = 0; // Store when the lock will end
bool isLocked = false; // Flag for lock state

void setup() {
  // Initialize input/output pins
  pinMode(setPasswordBtn, INPUT);
  pinMode(verifyBtn, INPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  
  // Set all switch pins as inputs
  for(int i = 0; i < 6; i++){
    pinMode(switchPins[i], INPUT);
  }
  
  Serial.begin(9600);
  digitalWrite(greenLed, LOW);
  digitalWrite(redLed, LOW);
}

void loop() {
  // Handle locked state first
  if(isLocked){
    if(millis() >= lockExpiryTime){
      // Lock time is up — unlock
      isLocked = false;
      failedAttempts = 0; // Reset failed attempts
      digitalWrite(redLed, LOW);
      Serial.println("Unlocked! You can try again.");
    }
    return; // Don't process other actions while locked
  }

  // Set password: Save switch states when set button is pressed
  if(digitalRead(setPasswordBtn) == HIGH){
    delay(50); // Debounce button
    if(digitalRead(setPasswordBtn) == HIGH){ // Confirm button is still pressed
      for(int i = 0; i < 6; i++){
        storedPassword[i] = digitalRead(switchPins[i]);
        Serial.print("Password bit ");
        Serial.print(i);
        Serial.print(": ");
        Serial.println(storedPassword[i]);
      }
      // Visual confirmation of saved password
      digitalWrite(greenLed, HIGH);
      delay(500);
      digitalWrite(greenLed, LOW);
      Serial.println("Password saved successfully!");
      
      // Wait for button release to avoid repeated triggers
      while(digitalRead(setPasswordBtn) == HIGH);
    }
  }

  // Verify password: Check switch states against saved password
  if(digitalRead(verifyBtn) == HIGH){
    delay(50); // Debounce button
    if(digitalRead(verifyBtn) == HIGH){
      bool passwordMatches = true;
      // Compare each switch state to the saved password
      for(int i = 0; i < 6; i++){
        if(digitalRead(switchPins[i]) != storedPassword[i]){
          passwordMatches = false;
          break;
        }
      }

      if(passwordMatches){
        // Correct password
        digitalWrite(greenLed, HIGH);
        digitalWrite(redLed, LOW);
        failedAttempts = 0; // Reset failed attempts
        Serial.println("Password correct!");
        // Wait for button release
        while(digitalRead(verifyBtn) == HIGH);
      } else {
        // Wrong password
        failedAttempts++;
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
        Serial.print("Wrong password! Attempts remaining: ");
        Serial.println(3 - failedAttempts);
        
        // Trigger lock if 3 failed attempts
        if(failedAttempts >= 3){
          isLocked = true;
          lockExpiryTime = millis() + 10000; // Lock for 10 seconds
          Serial.println("Too many wrong attempts! Locked for 10 seconds.");
        }
        
        // Give visual feedback, then wait for button release
        delay(1000);
        digitalWrite(redLed, LOW);
        while(digitalRead(verifyBtn) == HIGH);
      }
    }
  }
}

Key improvements in this code:

  • Array-based switch/password management:Cleaner and easier to maintain than 6 individual variables.
  • Failed attempt tracking:Uses failedAttempts to count mistakes, with each verify button press counting as one attempt (no more instant loops).
  • Non-blocking lock timer:Uses millis() instead of delay() so the program can still respond to the set password button (you can disable this if you want locks to block password changes too).
  • Button debouncing:Short delays prevent accidental multiple triggers from mechanical button jitter.
  • Clear user feedback:Red LED for wrong passwords, green LED for correct ones, plus serial monitor status messages.

三、实现多次锁定自定义时长

To add progressive locking (longer lock times after each repeated 3 failed attempts), you just need to track how many times the user has been locked, and adjust the lock duration accordingly:

Modified key variables and logic:

// Add new variables at the top
int lockCounter = 0; // Track how many times the user has been locked
const int baseLockTime = 10000; // Base lock duration (10 seconds)
const int lockTimeMultiplier = 2; // Double lock time each time (customize this!)

// Update the lock trigger logic:
if(failedAttempts >= 3){
  lockCounter++;
  isLocked = true;
  // Calculate lock time (example: double duration each lock)
  unsigned long currentLockTime = baseLockTime * pow(lockTimeMultiplier, lockCounter - 1);
  // Alternative: Add 5 seconds each time: currentLockTime = baseLockTime + (lockCounter - 1)*5000;
  lockExpiryTime = millis() + currentLockTime;
  
  Serial.print("Too many wrong attempts! Locked for ");
  Serial.print(currentLockTime / 1000);
  Serial.println(" seconds.");
}

// Update the unlock logic to keep track of lock count:
if(millis() >= lockExpiryTime){
  isLocked = false;
  failedAttempts = 0;
  digitalWrite(redLed, LOW);
  Serial.print("Unlocked! Next lock will be for ");
  Serial.print((baseLockTime * pow(lockTimeMultiplier, lockCounter)) / 1000);
  Serial.println(" seconds if you fail 3 times again.");
}

How this works:

  • lockCounter keeps track of how many times the user has been locked.
  • Lock duration scales based on lockCounter — you can customize the formula (double the time, add fixed seconds, etc.).
  • lockCounter doesn't reset when unlocked, so the lock time keeps increasing until you add a reset feature (like holding the set password button for 3 seconds to reset all lock counts).

内容的提问来源于stack exchange,提问作者Placidium

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:48:39