如果一個單晶片的系統只做 LED 顯示,未免也太單調了些。在這一節中,我們將教你如何讓 Arduino UNO 讀取外部按鍵的狀態,然後變更 LED 的閃爍速度。
上一節我們只是讓 LED 在固定的時間內亮起、滅掉,或者是讓一整排的 LED 能夠個別點亮或滅掉,而當你要改變閃爍速度或亮滅順序的時候,你就必須要重新撰寫一次程式碼、編譯然後燒錄到 Arduino 中。
這樣的過程其實一點也不有趣,如果我們能夠靠按下一個或多個按鈕來讓閃爍速度改變或讓 LED 跑馬燈的順序改變,那應該會有去得多對吧?
這一節將告訴你,如何讓 Arduino 能夠讀取按鈕按下的動作,並且讓上述的功能實現!
與點亮 LED 時相同,我們必須要在程式中定義腳位資訊,讓 Arduino 知道哪個腳位是做什麼,而因為按鈕是屬於輸入,因此在 setup()
中我們必須加入這行程式碼:
pinMode(腳位, INPUT); // 腳位為 Arduino 腳位
如此一來便能使那個腳位作為輸入來讀取,但這樣還不夠,我們只是使腳位能夠讀取輸入訊號罷了,但在程式中並無法直接讀取,我們必須要用一個變數來接收讀取到的值,如:
int input = digitalRead(腳位); // 腳位為 Arduino 腳位
如此,當你按下按鈕時,變數 input 便會變成 1(或0,根據電路),有了這個變數,我們便可以在程式中做更多的流程控制。
是否看過許多用一個按鍵就能開關的電器呢?我們將來實作這一個功能,來幫助你理解這 digitalRead(腳位)
的使用方式。
int led = 13; // LED 腳位
int btn = 2; // 按鈕腳位
int isPressed = 0; // 是否被按過的判斷
void setup()
{
// 設定 led 為輸出
pinMode(led, OUTPUT);
// 設定 btn 為輸入
pinMode(btn, INPUT);
}
void loop()
{
int b = digitalRead(btn);
if( b ) {
// 如果按鈕按下時,isPressed 反向
isPressed = !isPressed;
// 當按鈕按住時進入無窮迴圈
while(digitalRead(btn));
}
if( isPressed )
digitalWrite(led, HIGH); // 點亮
else
digitalWrite(led, LOW); // 滅掉
}
在這個範例程式中,我們將按鈕的輸入腳位設定在 Arduino UNO 的第 2 隻腳,然後使用板子上的 LED 來顯示我們的結果。
當程式燒錄到 Arduino 後,你會看到 LED 以大約每秒一次的頻率閃爍,這時你可以按下按鈕,應會看到 LED 加速閃爍。
int led = 13; // LED 腳位
int btn = 2; // 按鈕腳位
void setup()
{
// 設定 led 為輸出
pinMode(led, OUTPUT);
// 設定 btn 為輸入
pinMode(btn, INPUT);
}
void loop()
{
int b = digitalRead(btn);
if( b ) {
// 如果按鈕按下時,閃爍速度為 100 ms
blink( 100 );
} else {
// 如果按鈕放開時,閃爍速度為 1000 ms
blink( 1000 );
}
}
// blink( ms )
void blink(int ms)
{
digitalWrite(led, HIGH); // 點亮
delay( ms );
digitalWrite(led, LOW); // 點亮
delay( ms );
}
還記得上一節的 LED 跑馬燈嗎,現在我們可以靠一個按鈕就讓它改變方向囉!
int BASE = 10; // 從腳位 10 開始
int NUM = 4; // LED 的總數
int btn = 2; // 按鈕腳位
bool isPressed = false;
void setup()
{
// 用迴圈設定腳位
for (int i = BASE; i < BASE + NUM; i ++)
{
pinMode(i, OUTPUT);
}
// 設定 btn 為輸入
pinMode(btn, INPUT);
}
void loop()
{
int b = digitalRead(btn);
int i = 0;
if( b )
{
isPressed = !isPressed;
// 當按鈕一值按著時就卡在迴圈中
while(digitalRead(btn));
}
if( isPressed )
{
for (int i = BASE; i < BASE + NUM; i++)
{
digitalWrite(i, LOW);
delay(100);
}
for (int i = BASE; i < BASE + NUM; i++)
{
digitalWrite(i, HIGH);
delay(100);
}
} else {
for (int i = BASE + NUM - 1; i >= BASE; i--)
{
digitalWrite(i, LOW);
delay(500);
}
for (int i = BASE + NUM - 1; i >= BASE; i--)
{
digitalWrite(i, HIGH);
delay(500);
}
}
}