You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Arduino loop函数中do-while循环内按钮无法读取问题求助

问题分析与解决方案:按钮无响应的根源与修复

嘿,我一眼就揪出问题所在了——你的按钮检测代码完全被卡在do-while循环外面了!

你看,当前代码逻辑是:程序会一直泡在do-while循环里,反复执行getID()、切换LED模式,直到successRead变成true(也就是成功读到卡片)。只有这时候,程序才会跳出循环,去执行后面的按钮检测代码。这就意味着,平时没刷卡片的时候,程序根本没机会去读取按钮状态,按按钮当然没反应!单独测试按钮代码没问题,是因为那时候没有这个霸占着程序的do-while循环。

修复方案:把按钮检测逻辑移到do-while循环内部

我们需要让程序在每次循环LED模式、检测卡片的同时,也顺便检查按钮状态,这样就不会错过任何一次按钮输入了。修改后的代码如下:

void loop() { 
  do { 
    successRead = getID(); 
    // --- 把按钮检测移到这里,每次循环都检查 ---
    buttonState = digitalRead(button); 
    if(buttonState != lastButtonState) { 
      if(buttonState == LOW){ 
        buttonPushCounter ++; 
        Serial.println("High"); 
        Serial.print("Number of button pushes : "); 
        Serial.println(buttonPushCounter); 
      } else{ 
        Serial.println("Low"); 
        Serial.println(buttonPushCounter); 
      } 
      delay(100); // 消抖延迟
    } 
    lastButtonState = buttonState;
    // --- 按钮检测结束 ---

    if (programMode) { 
      cycleLeds(); // 编程模式:循环切换红、绿、蓝LED,等待读取新卡片 
    } else { 
      normalModeOn(); // 正常模式:仅蓝色电源LED亮起,其余LED熄灭 
    } 
  } while (!successRead); 

  // 下面是卡片读取成功后的处理逻辑,保持不变
  if (programMode) { 
    if ( buttonPushCounter % 2 == 0 ) { 
      // 编程模式下:若再次扫描主卡则退出编程模式 
      Serial.println(F("Master Card Scanned")); 
      Serial.println(F("Exiting Program Mode")); 
      Serial.println(F("-----------------------------")); 
      programMode = false; 
      return; 
    } else { 
      if (findID(readCard) ) { 
        // 若扫描到已知卡片则删除 
        Serial.println(F("I know this PICC, removing...")); 
        deleteID(readCard); 
        Serial.println("-----------------------------"); 
        Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM")); 
      } else { 
        // 若扫描到未知卡片则添加 
        Serial.println(F("I do not know this PICC, adding...")); 
        writeID(readCard); 
        Serial.println(F("-----------------------------")); 
        Serial.println(F("Scan a PICC to ADD or REMOVE to EEPROM")); 
      } 
    } 
  } 
}

额外注意事项

  1. 按钮引脚初始化:确保你在setup()里已经正确设置了按钮引脚模式,比如用内部上拉电阻的话:

    pinMode(button, INPUT_PULLUP);
    

    这和你代码里检测LOW为按下的逻辑是匹配的。

  2. getID()的阻塞问题:如果getID()函数本身是阻塞式的(比如它会一直等待卡片,直到读取到才返回),那即使把按钮检测移到循环里,程序还是会被getID()卡住,无法及时响应按钮。这种情况下,你需要把getID()改成非阻塞式的——让它每次只检查一次卡片,不管有没有读到都立即返回,这样循环才能正常执行按钮检测。

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

火山引擎 最新活动