【Arduino入門】如何用按鈕開關控制LED燈

通常大家一開始設計程式的第一步就是Print “Hello World”或”這是我的第一個程式設計”,讓IDE列印(出現)這些字,當看到顯示這些時,感覺自己與電腦連線上了,心中浮起它懂得我要它做什麼事的小小喜悅!

在這一章LED糸列程式設計中,將分幾個章節一步一步讓這感覺再昇華,就一起來用程式設計讓Arduino Uno知道開關按鈕已被按下去,並創造LED燈光秀。GO~

  • LED交互閃爍
  • LED紅綠燈時間控制
  • 按鈕開關控制LED

LED交互閃爍

實驗準備材料

  •  LED x 2顆  (分別不同顏色)
  • 220Ω電阻 x 2顆
  • 杜邦線 x 3條
  • 麵包板 x 1片

設計邏輯想法

  1.  延伸上一篇中13腳的LED閃爍的作法(請參考”Arduino設計入門”),這次分別讓兩顆LED交互閃爍。
  2.  這裏使用了藍色LED與紅色LED,先讓藍LED亮著,並停留幾秒,而另一顆紅色LED暗著,也跟著停留幾秒。
  3. 停留時間結束後,換成紅色LED亮,藍色LED暗,停留幾秒。
  4. 依這樣子邏輯讓它們持續運行。

程式流程圖

程式流程圖是一種圖形化工具,它以直觀的方式展示了程式的運作過程。流程圖通過不同的圖形符號表示程式中的指令和流程方向,如方框顯示操作步驟,菱形表示決策判斷。這讓程式設計師能夠在開始編寫程式碼之前,清楚地規劃出程式的結構和邏輯。流程圖有助於發現邏輯錯誤,提高程式設計的效率和準確性,是理解和溝通複雜程式概念的有力工具。

將上頭的邏輯想法畫成流程圖,這樣子可以大大的幫助接下來要寫程式時的正確性和效率。

程式設計(1)

這些程式都已驗證過沒有問題,點擊右上方”copy”,然後貼上你的IDE中上傳就可以執行。

				
					const int ledBlue = 6;    //以整數(int)將6號腳位取名字(宣告)為"ledBlue",並設為常數(const)
const int ledRed = 9;     //以整數(int)將9號腳位取名字(宣告)為"ledRed",並設為常數(const)

void setup() {
  // put your setup code here, to run once:
  pinMode (ledBlue, OUTPUT);    //設ledBlue腳位為輸出
  pinMode (ledRed, OUTPUT);     //設ledRed腳位為輸出
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite (ledBlue, HIGH);   //ledBlue輸出為高電位
  digitalWrite (ledRed, LOW);     //ledRed輸出為低電位
  delay (1000);                   //停留1000毫秒=1秒
  digitalWrite (ledBlue, LOW);    //ledBlue輸出為低電位
  digitalWrite (ledRed, HIGH);    //ledRed輸出為高電位
  delay (1000);                   //停留1000毫秒=1秒
}
				
			

程式設計(2)

在程式設計(1)中,我們將想法一步一步的設計成程式碼,但如果我們想改讓紅色LED先亮,藍色LED暗著時,這時候程式需要一段一段檢查並將原”HIGH”改成”LOW”,反之”LOW”也改成”HIGH”,這程式碼需要改四行,但如果程式碼行數有上百上千時,那修改起來就很頭痛,而且容易出現錯誤!

那有沒有什麼方法能讓這程式設計更便利呢?答案是有的,因為程式語言依個人的熟練度越高時,你就可以使用更多指令將程式碼變的更簡潔,並且容易維護。

接下來使用Boolean(布林)這指令來建立這篇程式碼,讓後續想要那一LED先亮,就它先亮,方便修改。

程式碼解釋

