Arduino-C++布尔值无法从False转为True:NFC门锁状态异常如何解决?
Hey there! Let's break down why your lock isn't switching between locked/unlocked states when you swipe the card:
The Root Problem: Variable Scope Mistakes
Your code has two critical issues with how you're handling the locked state variable:
- You're resetting the state every time - Inside the
loop()function's NFC logic, you declarebool locked = false;every time a card is read. That means every swipe starts withlockedset tofalse, so it always tries to lock the door. - You're redefining the variable instead of updating it - When you do
bool locked = true;inside the if block, you're creating a brand new local variable that only exists inside that block. It doesn't change thelockedvariable you declared earlier at all.
No wonder it only ever locks the door!
The Fix
We need to make the locked state persist between swipes, and update it correctly without redefining it. Here's how:
Step 1: Move locked to Global Scope
Declare the locked variable outside of any function (at the top of your code) so its value stays intact between calls to loop():
// Global variable to track door state - starts unlocked (false) bool locked = false; // Also, let's make motor pin a global constant to avoid repeating it const int MOTOR_PIN = 3; // And move the valid UID to a global constant too const byte VALID_UID[4] = { 0xEB, 0xA6, 0xE9, 0x21 };
Step 2: Update the NFC Logic
Remove the local locked declaration inside loop(), and fix how you update the state. We can also clean up the logic to avoid repeating code:
// Inside loop(), replace your existing NFC state checks with this: if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; Serial.print(F("Card UID:")); dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); // Check if the card is valid if (memcmp(VALID_UID, mfrc522.uid.uidByte, mfrc522.uid.size) == 0) { if (!locked) { // Lock the door Serial.println(" - Door Locked"); digitalWrite(MOTOR_PIN, HIGH); delay(5000); digitalWrite(MOTOR_PIN, LOW); locked = true; // Update the global state - NO bool keyword here! } else { // Unlock the door Serial.println(" - Door Unlocked"); digitalWrite(MOTOR_PIN, HIGH); delay(5000); digitalWrite(MOTOR_PIN, LOW); locked = false; // Again, update the global variable } } else { Serial.println(" - Invalid Card"); }
Step 3: Initialize the Motor Pin
Don't forget to set the motor pin as an output in setup():
void setup() { // ... your existing setup code (SPI, Serial, MFRC522 init, etc.) pinMode(MOTOR_PIN, OUTPUT); digitalWrite(MOTOR_PIN, LOW); // Make sure motor starts off }
Why This Works
- The global
lockedvariable keeps its value between swipes, so the code remembers whether the door is currently locked or unlocked. - By removing the
boolkeyword when updatinglocked, we're modifying the existing global variable instead of creating a new local one. - We've cleaned up redundant code (no more repeating the valid UID check or motor pin declaration) to make the code easier to maintain.
With these changes, every swipe of your valid NFC card will toggle the door between locked and unlocked states as expected.
内容的提问来源于stack exchange,提问作者Brendan Jowett

