|
Hi,大家好!又跟大家見面啦!在上一次講解按鍵開關(guān)臨近結(jié)束的時(shí)候,我們提到在正常的使用過程中,美中有不足,按鍵開關(guān)還有一個(gè)小問題需要解決。那是什么問題呢?
每當(dāng)你按下或抬起按鍵開關(guān)的一瞬間,由于讀取信號(hào)的操作是持續(xù)進(jìn)行的,又由于按鍵自身的物理元器件的問題,每次觸碰的一瞬間,可能會(huì)發(fā)生多次短暫的物理接觸,以至于最終產(chǎn)生的信號(hào)發(fā)生了抖動(dòng)。為了消除這種抖動(dòng),讓按鍵變得更加好用,這次我們一起來試試看如何解決這個(gè)問題!這一次的學(xué)習(xí)過程中,我們用到了之前在《另一種時(shí)間延遲》中學(xué)過的知識(shí)點(diǎn)。如果你對(duì)此還有印象,那將會(huì)對(duì)這一次的學(xué)習(xí)有很大的幫助呢!
好!介紹的差不多了。還是老環(huán)節(jié),先準(zhǔn)備一下我們需要的材料。
硬件方面
arduino-read-digital.jpg (121.51 KB, 下載次數(shù): 875)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino電路配件
具體包括如下:
- Arduino UNO電路板(1塊)
- 面包板(1塊)
- 10k電阻(1個(gè))
- 按鍵開關(guān)(1個(gè))
- 面包線(3根)
咦?是不是看起來很像上一次在《按鍵開關(guān)》那一節(jié)中所使用的硬件��!哼哼!其實(shí)不單是硬件用的一樣,連電路的連接也是一摸一樣呢!同樣的,這次我們對(duì)按鍵測(cè)試所使用的LED神燈,用的還是Arduino UNO電路板上自帶的那一盞!
軟件方面不多說,依然是Arduino官方提供的IDE。
連接電路
arduino-ide-new.jpg (70.98 KB, 下載次數(shù): 259)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino連接開關(guān)按鍵電路示意圖
既然和上一次的電路連接一樣,就不多啰嗦了,我們直接進(jìn)入最后一步!
添加幾行代碼首先,還是新建一個(gè)項(xiàng)目窗口。
arduino-menu.jpg (9.87 KB, 下載次數(shù): 239)
下載附件
2015-12-19 22:08 上傳
圖片來源:Arduino官方IDE
然后向其中添加如下代碼:
- // 定義按鍵輸入針腳號(hào)常量,
- // 并初始化為2號(hào)針腳。
- const int buttonPin = 2;
- // 定義LED輸入針腳號(hào)常量,
- // 并初始化為13號(hào)針腳。
- // 注:此處我們使用的LED神燈是Arduino UNO電路板自帶,
- // 此神燈對(duì)應(yīng)的針腳號(hào)默認(rèn)為13,此數(shù)值不得隨意更改,
- // 所以這里定義的數(shù)值13是為了和默認(rèn)值相對(duì)應(yīng)。
- const int ledPin = 13;
- // 定義記錄LED神燈當(dāng)前狀態(tài)的變量,
- // 并初始化狀態(tài)為HIGH。
- int ledState = HIGH;
- // 定義記錄按鍵當(dāng)前狀態(tài)的變量
- int buttonState;
- // 定義記錄按鍵最近一次狀態(tài)變化的變量,
- // 并初始化狀態(tài)為L(zhǎng)OW。
- int lastButtonState = LOW;
- // 定義記錄最近一次抖動(dòng)的時(shí)間變量,
- // 并初始化時(shí)間為0毫秒。
- long lastDebounceTime = 0;
- // 定義延遲抖動(dòng)的時(shí)間變量,
- // 并初始化為50毫秒。
- long debounceDelay = 50;
- // 對(duì)Arduino電路板或相關(guān)狀態(tài)進(jìn)行初始化方法
- void setup() {
- // 設(shè)置按鍵的針腳為輸入狀態(tài)
- pinMode(buttonPin, INPUT);
- // 設(shè)置電路板上LED神燈的針腳狀態(tài)為輸出狀態(tài)
- pinMode(ledPin, OUTPUT);
- // 設(shè)置電路板上LED神燈的初始狀態(tài),
- // 此處因?yàn)樽兞縧edState的初始狀態(tài)為HIGH,
- // 所以LED神燈的初始狀態(tài)為亮。
- digitalWrite(ledPin, ledState);
- }
- // 系統(tǒng)調(diào)用,無限循環(huán)方法
- void loop() {
- // 讀取按鍵的狀態(tài)
- int reading = digitalRead(buttonPin);
- // 判斷當(dāng)前的按鍵狀態(tài)是否和之前有所變化
- if (reading != lastButtonState) {
- // 如果按鍵發(fā)生了變化,
- // 則重新設(shè)置最近一次抖動(dòng)的時(shí)間。
- lastDebounceTime = millis();
- }
- // 判斷按鍵按下或抬起的狀態(tài)時(shí)間間隔是否大于延遲抖動(dòng)的時(shí)間長(zhǎng)度。
- // 方法millis()可以獲取當(dāng)前時(shí)間,單位統(tǒng)一為毫秒。
- if ((millis() - lastDebounceTime) > debounceDelay) {
- // 判斷當(dāng)前的按鍵狀態(tài)是否和之前有所變化
- if (reading != buttonState) {
- // 如果發(fā)生了變化,
- // 則更新按鍵狀態(tài)變量。
- buttonState = reading;
- // 判斷按鍵的狀態(tài)是否為按下,
- // 只有在按鍵按下的時(shí)候,
- // 才改變LED神燈的狀態(tài)。
- if (buttonState == HIGH) {
- // 如果LED神燈當(dāng)前為亮度,
- // 則變?yōu)闇纭H绻麨闇纾?br />
- // 則變?yōu)榱痢?br />
- ledState = !ledState;
- }
- }
- }
- // 最終改變電路板上LED神燈的狀態(tài)
- digitalWrite(ledPin, ledState);
- // 更新按鍵最近一次狀態(tài)變化的變量
- lastButtonState = reading;
- }
復(fù)制代碼
好!總共的代碼就是醬紫!看起來有些長(zhǎng)呢!其實(shí)也只是看起來而已啦!老實(shí)說這里并沒有出現(xiàn)任何新的面孔,唯一看起來有點(diǎn)繞的,就是對(duì)時(shí)間延遲的控制。如果覺得有些吃力,可以回顧一下《另一種時(shí)間延遲》小節(jié)所學(xué)的內(nèi)容。之所以能夠最終解決抖動(dòng)問題,其實(shí)就是通過加入時(shí)間延遲來解決的。通過延長(zhǎng)按鍵狀態(tài)改變的時(shí)間長(zhǎng)度,來最終消除信號(hào)的抖動(dòng)。
圖片來源:Arduino官方IDE的文件編輯菜單選項(xiàng)
點(diǎn)擊上圖中標(biāo)有向右指向的箭頭圖標(biāo),將代碼一鍵燒入Arduino UNO電路板�,F(xiàn)在試試看,每次單擊按鍵,電路板上的LED神燈會(huì)不會(huì)有所變化?如果一切正常,現(xiàn)在每單擊一下按鍵,LED神燈的狀態(tài)就會(huì)變化一次。在《按鍵開關(guān)》那一節(jié),是每次按下按鍵,點(diǎn)亮LED神燈。抬起按鍵,LED神燈熄滅。而現(xiàn)在是每單擊一次按鍵,LED神燈變化一次。可以體會(huì)一下它們之間的不同。
總結(jié)通過這次學(xué)習(xí),我們解決了按鍵的信號(hào)抖動(dòng)的問題。解決的核心方法呢,是通過引入時(shí)間延遲,來消除信號(hào)抖動(dòng)。技術(shù)來說并沒有碰到新內(nèi)容,難點(diǎn)就在于對(duì)時(shí)間延遲的理解。
下期預(yù)告通過前兩次學(xué)習(xí),我們發(fā)現(xiàn)每次連接按鍵總要外加一個(gè)10k的電阻。在電路合理連接的情況下,能不能不引入電阻,直接就能使用按鍵呢!好!下一次,我們將一起學(xué)習(xí)一種如何不用外接電阻,也能正常使用按鍵的方法!
ohcoder的系列精彩Arduino教程:
Arduino教程-初識(shí)Arduino(包含本教程目錄):http://www.torrancerestoration.com/bbs/dpj-41334-1.html
Arduino教程-開篇:http://www.torrancerestoration.com/bbs/dpj-41335-1.html
Arduino教程-點(diǎn)亮LED神燈:http://www.torrancerestoration.com/bbs/dpj-41336-1.html
Arduino教程-讓LED神燈閃爍:http://www.torrancerestoration.com/bbs/dpj-41337-1.html
Arduino教程-讓LED神燈亮度漸變:http://www.torrancerestoration.com/bbs/dpj-41338-1.html
Arduino教程-獲取輸入數(shù)字信號(hào):http://www.torrancerestoration.com/bbs/dpj-41339-1.html
Arduino教程-獲取輸入模擬信號(hào):http://www.torrancerestoration.com/bbs/dpj-41340-1.html
Arduino教程-另一種時(shí)間延遲:http://www.torrancerestoration.com/bbs/dpj-41331-1.html
Arduino教程-按鍵開關(guān):http://www.torrancerestoration.com/bbs/dpj-41341-1.html
Arduino教程-停止抖動(dòng)!:http://www.torrancerestoration.com/bbs/dpj-41333-1.html
Arduino教程-拋棄外部電阻!:http://www.torrancerestoration.com/bbs/dpj-41332-1.html
Arduino教程-用按鍵開關(guān)計(jì)數(shù):http://www.torrancerestoration.com/bbs/dpj-41330-1.html
………后續(xù)持續(xù)更新中請(qǐng)打開:http://www.torrancerestoration.com/bbs/dpj-41334-1.html
|
|