在程式中取了(宣告變數)一個”state”為布林值,給它的狀態為true,在布林值只有兩種狀態,一個是true=HIGH=1,另一個false=LOW=0,就只有是與否/真和錯的狀態;但是這裏我們不需要再設定一個名稱宣告變數為false,只需要使用這”!”(驚嘆號),沒錯你沒看錯,它在程式語言中代表著相反的意思,所以我們在loop裏的程式只需要在”state”前加上”!”,就可以將原設定的意思相反,成為false了,那要修改那一顆LED先亮時,我們只需要把一開始的”state=true”改成”false”就可以,那底下loop中的LED也就跟著相反了,是不是很方便呢!

				
					const int ledBlue = 6;    //以整數(int)將6號腳位取名字(宣告)為"ledBlue",並設為常數(const)
const int ledRed = 9;     //以整數(int)將9號腳位取名字(宣告)為"ledRed",並設為常數(const)
bool state = true;        //將"state"設定成布林值為true

void setup() {
  // put your setup code here, to run once:
  pinMode (ledBlue, OUTPUT);    //設ledBlue腳位為輸出
  pinMode (ledRed, OUTPUT);     //設ledRed腳位為輸出
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite (ledBlue, state);     //ledBlue輸出為true=高電位
  digitalWrite (ledRed, !state);     //ledRed輸出為false=低電位 ("!"在程式中有相反的意思)
  delay (1000);                      //停留1000毫秒=1秒
  digitalWrite (ledBlue, !state);    //ledBlue輸出為false=低電位
  digitalWrite (ledRed, state);      //ledRed輸出為true高電位
  delay (1000);                      //停留1000毫秒=1秒
}
				
			

實物接線

  1.  將各LED的長腳正極(+)串聯一個220歐姆,也可以接其他歐姆值在330Ω以下都可以,歐姆值越高代表電阻值越高,LED燈的亮度會越暗而己,但是不可以不接,因為Arduino輸出的5V電壓會將LED燒毀;另外LED短腳負極(-)統一都插在麵包板一側旁的負極孔中。
  2. 使用杜邦線插在電阻的另外一頭,將它們連接上Arduino Uno板子上的6號和9號孔中;負極的孔用一條杜邦線連接到板子上的”GND”接地,這樣就完成實物配線了,如下圖片。

實物執行影片

LED紅綠燈時間控制

實驗準備材料

  •  紅/黃/綠LED x 各1顆
  • 220Ω電阻 x 3顆
  • 麵包板 x 1片
  • 杜邦線 x 4條

設計邏輯想法

  1.  設計出十字路口上的紅綠燈執行狀況。
  2. 紅/黃/線LED只會亮一盞,並使得各LED亮著時間不同。
  3. 想像當車流量大時,必須立即改變綠/紅燈的亮著時間,只改變兩個程式就可以執行!

程式流程圖

 

程式設計

在程式碼開頭,不只使用了布林宣告變數”state”狀態之外,在這程式中再加了兩個宣告變數,分別做為紅色LED與綠色LED的停留時間,相信到這裏,你已經看出端倪,所以當在車流量多寡時,我們只需要改變”redTime”和”greenTime”的數值,就可以立即讓底下的紅色LED與綠色LED停留時間改變,使用這宣告變數是不是很方便呢!

 

				
					const int ledRed = 3;         //設定紅色LED腳位為3號
const int ledYellow = 6;      //設定黃色LED腳位為6號
const int ledGreen = 9;       //設定綠色LED腳位為9號
bool state = true;            //宣告state為bool值為true
int redTime = 2000;           //宣告redTime為2000
int greenTime = 2500;         //宣告greenTime為2500

