基于Arduino的按键计数需求:长按按键不触发计数增量
Arduino实现单次按键计数(忽略长按)
这个需求其实很常见,核心就是区分短按和长按,用非阻塞式的计时方式就能解决,还不会影响程序里其他逻辑的运行。我给你整理了完整的实现思路和代码,你可以直接参考:
完整代码示例
// 定义引脚和核心参数 const int buttonPin = 2; // 按键连接的引脚 int counter1 = 0; // 需要计数的变量 unsigned long pressStartTime = 0; // 记录按键按下的起始时间点 bool isPressed = false; // 标记按键是否处于按下状态 const unsigned long shortPressThreshold = 200; // 短按阈值(单位:ms,可按需调整) void setup() { pinMode(buttonPin, INPUT_PULLUP); // 使用内部上拉电阻,按键按下时为低电平 Serial.begin(9600); // 打开串口用于调试(可选,方便看计数结果) } void loop() { int buttonState = digitalRead(buttonPin); // 检测按键按下(带简单消抖) if (buttonState == LOW && !isPressed) { delay(5); // 消抖:等待5ms后再次确认按键状态 if (digitalRead(buttonPin) == LOW) { pressStartTime = millis(); // 记录按下的时间点 isPressed = true; } } // 检测按键释放,判断长按/短按 if (buttonState == HIGH && isPressed) { delay(5); // 再次消抖确认 if (digitalRead(buttonPin) == HIGH) { unsigned long pressDuration = millis() - pressStartTime; // 计算按键按下的总时长 // 只有短按(时长小于阈值)才触发计数 if (pressDuration < shortPressThreshold) { counter1++; Serial.print("Counter1 当前值: "); Serial.println(counter1); // 串口输出计数结果(可选) } isPressed = false; // 重置按键状态标记 } } // 这里可以添加你的其他项目逻辑,不会被按键检测阻塞 }
关键逻辑说明
- 按键消抖:用
delay(5)做基础消抖,避免机械按键的抖动导致误触发;如果你的项目有更高的实时性要求,也可以用millis()实现非阻塞式消抖(记录上次状态变化时间,等待状态稳定后再处理)。 - 时长判断:当按键释放时,计算从按下到释放的时间差,只有时长小于设定的
shortPressThreshold(比如200ms)时,才让counter1加1;长按的话时长超过阈值,就不会触发计数。 - 非阻塞计时:用
millis()获取当前时间,代替delay(),这样程序在检测按键的同时,还能正常运行其他代码,不会出现卡死的情况。
可调参数提示
shortPressThreshold:可以根据你的使用习惯调整,比如改成300ms,只要按键按下时间不超过300ms就算短按,超过则视为长按忽略。buttonPin:根据你实际接线的引脚修改即可。
内容的提问来源于stack exchange,提问作者user9428725




