第十二篇、基于Arduino uno,获取多个按键的输入信号(滤波消抖)——结果导向

news/2024/11/24 3:26:13/

0、结果

说明:先来看看串口调试助手显示的结果,当按下按键的时候,按一次会打印一次按键被按下,并且打印是哪个按键被按下。如果是你想要的,可以接着往下看。

1、外观

说明:虽然每个型号的按键形态各异,但是原理和代码都是适用的,只要能保证按下导通,不按下不导通就行。

2、连线

说明:只需要连接两根线,一端和另一端需要保证按下导通,不按下不导通。
uno————按键

GND--------------按键一端
    D2--------------按键另一端

3、源程序

说明:对按键进行了消抖,基本上不会存在误触发的可能,按键多了或者少了也可以自行更改,很方便。并将对应功能进行函数化,方便移植。

/****************************************按键 part****************************************/
/*用到几个按键的话就定义几个引脚,不然引脚悬空的话会误触发!!!接线:按键一端接GND,一端接D2~D8,能保证按下导通,不按下不导通就行。
*/
#define startButton   2                                             //0号按钮
#define buttonPin1    3                                             //1号按钮
#define buttonPin2    4                                             //2号按钮
#define buttonPin3    5                                             //3号按钮
#define buttonPin4    6                                             //4号按钮
#define buttonPin5    7                                             //5号按钮
#define buttonPin6    8                                             //6号按钮#define buttonON      LOW                                           //按钮按下时为低电平  struct Button {int buttonState = !buttonON;                                      //按钮状态变量,与按钮按下时的状态取反int lastButtonState = !buttonON;                                  //按钮状态初始化,与按钮按下时的状态取反long lastDebounceTime = 0;                                        //记录抖动变量long debounceDelay = 30;                                          //抖动时间变量bool flag = false;                                                //按钮flag
};
const int buttonPins[7] = {startButton, buttonPin1, buttonPin2, buttonPin3, buttonPin4, buttonPin5, buttonPin6};
Button button, buttons[7];                                          //新建1个按钮,和按钮数组,数组含有七个按钮
int runCount = 0;                                                   //定义一个变量
int buttonCount = 9;                                                //按键号
/****************************************set up and loop part*********************************/
void setup() {Serial.begin(9600);                                               //初始化串口,波特率为9600initButtons();                                                    //初始化所有按键串口
}
void loop() {buttonMonitor();                                                  //按键检测函数
}
/****************************************按键 part****************************************/
/*按钮初始化函数,设置为上拉输入,更加稳定*/
void initButtons() {for (int i = 0; i < sizeof(buttonPins) / sizeof(buttonPins[0]); i++) {pinMode(buttonPins[i], INPUT_PULLUP);                          //适用于多个按钮}
}
/*按钮输入读取,采用非阻塞式按键消抖,适用于多个按钮*/
void getButton(int _buttonPin, int _buttonIndex) {int reading = digitalRead(_buttonPin);                           //读取状态if (reading != buttons[_buttonIndex].lastButtonState) {          //如果状态改变buttons[_buttonIndex].lastDebounceTime = millis();             //更新时间}                                                                //如果等待大于debounceDelayif ((millis() - buttons[_buttonIndex].lastDebounceTime) > buttons[_buttonIndex].debounceDelay) {if (reading != buttons[_buttonIndex].buttonState) {            //读取状态不等于按钮状态buttons[_buttonIndex].buttonState = reading;                 //更新状态if (buttons[_buttonIndex].buttonState == buttonON) {         //判断按钮是否真的按下buttonCount = _buttonIndex;Serial.print(buttonCount);                                 //打印按钮编号Serial.println(" is pressed");                             //输出按钮按下的文字buttons[_buttonIndex].flag = true;                         //按钮flag为真}else {buttons[_buttonIndex].flag = false;                        //按钮flag为假}}}buttons[_buttonIndex].lastButtonState = reading;                 //更新last状态
}
/*设备上电之后会误触发按键检测,写这个函数是为了稳定后,再来检测按键的状态*/
void runCountToStable() {if (runCount < 10) {                                             //防止误触发runCount++;}
}
/*按键检测函数*/
void buttonMonitor() {runCountToStable();                                              //记录运行次数为了按键检测运行精确for (int i = 0; i < sizeof(buttonPins) / sizeof(buttonPins[0]); i++) {getButton(buttonPins[i], i);                                   //适用于多个按钮}
}

4、注意事项

说明:按键有四个引脚或者三个引脚,四个引脚的按键,两个引脚挨得近的是不按下不导通,按下导通;如果是三个引脚的,随便接两个引脚就行。

5、基本原理

        在按键被按下时使得电路闭合,从而触发相应的程序操作。按键通常由两个部分组成:一个是用于连接电路的接点(也称为触点或固定触点),另一个是用于控制接点状态的弹簧式机构(也称为活动触点)。
        当按键未被按下时,接点处于断开状态,此时电路不通,无法传递电信号。当按键被按下时,机械结构将弹簧压缩,使活动触点与固定触点接触,从而形成闭合电路。在这个过程中,电流可以沿着闭合的电路流通,达到控制相应程序操作的目的。
        在Arduino中,按键的工作流程主要包括两个阶段:输入和处理。在输入阶段,当按键被按下时,Arduino会读取对应的数字或模拟输入引脚的电压状态,并将其转换为高或低电平信号。在处理阶段,Arduino根据输入信号的状态进行相应的判断和操作,如执行特定函数、调用模块等操作。

6、消抖的方法

        采用软件消抖的原理是通过编程实现,在按键被按下后,通过程序进行一定的处理和判断,使得系统仅响应有效的按键操作,避免因按键抖动等原因产生误触发现象。
        具体来说,软件消抖的原理主要包括以下几个步骤:

  1. 读取按键状态:首先需要读取按键状态,即检测输入引脚的电平是否发生变化(从高电平到低电平)。可以使用Arduino中的digitalRead函数实现该功能。

  2. 延时消抖:当检测到按键状态发生变化时,需要延时一段时间,以等待按键抖动消除。可以使用Arduino中的delay函数或借助定时器实现延时功能。

  3. 再次读取按键状态:在延时结束后,需要再次读取按键状态,并与之前的状态比较,以确定是否发生有效的按键操作。只有当两次读取的状态相同,且状态为低电平时,才表示发生了有效的按键操作。


http://www.ppmy.cn/news/142780.html

相关文章

系统补丁下载地址

http://www.catalog.update.microsoft.com/home.aspx

ubuntu 升级安装包 进行安装包的更新(软件版本的升级) 进行系统版本的升级

apt-get update: 升级安装包相关的命令,刷新可安装的软件列表(但是不做任何实际的安装动作)apt-get upgrade: 进行安装包的更新(软件版本的升级)apt-get dist-upgrade: 进行系统版本的升级(Ubuntu版本的升级)do-release-upgrade: Ubuntu官方推荐的系统升级方式,若加参数-d还可以…

如何打补丁包

当需要修改vue插件源码时需要打补丁包&#xff0c;防止下一个人直接i install需要修改的插件被覆盖掉 1.安装patch-package&#xff1a;npm i patch-package --save-dev 2.修改package.json&#xff0c;新增命令postinstall:"postinstall": "patch-package"…

microsoft windows 系统更新包下载与离线安装

未联网的电脑&#xff0c;需要对系统进行更新。 更新包的搜索及下载地址&#xff1a; sMicrosoft Update Cataloghttps://catalog.update.microsoft.com/Search.aspx?qkb4490628 安装包为msu专用格式&#xff0c;双击安装即可。

windows10补丁包离线更新

微软官方补丁更新目录 在上述可以下载相关系统的补丁&#xff0c;但是十分不方便&#xff0c;需要比较繁琐的找。 windows10补丁合集 在这个网站可以直接下载补丁的合集 现在微软已经把安全补丁设置为累积更新&#xff0c;你只需要下载最新的累积更新补丁。可以用上面的用户…

微软补丁包下载

Microsoft Update Cataloghttps://www.catalog.update.microsoft.com/Home.aspxMicrosoft Update CatalogMicrosoft Update Cataloghttps://www.catalog.update.microsoft.com/Home.aspx

Windows7SP1补丁包(Win7补丁汇总) 32位/64位版 更新截至2016年11月

Windows7SP1(64位)补丁包(Win7补丁汇总)更新到本月最新。包含Windows7SP1中文版所有重要补丁&#xff0c;可离线安装&#xff0c;适用于Windows 7 SP1 64位 简体中文系统。包含Internet Explorer 8补丁和IE兼容性补丁。安装程序会自动检测跳过系统已安装的更新程序。支持集成系…

微软服务器打补丁步骤,自己手动制作 Windows 系统补丁包全过程

既然刚才谈到了 Windows Update 补丁失败的问题&#xff0c;网上翻资料的时候翻到一篇不错的文章&#xff0c;是关于自己手工集成 Windows 7 补丁包的方法。因为微软的 Update 服务器在国内很不稳定&#xff0c;新安装完一台电脑&#xff0c;有时候打补丁挺快&#xff0c;有时候…