## 按键去抖
> 由于物理性质和机械特性等原因,矩阵按键经常在按下后的一小段时间产生不定状态。这很可能被程序误认为在短时间内进行了多次按键操作。本例向你展示如何进行**按键去抖**:通过在一小段间隔时间后再次读取按键状态的方式,来确保按键确实是完全被按下了(简单来说就是”滤去”发生按键抖动的时间)。
当**按键抖动**发生的时候会产生不可预期的效果。本例使用**millis()**函数来算得按键按下后经过的时间,以避免按键抖动造成的影响。
### 所需硬件
Arduino板或Genuino板
自锁按钮或开关
10kΩ电阻
面包板跳线
面包板
### 电路
![图片来自官网](http://img.blog.csdn.net/20160421164151566)
### 原理图
![图片来自官网](http://img.blog.csdn.net/20160421164218426)
### 代码
下面的例程借鉴了Limor Fried的代码,但是代码逻辑与她的相反。在她的范例中,开关闭合Arduino读出的是LOW,断开读出的是HIGH。而本例中开关闭合Arduino读出的是HIGH,断开读出的是LOW。
### 例程代码
~~~
/*
按键去抖
每当输入引脚发生高低电平的变化时(比如由于矩阵按键被按下了),或当输出引脚发生高低电平的变化时,程序就应该暂停一小段时间来避免这个抖动的干扰(或者说避免这种电子噪声的干扰)。
电路搭建:
* LED连接13号引脚和GND
* 矩阵按键连接2号引脚和+5V
* 10kΩ电阻连接2号引脚和GND
* 小贴士: 大多数Arduino板在13号引脚已经有板载LED,所以你一般不用附加LED来完成本例。
代码是公开的
*/
// 常量,用来定义引脚号码
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;
// 只有当稳定的按键状态时HIGH时才打开LED。
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// 设置LED:
digitalWrite(ledPin, ledState);
// 保存处理结果:
lastButtonState = reading;
}
~~~
## 相关资料
[pinMode()](http://www.arduino.cc/en/Reference/PinMode)
[digitalWrite()](http://www.arduino.cc/en/Reference/DigitalWrite)
[digitalRead()](http://www.arduino.cc/en/Reference/DigitalRead)
[if()](http://www.arduino.cc/en/Reference/If)
[millis()](http://www.arduino.cc/en/Reference/Millis)
- 说明
- 系统示例文件目录结构及说明
- 01.Basics
- AnalogReadSerial
- BareMinimum
- Blink
- DigitalReadSerial
- Fade
- ReadAnalogVoltage
- 02.Digital
- BlinkWithoutDelay
- Button
- Debounce
- DigitalInputPullup
- StateChangeDetection
- toneKeyboard
- toneMelody
- toneMultiple
- tonePitchFollower
- 03.Analog
- AnalogInOutSerial
- AnalogInput
- AnalogWriteMega
- Calibration
- Fading
- Smoothing
- 04.Communication
- ASCIITable
- Dimmer
- Graph
- Midi
- MultiSerial
- PhysicalPixel
- ReadASCIIString
- SerialCallResponse
- SerialCallResponseASCII
- SerialEvent
- SerialPassthrough
- VirtualColorMixer
- 05.Control
- Arrays
- ForLoopIteration
- IfStatementConditional
- switchCase
- switchCase2
- WhileStatementConditional
- 06.Sensors
- ADXL3xx
- Knock
- Memsic2125
- Ping
- 07.Display
- barGraph
- RowColumnScanning
- 08.Strings
- CharacterAnalysis
- StringAdditionOperator
- StringAppendOperator
- StringCaseChanges
- StringCharacters
- StringComparisonOperators
- StringConstructors
- StringIndexOf
- StringLength
- StringLengthTrim
- StringReplace
- StringStartsWithEndsWith
- StringSubstring
- StringToInt
- 09.USB
- Keyboard
- KeyboardLogout
- KeyboardMessage
- KeyboardReprogram
- KeyboardSerial
- KeyboardAndMouseControl
- Mouse
- ButtonMouseControl
- JoystickMouseControl
- 10.StarterKit_BasicKit (与特定硬件相关,暂无)
- p02_SpaceshipInterface
- p03_LoveOMeter
- p04_ColorMixingLamp
- p05_ServoMoodIndicator
- p06_LightTheremin
- p07_Keyboard
- p08_DigitalHourglass
- p09_MotorizedPinwheel
- p10_Zoetrope
- p11_CrystalBall
- p12_KnockLock
- p13_TouchSensorLamp
- p14_TweakTheArduinoLogo
- p15_HackingButtons
- 11.ArduinoISP(暂无)
- ArduinoISP