久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 45773|回復: 10
打印 上一主題 下一主題
收起左側

Arduino教程-消除按鍵抖動!

[復制鏈接]
跳轉到指定樓層
樓主
Hi,大家好!又跟大家見面啦!在上一次講解按鍵開關臨近結束的時候,我們提到在正常的使用過程中,美中有不足,按鍵開關還有一個小問題需要解決。那是什么問題呢?
每當你按下或抬起按鍵開關的一瞬間,由于讀取信號的操作是持續進行的,又由于按鍵自身的物理元器件的問題,每次觸碰的一瞬間,可能會發生多次短暫的物理接觸,以至于最終產生的信號發生了抖動。為了消除這種抖動,讓按鍵變得更加好用,這次我們一起來試試看如何解決這個問題!這一次的學習過程中,我們用到了之前在《另一種時間延遲》中學過的知識點。如果你對此還有印象,那將會對這一次的學習有很大的幫助呢!
好!介紹的差不多了。還是老環節,先準備一下我們需要的材料。
硬件方面
圖片來源:Arduino電路配件
具體包括如下:
  • Arduino UNO電路板(1塊)
  • 面包板(1塊)
  • 10k電阻(1個)
  • 按鍵開關(1個)
  • 面包線(3根)
咦?是不是看起來很像上一次在《按鍵開關》那一節中所使用的硬件啊!哼哼!其實不單是硬件用的一樣,連電路的連接也是一摸一樣呢!同樣的,這次我們對按鍵測試所使用的LED神燈,用的還是Arduino UNO電路板上自帶的那一盞!
軟件方面不多說,依然是Arduino官方提供的IDE。
連接電路
圖片來源:Arduino連接開關按鍵電路示意圖
既然和上一次的電路連接一樣,就不多啰嗦了,我們直接進入最后一步!
添加幾行代碼首先,還是新建一個項目窗口。

圖片來源:Arduino官方IDE
然后向其中添加如下代碼:


  1. // 定義按鍵輸入針腳號常量,
  2. // 并初始化為2號針腳。
  3. const int buttonPin = 2;
  4. // 定義LED輸入針腳號常量,
  5. // 并初始化為13號針腳。
  6. // 注:此處我們使用的LED神燈是Arduino UNO電路板自帶,
  7. // 此神燈對應的針腳號默認為13,此數值不得隨意更改,
  8. // 所以這里定義的數值13是為了和默認值相對應。
  9. const int ledPin = 13;
  10. // 定義記錄LED神燈當前狀態的變量,
  11. // 并初始化狀態為HIGH。
  12. int ledState = HIGH;
  13. // 定義記錄按鍵當前狀態的變量
  14. int buttonState;
  15. // 定義記錄按鍵最近一次狀態變化的變量,
  16. // 并初始化狀態為LOW。
  17. int lastButtonState = LOW;
  18. // 定義記錄最近一次抖動的時間變量,
  19. // 并初始化時間為0毫秒。
  20. long lastDebounceTime = 0;
  21. // 定義延遲抖動的時間變量,
  22. // 并初始化為50毫秒。
  23. long debounceDelay = 50;

  24. // 對Arduino電路板或相關狀態進行初始化方法
  25. void setup() {
  26.   // 設置按鍵的針腳為輸入狀態
  27.   pinMode(buttonPin, INPUT);
  28.   // 設置電路板上LED神燈的針腳狀態為輸出狀態
  29.   pinMode(ledPin, OUTPUT);
  30.   // 設置電路板上LED神燈的初始狀態,
  31.   // 此處因為變量ledState的初始狀態為HIGH,
  32.   // 所以LED神燈的初始狀態為亮。
  33.   digitalWrite(ledPin, ledState);
  34. }

  35. // 系統調用,無限循環方法
  36. void loop() {
  37.   // 讀取按鍵的狀態
  38.   int reading = digitalRead(buttonPin);
  39.   // 判斷當前的按鍵狀態是否和之前有所變化
  40.   if (reading != lastButtonState) {
  41.     // 如果按鍵發生了變化,
  42.     // 則重新設置最近一次抖動的時間。
  43.     lastDebounceTime = millis();
  44.   }
  45.   // 判斷按鍵按下或抬起的狀態時間間隔是否大于延遲抖動的時間長度。
  46.   // 方法millis()可以獲取當前時間,單位統一為毫秒。
  47.   if ((millis() - lastDebounceTime) > debounceDelay) {
  48.     // 判斷當前的按鍵狀態是否和之前有所變化
  49.     if (reading != buttonState) {
  50.       // 如果發生了變化,
  51.       // 則更新按鍵狀態變量。
  52.       buttonState = reading;
  53.       // 判斷按鍵的狀態是否為按下,
  54.       // 只有在按鍵按下的時候,
  55.       // 才改變LED神燈的狀態。
  56.       if (buttonState == HIGH) {
  57.         // 如果LED神燈當前為亮度,
  58.         // 則變為滅。如果為滅,
  59.         // 則變為亮。
  60.         ledState = !ledState;
  61.       }
  62.     }
  63.   }
  64.   // 最終改變電路板上LED神燈的狀態
  65.   digitalWrite(ledPin, ledState);
  66.   // 更新按鍵最近一次狀態變化的變量
  67.   lastButtonState = reading;
  68. }