void setup() {
  // put your setup code here, to run once:
  pinMode(ledRed, OUTPUT);      //設定紅色LED腳位為輸出
  pinMode(ledYellow, OUTPUT);   //設定黃色LED腳位為輸出
  pinMode(ledGreen, OUTPUT);    //設定綠色LED腳位為輸出
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ledRed, state);      //紅色LED亮
  digitalWrite(ledYellow, !state);  //黃色LED暗
  digitalWrite(ledGreen, !state);   //綠色LED暗
  delay(redTime);                   //停留2000毫秒
  digitalWrite(ledRed, !state);     //紅色LED暗
  digitalWrite(ledYellow, !state);  //黃色LED暗
  digitalWrite(ledGreen, state);    //綠色LED亮
  delay(greenTime);                 //停留2500毫秒
  digitalWrite(ledRed, !state);     //紅色LED暗
  digitalWrite(ledYellow, state);   //黃色LED亮
  digitalWrite(ledGreen, !state);   //綠色LED暗
  delay(1000);                      //停留1000毫秒
}
				
			

實物接線

實物執行影片

按鈕開關控制LED

實驗準備材料

  •  LED x 1顆
  • 按鈕開關 x 1顆
  • 麵包板 x 1片
  • 杜邦線 x 4條

設計邏輯想法

  • 當按下按鈕開關時,LED會亮起,再按一下按鈕開關,LED就關閉,但要防止按鈕一直按著的,導致LED一直自動變換!

程式流程圖

程式設計

運用”if()”指令來判斷按鈕開關是否有按下,當按下時就交換LED亮與暗;並且能判斷按鈕開關是否有放開,如沒有則不會改變LED狀態。

程式碼解釋

  1.  從第15行程式開始,當按鈕開關(buttonPin)沒被按下時的腳位狀態是在”setup()”裏設定的true,與if判斷程式中”!HIGH”不成立,也與18行中的else if判斷式中的switchUp狀態不符合,此時這段程式不會有接下來的動作。
  2. 但當按鈕開關按下時,狀態由原true改為false,15行的判斷式就會成立,並且switchUp狀態為true也成立,程式就會往下執行16行,將”state”改變,而讓17行裏的LED腳位輸出對應的改變。
  3. 沒有放開按鈕開關時第15行和第19行的判斷式不成,因為switchUp一直處在false的狀態。
  4. 放開按鈕開關後,第19行判斷式就成立,而執行第20行,將switchUp狀態改為true,再回到上頭的狀態。
				
					const int buttonPin = 2;  // 宣告按鈕開關buttonPin為2號腳
const int ledPin = 6;     // 宣告ledPin為6號腳

bool state = false;    // 宣告一狀態為0(關閉)
bool switchUp = true;  // 宣告按鈕開關的狀態為1,便於記錄按鈕狀況是否有變化

void setup() {
  pinMode(ledPin, OUTPUT);    //設定LED腳位為輸出
  digitalWrite(ledPin, LOW);  //設定LED腳位一開始為低電位
  pinMode(buttonPin, INPUT_PULLUP);  //設定按鈕開關腳位為輸入,並使用上拉電阻
  digitalWrite(buttonPin, HIGH);
}

void loop() {
  if (digitalRead(buttonPin) != HIGH && switchUp == true) {         //如果按鈕開關被按下,並且switchUp曾經被放開過成立後
    state = !state;                                                 //狀態交換成相反的狀態
    digitalWrite(ledPin, state);                                    //LED依上頭state狀態來做改變
    switchUp = false;                                               //再將按鈕開關狀態由高電位改成低電位
  } else if (digitalRead(buttonPin) == HIGH && switchUp != true) {  //如果當按鈕開關被放開了,這時switchUp狀態處於低電位成立後
    switchUp = true;                                                //將switch狀態就改成1
  }
}

				
			

實物接線

實物執行影片

結論

此篇介紹了使用Bool(布林)指令,在控制眾多的元件時,可以便於管理,也使用if(如果)判斷式,來判斷Arduino在收到的訊號時,是否執行底下的程式,這些指令在未來還會有更多的運用,使得設計更接近智能化,就讓我們一起探索!

有主意,就動手!下一篇見~

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端