Hi,大家好!又跟大家見面啦!在上一次講解按鍵開關臨近結束的時候,我們提到在正常的使用過程中,美中有不足,按鍵開關還有一個小問題需要解決。那是什么問題呢?
每當你按下或抬起按鍵開關的一瞬間,由于讀取信號的操作是持續進行的,又由于按鍵自身的物理元器件的問題,每次觸碰的一瞬間,可能會發生多次短暫的物理接觸,以至于最終產生的信號發生了抖動。為了消除這種抖動,讓按鍵變得更加好用,這次我們一起來試試看如何解決這個問題!這一次的學習過程中,我們用到了之前在《另一種時間延遲》中學過的知識點。如果你對此還有印象,那將會對這一次的學習有很大的幫助呢!
好!介紹的差不多了。還是老環節,先準備一下我們需要的材料。
硬件方面
arduino-read-digital.jpg (121.51 KB, 下載次數: 875)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino電路配件
具體包括如下:
- Arduino UNO電路板(1塊)
- 面包板(1塊)
- 10k電阻(1個)
- 按鍵開關(1個)
- 面包線(3根)
咦?是不是看起來很像上一次在《按鍵開關》那一節中所使用的硬件啊!哼哼!其實不單是硬件用的一樣,連電路的連接也是一摸一樣呢!同樣的,這次我們對按鍵測試所使用的LED神燈,用的還是Arduino UNO電路板上自帶的那一盞!
軟件方面不多說,依然是Arduino官方提供的IDE。
連接電路
arduino-ide-new.jpg (70.98 KB, 下載次數: 259)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino連接開關按鍵電路示意圖
既然和上一次的電路連接一樣,就不多啰嗦了,我們直接進入最后一步!
添加幾行代碼首先,還是新建一個項目窗口。
arduino-menu.jpg (9.87 KB, 下載次數: 239)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino官方IDE
然后向其中添加如下代碼:
- // 定義按鍵輸入針腳號常量,
- // 并初始化為2號針腳。
- const int buttonPin = 2;
- // 定義LED輸入針腳號常量,
- // 并初始化為13號針腳。
- // 注:此處我們使用的LED神燈是Arduino UNO電路板自帶,
- // 此神燈對應的針腳號默認為13,此數值不得隨意更改,
- // 所以這里定義的數值13是為了和默認值相對應。
- const int ledPin = 13;
- // 定義記錄LED神燈當前狀態的變量,
- // 并初始化狀態為HIGH。
- int ledState = HIGH;
- // 定義記錄按鍵當前狀態的變量
- int buttonState;
- // 定義記錄按鍵最近一次狀態變化的變量,
- // 并初始化狀態為LOW。
- int lastButtonState = LOW;
- // 定義記錄最近一次抖動的時間變量,
- // 并初始化時間為0毫秒。
- long lastDebounceTime = 0;
- // 定義延遲抖動的時間變量,
- // 并初始化為50毫秒。
- long debounceDelay = 50;
- // 對Arduino電路板或相關狀態進行初始化方法
- void setup() {
- // 設置按鍵的針腳為輸入狀態
- pinMode(buttonPin, INPUT);
- // 設置電路板上LED神燈的針腳狀態為輸出狀態
- pinMode(ledPin, OUTPUT);
- // 設置電路板上LED神燈的初始狀態,
- // 此處因為變量ledState的初始狀態為HIGH,
- // 所以LED神燈的初始狀態為亮。
- digitalWrite(ledPin, ledState);
- }
- // 系統調用,無限循環方法
- void loop() {
- // 讀取按鍵的狀態
- int reading = digitalRead(buttonPin);
- // 判斷當前的按鍵狀態是否和之前有所變化
- if (reading != lastButtonState) {
- // 如果按鍵發生了變化,
- // 則重新設置最近一次抖動的時間。
- lastDebounceTime = millis();
- }
- // 判斷按鍵按下或抬起的狀態時間間隔是否大于延遲抖動的時間長度。
- // 方法millis()可以獲取當前時間,單位統一為毫秒。
- if ((millis() - lastDebounceTime) > debounceDelay) {
- // 判斷當前的按鍵狀態是否和之前有所變化
- if (reading != buttonState) {
- // 如果發生了變化,
- // 則更新按鍵狀態變量。
- buttonState = reading;
- // 判斷按鍵的狀態是否為按下,
- // 只有在按鍵按下的時候,
- // 才改變LED神燈的狀態。
- if (buttonState == HIGH) {
- // 如果LED神燈當前為亮度,
- // 則變為滅。如果為滅,
- // 則變為亮。
- ledState = !ledState;
- }
- }
- }
- // 最終改變電路板上LED神燈的狀態
- digitalWrite(ledPin, ledState);
- // 更新按鍵最近一次狀態變化的變量
- lastButtonState = reading;
- }
復制代碼
好!總共的代碼就是醬紫!看起來有些長呢!其實也只是看起來而已啦!老實說這里并沒有出現任何新的面孔,唯一看起來有點繞的,就是對時間延遲的控制。如果覺得有些吃力,可以回顧一下《另一種時間延遲》小節所學的內容。之所以能夠最終解決抖動問題,其實就是通過加入時間延遲來解決的。通過延長按鍵狀態改變的時間長度,來最終消除信號的抖動。
圖片來源: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
|