復制代碼



好!總共的代碼就是醬紫!看起來有些長呢!其實也只是看起來而已啦!老實說這里并沒有出現任何新的面孔,唯一看起來有點繞的,就是對時間延遲的控制。如果覺得有些吃力,可以回顧一下《另一種時間延遲》小節所學的內容。之所以能夠最終解決抖動問題,其實就是通過加入時間延遲來解決的。通過延長按鍵狀態改變的時間長度,來最終消除信號的抖動。

圖片來源:Arduino官方IDE的文件編輯菜單選項
點擊上圖中標有向右指向的箭頭圖標,將代碼一鍵燒入Arduino UNO電路板。現在試試看,每次單擊按鍵,電路板上的LED神燈會不會有所變化?如果一切正常,現在每單擊一下按鍵,LED神燈的狀態就會變化一次。在《按鍵開關》那一節,是每次按下按鍵,點亮LED神燈。抬起按鍵,LED神燈熄滅。而現在是每單擊一次按鍵,LED神燈變化一次。可以體會一下它們之間的不同。
總結通過這次學習,我們解決了按鍵的信號抖動的問題。解決的核心方法呢,是通過引入時間延遲,來消除信號抖動。技術來說并沒有碰到新內容,難點就在于對時間延遲的理解。
下期預告通過前兩次學習,我們發現每次連接按鍵總要外加一個10k的電阻。在電路合理連接的情況下,能不能不引入電阻,直接就能使用按鍵呢!好!下一次,我們將一起學習一種如何不用外接電阻,也能正常使用按鍵的方法!


ohcoder的系列精彩Arduino教程:
Arduino教程-初識Arduino(包含本教程目錄):http://www.zg4o1577.cn/bbs/dpj-41334-1.html
Arduino教程-開篇:http://www.zg4o1577.cn/bbs/dpj-41335-1.html
Arduino教程-點亮LED神燈:http://www.zg4o1577.cn/bbs/dpj-41336-1.html
Arduino教程-讓LED神燈閃爍:http://www.zg4o1577.cn/bbs/dpj-41337-1.html
Arduino教程-讓LED神燈亮度漸變:http://www.zg4o1577.cn/bbs/dpj-41338-1.html
Arduino教程-獲取輸入數字信號:http://www.zg4o1577.cn/bbs/dpj-41339-1.html
Arduino教程-獲取輸入模擬信號:http://www.zg4o1577.cn/bbs/dpj-41340-1.html
Arduino教程-另一種時間延遲:http://www.zg4o1577.cn/bbs/dpj-41331-1.html
Arduino教程-按鍵開關:http://www.zg4o1577.cn/bbs/dpj-41341-1.html
Arduino教程-停止抖動!:http://www.zg4o1577.cn/bbs/dpj-41333-1.html
Arduino教程-拋棄外部電阻!:http://www.zg4o1577.cn/bbs/dpj-41332-1.html
Arduino教程-用按鍵開關計數:http://www.zg4o1577.cn/bbs/dpj-41330-1.html

