實驗中我們將用到按鍵或者按鍵模塊,常見的有2腳按鍵和4腳按鍵,其內部如圖2-25所示。當按下按鍵時,就會接通按鍵兩端,放開時,兩端會再次斷開。
所需材料
Arduino、面包板、LED一個、按鍵一個、220Ω電阻一個、10KΩ電阻一個
連接示意圖
原理圖
如上圖所示,我們使用了兩個電阻。LED的一端,我們使用了220Ω的電阻,按鍵一端,我們使用了10K的電阻,兩個電阻的作用分別如下:
------------------------------------------------------------
限流電阻
一般LED的最大能承受的電流為25mA,如若直接將LED連接到電路中,當其點亮時,如果電流過大,很容易燒毀。如圖2-24所示,我們在LED一端串聯(lián)了一個電阻R2,這樣做可以控制流過LED的電流,防止損壞LED。這個電阻我們稱之為限流電阻。
下拉電阻
在Arduino的2號引腳到GND之前,連接了一個阻值10K的電阻。如果沒有該電阻,當未按下按鍵時,2號引腳會一直處于懸空 狀態(tài),此時使用digitalRead() 讀取2號引腳狀態(tài),會得到一個不穩(wěn)定的值(可能是高,也可能是低)。添加這個R1電阻到地就是為了穩(wěn)定引腳的電平,當引腳懸空時,就會識別為低電平。而這種將某節(jié)點通過電阻接地的做法,叫做下拉,這個電阻叫做下拉電阻。
------------------------------------------------------------
實現(xiàn)方法分析
當未按下按鍵時,2號引腳檢測到的輸入電壓為低電平;當按下按鍵時,會導通2號引腳和VCC,此時2號引腳檢測到的輸入電壓為高電平。通過判斷按鍵是否被按下,來控制LED的亮滅。
示例程序
你可以在 Arduino IDE菜單>文件>示例>02.Digital>Button 中找到以下程序:
- /*
- Button
- 通過2號引腳連接的按鍵,控制13號引腳連接的LED
- 備注:大多數(shù)Arduino的13號引腳上都連接了名為L的LED.
- created 2005
- by DojoDave <<a href="http://www.0j0.org" target="_blank">http://www.0j0.org</a>>
- modified 30 Aug 2011
- by Tom Igoe
- This example code is in the public domain.
- <a href="http://www.arduino.cc/en/Tutorial/Button" target="_blank">http://www.arduino.cc/en/Tutorial/Button</a>
- */
- // 設置各引腳別名
- const int buttonPin = 2; // 連接按鍵的引腳
- const int ledPin = 13; // 連接LED的引腳
- // 變量定義
- int buttonState = 0; // 存儲按鍵狀態(tài)的變量
- void setup() {
- // 初始化LED引腳為輸出狀態(tài)
- pinMode(ledPin, OUTPUT);
- // 初始化按鍵引腳為輸入狀態(tài)
- pinMode(buttonPin, INPUT);
- }
- void loop(){
- // 讀取按鍵狀態(tài)并存儲在變量中
- buttonState = digitalRead(buttonPin);
- // 檢查按鍵是否被按下
- // 如果按鍵按下,那buttonState應該為高電平
- if (buttonState == HIGH) {
- // 點亮LED
- digitalWrite(ledPin, HIGH);
- }
- else {
- // 熄滅LED
- digitalWrite(ledPin, LOW);
- }
- }
編譯并上傳該程序后,按下按鍵,你會觀察到LED會被點亮,松開按鍵,LED又會熄滅。
項目進階
對于在以上項目,我們還可以做如下修改。
連接示意圖
如上,我們去掉了原來電路中2號引腳連接的下拉電阻,并將按鍵的一端連接到GND;
原理圖
同時,我們需要將原程序setup() 部分中的
- pinMode(buttonPin,INPUT);
修改為
- pinMode(buttonPin,INPUT_PULLUP);
這樣能使能該引腳上的內部上拉電阻,等效于在該引腳到VCC之間連接一個外部上拉電阻。
-----------------------------------------------------
上拉電阻
同下拉電阻一樣,可以穩(wěn)定I/O口電平,不同的是電阻連接到VCC,將引腳穩(wěn)定在高電位。這種電阻叫做上拉電阻。
-----------------------------------------------------
這里使用的是內部上拉電阻,也可以使用外部上拉電阻替代。穩(wěn)定懸空引腳的電平所用電阻應該選擇合適的阻值,例如10K。
示例程序
修改后的程序代碼如下:
- /*
- 按鍵控制LED - 1
- <a href="http://www.arduino.cn/" target="_blank">http://www.arduino.cn/</a>
- */
- int buttonPin = 2;
- int ledPin = 13;
- int buttonState = 0;
- void setup()
- {
- // 初始化I/O口
- pinMode(buttonPin,INPUT_PULLUP);
- pinMode(ledPin,OUTPUT);
- }
- void loop()
- {
- buttonState = digitalRead(buttonPin);
- // 按住按鍵時,點亮LED;放開按鍵后,熄滅LED。
- if(buttonState==HIGH)
- {
- digitalWrite(ledPin,LOW);
- }
- else
- {
- digitalWrite(ledPin,HIGH);
- }
- }
接下來我們要對控制程序做一個升級,完成一個新的控制效果。按一下按鍵,點亮LED;再按一下按鍵,熄滅LED。
程序代碼如下:
- /*
- 按鍵控制LED - 2
- <a href="http://www.arduino.cn/" target="_blank">http://www.arduino.cn/</a>
- */
- int buttonPin = 2;
- int ledPin = 13;
- boolean ledState=false; // 記錄LED狀態(tài)
- boolean buttonState=true; // 記錄按鍵狀態(tài)
- void setup()
- {
- // 初始化I/O口
- pinMode(buttonPin, INPUT_PULLUP);
- pinMode(ledPin,OUTPUT);
- }
- void loop()
- {
- // 等待按鍵按下
- while(digitalRead(buttonPin)==HIGH){}
- // 當按鍵按下時,點亮或熄滅LED
- if(ledState==true)
- {
- digitalWrite(ledPin,LOW);
- ledState=!ledState;
- }
- else
- {
- digitalWrite(ledPin,HIGH);
- ledState=!ledState;
- }
- delay(500);
- }
編譯并上傳該程序后,每按一下按鍵,LED狀態(tài)都會改變。以上程序中,使用了
- while( digitalRead(buttonPin)==HIGH ) { }
因為在初始化時,我們已經將buttonPin引腳設為了輸入上拉狀態(tài)。如果沒有按下按鍵,使用digitalRead(buttonPin) 讀出的值始終為高電平,這個循環(huán)也將一直運行;當你按下按鍵后,digitalRead(buttonPin) 讀出了低電平,while循環(huán)的判斷條件為假,程序會退出這個循環(huán),并開始運行此后的語句。這樣我們就實現(xiàn)了一個等待用戶按下按鍵的效果。
程序末尾有一個delay(500) 的延時,它在這里是極其重要的。可以嘗試刪去這個延時操作,再上傳程序到Arduino。你會發(fā)現(xiàn)按鍵經常出現(xiàn)控制失靈的情況。這是因為程序運行的非?欤瑳]有了延時操作,你按下按鍵到放開按鍵的間隔時間雖然極短,但loop中的語句可能已經運行了很多次,很難確定你放開按鍵時正在運行的loop() 循環(huán)是點亮還是熄滅LED。正是這樣的原因,程序變得不那么好用了。
上面程序中,我們使用延時操作來使兩次按鍵間產生一定的間隔時間,在間隔時間內Arduino會忽略按鍵按下情況,從而達到區(qū)分兩次按鍵的目的。
承擔因您的行為而導致的法律責任,
本站有權保留或刪除有爭議評論。
參與本評論即表明您已經閱讀并接受
上述條款。