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

基于Arduino的双按键LED闪烁时长调节问题求助

Arduino按键控制LED闪烁时长问题排查与修复

问题描述

基于Arduino UNO制作电路,需求为:

  • LED默认闪烁时长0.5秒
  • 按键1按下时,闪烁时长增加0.1秒
  • 按键2按下时,闪烁时长减少0.1秒

实际运行出现异常:时长卡在500ms和600ms之间,未操作按键时程序也会自动增减时长。

原代码

const int led = 7;
const int buttonUp = 6;
const int buttonDown = 5;
int duration = 500;

void setup(){
  pinMode(led, OUTPUT);
  pinMode(buttonUp, INPUT);
  pinMode(buttonDown, INPUT);
  Serial.begin(9600);
}

void loop(){
  int inc = digitalRead(buttonUp);
  int dec = digitalRead(buttonDown);
  
  if(inc == HIGH){
      duration += 100;
      Serial.println(duration);
  }
  
  if(dec == HIGH){
      duration -= 100;
      if(duration < 0){
          duration = 100;
      }
      Serial.println(duration);
  }
  
  digitalWrite(led, HIGH);
  delay(duration);
  digitalWrite(led, LOW);
  delay(duration);
  
}

问题原因

  1. 按键引脚浮空,电平不稳定:
    代码中按键引脚设置为INPUT,未启用内部上拉或外接下拉电阻。按键未按下时,引脚处于浮空状态,受环境干扰会出现随机电平跳变,导致程序误判按键被触发。
  2. 无消抖与单次触发逻辑:
    按键机械结构会产生抖动,且loop()会反复执行检测,只要按键保持按下状态,每次循环都会执行增减操作,导致时长连续变化,同时抖动也会引发误触发。

修复方案

1. 硬件调整(二选一)

  • 给每个按键外接10kΩ下拉电阻(一端接引脚,一端接GND),确保未按下时引脚为LOW电平。
  • 启用Arduino内部上拉电阻,无需外接电阻,对应调整代码中的电平判断逻辑。

2. 修复后代码(启用内部上拉版本)

const int led = 7;
const int buttonUp = 6;
const int buttonDown = 5;
int duration = 500;

// 按键状态与消抖变量
int lastUpState = HIGH;
int lastDownState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 50ms消抖延时

void setup(){
  pinMode(led, OUTPUT);
  pinMode(buttonUp, INPUT_PULLUP); // 启用内部上拉电阻
  pinMode(buttonDown, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop(){
  int currentUpState = digitalRead(buttonUp);
  int currentDownState = digitalRead(buttonDown);
  unsigned long currentTime = millis();

  // 处理递增按键
  if (currentUpState != lastUpState) {
    lastDebounceTime = currentTime;
  }
  if ((currentTime - lastDebounceTime) > debounceDelay) {
    // 检测按键按下的下降沿(上拉模式下,按下为LOW)
    if (currentUpState == LOW && lastUpState == HIGH) {
      duration += 100;
      Serial.println(duration);
    }
    lastUpState = currentUpState;
  }

  // 处理递减按键
  if (currentDownState != lastDownState) {
    lastDebounceTime = currentTime;
  }
  if ((currentTime - lastDebounceTime) > debounceDelay) {
    if (currentDownState == LOW && lastDownState == HIGH) {
      duration -= 100;
      if (duration < 100) { // 限制最小时长为100ms
          duration = 100;
      }
      Serial.println(duration);
    }
    lastDownState = currentDownState;
  }

  // LED闪烁逻辑
  digitalWrite(led, HIGH);
  delay(duration);
  digitalWrite(led, LOW);
  delay(duration);
}

代码说明

  • 内部上拉电阻:通过INPUT_PULLUP设置引脚,未按下时引脚为HIGH,按下时接地变为LOW,彻底解决浮空问题。
  • 消抖处理:使用millis()实现非阻塞消抖,等待50ms确认电平稳定,避免机械抖动引发的误触发。
  • 单次触发:检测按键的下降沿(HIGH→LOW),确保每次按下仅执行一次增减操作,不会持续变化。
  • 边界限制:将最小时长设为100ms,避免出现无效的0或负时长。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:10:30