輸入、處理、輸出,一個簡單的小遊戲
上次的 Hello World 程式示範了怎樣用 Arduino 控制數碼輸出。今次將加入數碼輸入和處理的部份,做一個簡單的電子遊戲。
組件
- Arduino UNO
- 一紅一綠 LED
- 一個按鍵。
程式
紅綠 LED 會隨機亮起,遊戲目的是要在綠色燈亮起的時候按鍵。要是在綠色燈亮起關掉之前沒有按下按鍵,或在紅色燈亮起時按下,遊戲就會完結。一直在正確的時間按下按鍵,遊戲的速度就會越來越快。
這個 project 將會學習到:
- 使用 function
- 用 Serial 除錯
- 用 LED 作數碼輸出
- 用按鍵作數碼輸入
使用 function
這個程式比之前的複雜,有些部份的源碼將會重覆,為了重用這些源碼我們可以將之寫成 function :
// standard sigmoid curve function
double sigmoid(double t) {
double e = 2.71828182845904523536;
return 1 / (1 + pow(e, -t));
}
寫法跟 C 系的語法十分相似,詳細資料可參考 Arduino 的 Reference 。
用 Serial 除錯
現代軟件工程發展很快,但開發時最有效的除錯方式還是寫 log,在Arduino 也不例外。雖然它沒有特定的檔案系統給你寫 log 檔,但它的 USB 介面只要連接電腦,就可以當一般的 console 寫 log 。
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("********* GAME START ********* ");
}
用 Serial.print()
或 Serial.println()
寫到 Serial 就可以在 Arduino IDE 上的 Serial Monitor 上看到你寫的輸出了。
在除錯時你會發現它是無可取代的重要工具!
用 LED 作數碼輸出
這基本跟上一次沒有分別,只是今次用了 2 個 LED。只要把他們接到不同輸出即可。
const int LED_R = 13;
const int LED_G = 12;
void setup() {
pinMode(LED_R, OUTPUT);
pinMode(LED_G, OUTPUT);
}
void loop() {
digitalWrite(LED_R, LOW);
digitalWrite(LED_G, HIGH);
}
按鍵輸入
這次使用的是輕觸開關 (Momentary tactile pushbutton switch)。它的特點是按下去時會有一瞬間通電,一放手它就會彈回關閉的狀態。
最簡單的使用方法是這樣:
void loop(){
val = digitalRead(BUTTON); // read input value and store it
// check whether the input is HIGH (button pressed)
if (val == HIGH) {
// do something when button ON
}
}
不過要留意 Arduino 的 loop() 會高速地不斷執行,如果直接把工作放在這個 if 入面,雖然按下鍵時只有一瞬間,但這個 loop() 也會被執行許多次。
要避免這情況可以修改程式,讓它只在「由沒按的狀態變為按下的狀態」才執行我們想要的程式:
void loop(){
buttonState = digitalRead(BUTTON);
buttonPressed = (buttonState == HIGH) && (lastButtonState == LOW);
lastButtonState = buttonState;
if (buttonPressed) {
// do something when button changed to ON
}
}
整合
有以上的部份,實作這個程式就十分簡單。
它大概有以下三部份:
1. 未開始
- 等待用家啟動遊戲,紅綠兩個 LED 輪流閃動。
2. 遊戲進行中
- 設定下一次開始和關閉燈的時間、以及哪一顏色的燈被開啟
- 如果沒開燈而又夠時間開燈,便開燈
- 如果已經開綠燈而玩家及時按鍵,玩家得分並重新開始;如果玩家沒及時按鍵,遊戲完結。
- 如果已經開紅綠而玩家按鍵,遊戲中止;如果玩家沒按鍵,玩家得分並重新開始。
3. 遊戲完結
- 閃亮紅燈、等待玩家按鍵回到「未開始」狀態。
示範
實作的影片示範:
雖然這只是個無聊小遊戲,但它已經包括為微處理器編程,用它讀取輸入、處理資料和輸出!很簡單,卻十分奇妙!