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

Arduino按键计数项目求助:实现预警后双击重置功能

Arduino按键计数项目:双击重置逻辑修复方案

核心问题分析

你的需求核心是仅在预警状态(计数超阈值)时,通过双击按键触发重置,常见问题点通常包括:

  • 双击检测逻辑未与预警状态绑定,导致非预警阶段也能触发重置
  • 双击时间窗口设置不合理,或按键消抖处理不到位引发误判
  • LED闪烁逻辑与按键检测逻辑冲突,导致状态切换异常

修复后的完整代码

#include <LiquidCrystal.h>

// 硬件引脚定义
const int btnPin = 2;
const int ledPin = 13;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // 根据实际接线调整
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// 配置参数
const int threshold = 10; // 预警阈值
const unsigned long doubleClickWindow = 500; // 双击检测时间窗口(毫秒)

// 状态变量
int count = 0;
bool isWarning = false;
unsigned long lastPressTime = 0;
int pressCount = 0;
bool btnState = HIGH;
bool lastBtnState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 按键消抖延迟

void setup() {
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  lcd.begin(16, 2);
  lcd.print("Count: ");
  lcd.setCursor(7, 0);
  lcd.print(count);
}

void loop() {
  // 按键消抖处理
  int reading = digitalRead(btnPin);
  if (reading != lastBtnState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != btnState) {
      btnState = reading;
      if (btnState == LOW) { // 按键按下(根据实际接线调整高低电平)
        handleButtonPress();
      }
    }
  }
  lastBtnState = reading;

  // 预警阶段LED非阻塞闪烁逻辑
  if (isWarning) {
    blinkLED();
  } else {
    digitalWrite(ledPin, LOW);
  }
}

void handleButtonPress() {
  if (!isWarning) {
    // 正常状态:累加计数并更新LCD
    count++;
    updateLCD();
    // 判断是否进入预警状态
    if (count > threshold) {
      isWarning = true;
      lcd.setCursor(0, 1);
      lcd.print("WARNING!");
    }
  } else {
    // 预警状态:处理双击重置逻辑
    unsigned long currentTime = millis();
    if (currentTime - lastPressTime <= doubleClickWindow) {
      // 触发双击:重置计数并退出预警
      count = 0;
      isWarning = false;
      updateLCD();
      lcd.setCursor(0, 1);
      lcd.print("          "); // 清除预警提示
      pressCount = 0;
    } else {
      // 第一次按键:记录时间,超时未触发双击则重置计数
      pressCount = 1;
      lastPressTime = currentTime;
      delay(doubleClickWindow + 10);
      if (pressCount == 1) {
        pressCount = 0;
      }
    }
  }
}

void updateLCD() {
  lcd.setCursor(7, 0);
  lcd.print("   "); // 清除原有数字避免重叠
  lcd.setCursor(7, 0);
  lcd.print(count);
}

void blinkLED() {
  static unsigned long lastBlinkTime = 0;
  const unsigned long blinkInterval = 500;
  if (millis() - lastBlinkTime >= blinkInterval) {
    lastBlinkTime = millis();
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}

关键修复点说明

  • 状态隔离:通过isWarning变量明确区分正常计数和预警状态,仅在预警状态下响应双击逻辑
  • 可靠双击检测:设置固定时间窗口,仅当两次按键间隔在窗口内才触发重置
  • 按键消抖:加入标准消抖逻辑,避免机械抖动导致的误触发
  • 非阻塞LED闪烁:使用millis()实现非阻塞闪烁,避免delay()阻塞按键检测
  • LCD优化:更新计数时先清除原有数字,防止数字重叠显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:55:32