Arduino 按键消抖
本文主要介绍在 Arduino 中消除按键抖动的几种方法,包括常见的延时判断,以及一些库的使用。
由于物理性质和机械特性等原因,矩阵按键经常在按下后的一小段时间产生不定状态,这很可能被程序误认为在短时间内进行了多次按键操作。因此,在使用矩阵按键时,如果没有硬件消抖的措施,软件消抖是必不可少的,否则可能会产生不可预期的效果!
延时判断
延时判断就是通过在一小段间隔时间后再次读取按键状态的方式,来确保按键确实是完全被按下了,简单来说就是屏蔽掉发生按键抖动的时间段。在 Arduino 中可以使用 millis()
函数来算得按键按下后经过的时间。
下面示例代码通过延时判断去除按键抖动,并控制 LED 灯翻转。你可能需要根据 Arduino 开发板的硬件情况,修改引脚和有效电平状态。
const int buttonPin = 2; // 连接矩阵按键的引脚
const int ledPin = 13; // LED引脚
int ledState = HIGH; // 记录LED的状态
int buttonState; // 记录按键的状态
int lastButtonState = LOW; // 上一次按键的状态
// 以下代码以long类型声明,因为时间值以毫秒为单位(用整型会很快溢出)
long lastDebounceTime = 0; // 按键最后一次被触发
long debounceDelay = 50; // 为了滤去抖动暂停的时间,如果发现输出不正常增加这个值
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// 设置LED初始状态
digitalWrite(ledPin, ledState);
}
void loop() {
// 读取按键状态并存储到变量中
int reading = digitalRead(buttonPin);
// 检查下按键状态是否改变(换句话说,输入是否是从 LOW 到 HIGH)
// 检查是否距离上一次按下的时间已经足够滤去按键抖动
if (reading != lastButtonState) { // 如果按键状态和上次不同
lastDebounceTime = millis(); // 记录初始时间
}
// 离初始时间已经过了按键抖动出现的时间,因此当前的按键状态是稳定状态
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) { // 如果按键状态改变了
buttonState = reading;
if (buttonState == HIGH) { // 只有当按键状态稳定为 HIGH 时才打开 LED
ledState = !ledState;
}
}
}
digitalWrite(ledPin, ledState); // 设置LED
lastButtonState = reading; // 保存处理结果
}
Bounce2 库
Bounce2 库是 Thomas O Fredericks 编写的一个专用于机械按钮和开关消抖的软件库。
这个库包含三个类:
- Debouncer:执行实际去抖动的代码。只有高级用户会关心这个类,一般用户不需要关心。
- Bounce:这是通用库。它的底层由 Debouncer 实现。
- Button:基于 Bounce 类,专用于 按下(pressed)按钮。
使用该库需要预先安装,并载入头文件:
#include <Bounce2.h>
Bounce 示例
下面示例代码通过 Bounce 类实现按键消抖,当按下按钮(pin 2)时翻转 LED 灯(pin 13)状态。你可能需要根据 Arduino 开发板的硬件情况,修改引脚和有效电平状态。
#include <Bounce2.h>
#define BUTTON_PIN 2
#define LED_PIN 13
int ledState = LOW;
Bounce b = Bounce(); // Instantiate a Bounce object
void setup() {
b.attach(BUTTON_PIN,INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
b.interval(25); // Use a debounce interval of 25 milliseconds
pinMode(LED_PIN,OUTPUT); // Setup the LED
digitalWrite(LED_PIN,ledState); // Turn off the LED
}
void loop() {
b.update(); // Update the Bounce instance
if ( b.fell() ) { // Call code if button transitions from HIGH to LOW
ledState = !ledState; // Toggle LED state
digitalWrite(LED_PIN,ledState); // Apply new LED state
}
}
Button 示例
下面示例代码通过 Button 类实现按键消抖,当按下按钮(pin 39)时翻转 LED 灯(pin 13)状态。你可能需要根据 Arduino 开发板的硬件情况,修改引脚和有效电平状态。
#include <Bounce2.h>
// INSTANTIATE A Button OBJECT
Bounce2::Button button = Bounce2::Button();
// WE WILL attach() THE BUTTON TO THE FOLLOWING PIN IN setup()
#define BUTTON_PIN 39
// DEFINE THE PIN FOR THE LED :
// 1) SOME BOARDS HAVE A DEFAULT LED (LED_BUILTIN)
//#define LED_PIN LED_BUILTIN
// 2) OTHERWISE SET YOUR OWN PIN
#define LED_PIN 13
// SET A VARIABLE TO STORE THE LED STATE
bool ledState = LOW;
void setup() {
// BUTTON SETUP
// SELECT ONE OF THE FOLLOWING :
// 1) IF YOUR BUTTON HAS AN INTERNAL PULL-UP
// button.attach( BUTTON_PIN , INPUT_PULLUP ); // USE INTERNAL PULL-UP
// 2) IF YOUR BUTTON USES AN EXTERNAL PULL-UP
button.attach( BUTTON_PIN, INPUT ); // USE EXTERNAL PULL-UP
// DEBOUNCE INTERVAL IN MILLISECONDS
button.interval(5);
// INDICATE THAT THE LOW STATE CORRESPONDS TO PHYSICALLY PRESSING THE BUTTON
button.setPressedState(LOW);
// LED SETUP
pinMode(LED_PIN,OUTPUT);
digitalWrite(LED_PIN,ledState);
}
void loop() {
// UPDATE THE BUTTON
// YOU MUST CALL THIS EVERY LOOP
button.update();
if ( button.pressed() ) {
// TOGGLE THE LED STATE :
ledState = !ledState; // SET ledState TO THE OPPOSITE OF ledState
digitalWrite(LED_PIN,ledState);
}
}