………后續持續更新中請打開:http://www.zg4o1577.cn/bbs/dpj-41334-1.html
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:253661 發表于 2017-11-26 02:48 | 只看該作者
大神請問一下 51步 if (reading != buttonState)中 reading不就是讀取的buttonstate中的狀態嗎?為什么還可以比較啊? 求解釋
回復

使用道具 舉報

板凳
ID:437197 發表于 2019-5-16 09:22 | 只看該作者
我覺得寫得挺好滴,頂一個
回復

使用道具 舉報

地板
ID:437197 發表于 2019-5-16 09:34 | 只看該作者
如果按鈕按得夠久,先0-1再1-0,都是穩定的,那燈的狀態就會變兩次嗎?
回復

使用道具 舉報

5#
ID:20841 發表于 2020-3-5 17:09 | 只看該作者
很好的按鍵的函數 謝謝分享
回復

使用道具 舉報

6#
ID:455377 發表于 2020-3-5 21:30 | 只看該作者
ZFDPJ 發表于 2017-11-26 02:48
**** 作者被禁止或刪除 內容自動屏蔽 ****

buttonState是int類型只有兩種值0和1   如果為0不執行   如果為1  執行    關鍵在那個!=  這個符號
回復

使用道具 舉報

7#
ID:35955 發表于 2020-3-23 11:29 | 只看該作者
ZFDPJ 發表于 2017-11-26 02:48
**** 作者被禁止或刪除 內容自動屏蔽 ****

我分析這個地方應該是寫錯了,BUTTONSTATE在程序中沒有用到,這個地方應該改成lastButtonState就可以了,reading確實是當前獲取到的按鍵狀態值
回復

使用道具 舉報

8#
ID:607710 發表于 2020-4-15 10:40 | 只看該作者
科比之心 發表于 2020-3-23 11:29
我分析這個地方應該是寫錯了,BUTTONSTATE在程序中沒有用到,這個地方應該改成lastButtonState就可以了, ...

把這句"int reading = digitalRead(buttonPin);"改為#define reading   digitalRead(buttonPin);
就好理解了
回復

使用道具 舉報

9#
ID:160932 發表于 2020-9-25 14:28 | 只看該作者
我是菜鳥,請問下:
// 定義按鍵輸入針腳號常量,
// 并初始化為2號針腳。
const int buttonPin = 2;
這個可不可以用宏定義,因為引腳號基本只是指定,而不會在程序運行去改變的,是不是可以不用int變量,而用:#define buttonPin  = 2
宏定義是不占內存空間的吧,而一個int整型是要消耗內存的,不知我想的對不對?
回復

使用道具 舉報

10#
ID:138707 發表于 2023-7-29 18:32 | 只看該作者
很好的按鍵的函數 謝謝分享
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av天天爽| 欧美精品在线一区 | 久久国产婷婷国产香蕉 | 范冰冰一级做a爰片久久毛片 | 亚洲色图婷婷 | 毛片久久久 | 国产99久久久国产精品 | 91色在线视频 | 色视频www在线播放国产人成 | 红色av社区 | 91综合网 | 天天玩天天干天天操 | 中文字幕视频在线免费 | 99这里只有精品视频 | 欧美精品国产精品 | 国产日韩电影 | 成人福利| 日韩视频在线一区二区 | 天天夜天天操 | 欧美日韩成人网 | 亚洲视频在线观看免费 | 亚洲精品乱码久久久久久按摩观 | 99精品国产一区二区三区 | 国产1区2区在线观看 | av大全在线 | 美国一级片在线观看 | 成人av影院 | 成人一区二区视频 | 91精品国产91久久久久久最新 | 99久久精品国产一区二区三区 | 99国产精品久久久久老师 | 自拍偷拍精品 | 国产成人一区二区三区精 | 亚洲综合久久久 | 中文在线www | 国产视频一二三区 | 国产精品久久久久久婷婷天堂 | 久久精品a级毛片 | 人人人干 | 欧洲亚洲一区二区三区 | 午夜精品久久久久久久久久久久久 |