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

標題: Arduino教程-消除按鍵抖動! [打印本頁]

作者: 51黑電子論壇    時間: 2015-12-19 21:23
標題: Arduino教程-消除按鍵抖動!
Hi,大家好!又跟大家見面啦!在上一次講解按鍵開關臨近結束的時候,我們提到在正常的使用過程中,美中有不足,按鍵開關還有一個小問題需要解決。那是什么問題呢?
每當你按下或抬起按鍵開關的一瞬間,由于讀取信號的操作是持續進行的,又由于按鍵自身的物理元器件的問題,每次觸碰的一瞬間,可能會發生多次短暫的物理接觸,以至于最終產生的信號發生了抖動。為了消除這種抖動,讓按鍵變得更加好用,這次我們一起來試試看如何解決這個問題!這一次的學習過程中,我們用到了之前在《另一種時間延遲》中學過的知識點。如果你對此還有印象,那將會對這一次的學習有很大的幫助呢!
好!介紹的差不多了。還是老環節,先準備一下我們需要的材料。
硬件方面
圖片來源:Arduino電路配件
具體包括如下:
咦?是不是看起來很像上一次在《按鍵開關》那一節中所使用的硬件啊!哼哼!其實不單是硬件用的一樣,連電路的連接也是一摸一樣呢!同樣的,這次我們對按鍵測試所使用的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

作者: ZFDPJ    時間: 2017-11-26 02:48
大神請問一下 51步 if (reading != buttonState)中 reading不就是讀取的buttonstate中的狀態嗎?為什么還可以比較啊? 求解釋
作者: w53532628    時間: 2019-5-16 09:22
我覺得寫得挺好滴,頂一個
作者: w53532628    時間: 2019-5-16 09:34
如果按鈕按得夠久,先0-1再1-0,都是穩定的,那燈的狀態就會變兩次嗎?
作者: vbn6264    時間: 2020-3-5 17:09
很好的按鍵的函數 謝謝分享

作者: 定不負全卿    時間: 2020-3-5 21:30
ZFDPJ 發表于 2017-11-26 02:48
**** 作者被禁止或刪除 內容自動屏蔽 ****

buttonState是int類型只有兩種值0和1   如果為0不執行   如果為1  執行    關鍵在那個!=  這個符號
作者: 科比之心    時間: 2020-3-23 11:29
ZFDPJ 發表于 2017-11-26 02:48
**** 作者被禁止或刪除 內容自動屏蔽 ****

我分析這個地方應該是寫錯了,BUTTONSTATE在程序中沒有用到,這個地方應該改成lastButtonState就可以了,reading確實是當前獲取到的按鍵狀態值
作者: 完完全全    時間: 2020-4-15 10:40
科比之心 發表于 2020-3-23 11:29
我分析這個地方應該是寫錯了,BUTTONSTATE在程序中沒有用到,這個地方應該改成lastButtonState就可以了, ...

把這句"int reading = digitalRead(buttonPin);"改為#define reading   digitalRead(buttonPin);
就好理解了
作者: 精彩一刻    時間: 2020-9-25 14:28
我是菜鳥,請問下:
// 定義按鍵輸入針腳號常量,
// 并初始化為2號針腳。
const int buttonPin = 2;
這個可不可以用宏定義,因為引腳號基本只是指定,而不會在程序運行去改變的,是不是可以不用int變量,而用:#define buttonPin  = 2
宏定義是不占內存空間的吧,而一個int整型是要消耗內存的,不知我想的對不對?
作者: ziba108    時間: 2023-7-29 18:32
很好的按鍵的函數 謝謝分享




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 一本一道久久a久久精品蜜桃 | 99久久久久 | 欧美日韩高清 | 欧美成人激情 | av网站在线看 | 色天天综合| 国产真实乱全部视频 | 二区三区在线观看 | 国产精品一区二区av | 亚洲国产欧美一区二区三区久久 | 久久精品毛片 | 欧美激情综合色综合啪啪五月 | 欧美激情综合 | 国产免费一区二区三区最新6 | 欧美日韩在线播放 | 国产精品色综合 | 亚洲在线视频 | 四虎影院在线免费观看 | 久久久青草婷婷精品综合日韩 | 日本三级在线网站 | 亚洲一区二区在线电影 | 日本不卡一区二区三区在线观看 | 午夜免费成人 | 中文字幕在线观看 | 伊人伊成久久人综合网站 | www国产精品 | 视频第一区 | 亚洲精品www| 欧美一级片在线看 | 国产精品久久久久久久久久免费看 | 久久久久综合 | 羞羞网站免费 | 国产剧情一区二区三区 | 国产精品美女久久久久久免费 | 激情自拍偷拍 | 99精品欧美一区二区蜜桃免费 | 久久成人综合 | 国产日韩欧美在线 | 亚洲国产日韩一区 | 国产情侣一区 | 日韩一级 |