# 2025 陽明交大電機營 Arduino組
### 底下Exercise與Lab的程式碼都會被挖空,請根據題目要求將程式碼完成
---
# Exercise 0 前置作業
## CH340與Arduino IDE
https://drive.google.com/drive/folders/1xobgSl3XplSYGP4RiAqiI1rOKVg4xDGa?usp=drive_link
## 工具箱
1. Arduino UNO版(含連接線)*1
2. 麵包版*1
3. 公對公杜邦線*18
4. 公對母杜邦線*5
6. 色環電阻*4
7. LED*4
8. 可變電阻*1
9. 按鈕*1
10. 超音波感測器*1
11. 伺服馬達*1
12. 無源蜂鳴器*1
13. 搖桿*1
---
# Exercise 1 可變電阻與LED
---

# Exercise 2 按鈕
---

## 程式碼
```arduino=
int pushbutton = 2; //設定按鈕的接腳
int buttonState = 1; //代表按鈕現在的狀態
int beforeState = 1; //代表按鈕的前一個狀態
int times = 0; //設定一個用於計次的整數
void setup() {
Serial.begin(9600); //開始與電腦連接
___1___ //設定按鈕並且給予上拉電阻
}
void loop() {
buttonState = digitalRead(pushbutton); //讀入此時的按鈕狀態
if(buttonState == 0 && beforeState == 1) { //當按鈕被按下時執行
___2___ //讓程式暫停50毫秒後再繼續讀取
times++; //計次數加1
___3___ //在視窗列印出計次數並換行
}
beforeState = buttonState; //將此時的按鈕狀態存到前一刻的按鈕狀態
}
```
## Problem 1 設定按鈕給予上拉電阻
```arduino=5
void setup() {
Serial.begin(9600); //開始與電腦連接
___1___ //設定按鈕並且給予上拉電阻
}
```
<aside>
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `pinmode(pushbutton,INPUT);`
>
>
> B ) `pinmode(pushbutton,INPUT_PULLUP);`
>
> C ) `pinMode(pushbutton,Input_Pullup);`
>
> D ) `pinMode(pushbutton,INPUT_PULLUP);`
>
## Problem 2 Debounce
```arduino=11
if(buttonState == 0 && beforeState == 1) { //當按鈕被按下時執行
___2___ //讓程式暫停50毫秒後再繼續讀取
times++; //計次數加1
___3___ //在視窗列印出計次數並換行
}
```
<aside>
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `delay(50);`
>
>
> B ) `Delay(50);`
>
> C ) `Debounce(times);`
>
> D ) `Debounce(buttonState);`
>
## Problem 3 在序列埠監控視窗列印出計次數並換行
```arduino=11
if(buttonState == 0 && beforeState == 1){ //當按鈕被按下時執行
___2___ //讓程式暫停20毫秒後再繼續讀取
times++; //計次數加1
___3___ //在視窗列印出計次數並換行
}
```
<aside>
:::success
Problem 3 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `Serial.print(times);`
>
>
> B ) `serial.print(times);`
>
> C ) `Serial.println("times");`
>
> D ) `Serial.println(times);`
>
# Exercise 3 超音波感測器

---
### 超音波感測器請這樣接。

## 程式碼
```arduino=
int Trig=13;
int Echo=12;
double distance();
void setup() {
Serial.begin(9600); //設定鮑率為9600
__1.1__ //將Trig腳位訂為輸出
__1.2__ //將Echo腳位訂為輸入
}
void loop() {
Serial.print("Distance : ");
Serial.print(distance());
Serial.println("cm");
delay(2000);
}
double distance(){
digitalWrite(Trig,__2.1__); //高電位
delayMicroseconds(10); //持續10微秒
digitalWrite(Trig,__2.2__); //回到低電位
long duration = pulseIn(Echo,HIGH);
return ___3___; //套公式
}
```
## Problem 1 設定腳位的模式
```arduino=5
void setup() {
Serial.begin(9600); //設定鮑率為9600
__1.1__ //將Trig腳位訂為輸出
__1.2__ //將Echo腳位訂為輸入
}
```
<aside>
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
</aside>
```
__1.1__ / __1.2__
```
> A ) `pinMode(Trig,OUTPUT);` / `pinMode(Echo,OUTPUT);`
>
> B ) `pinMode(Trig,INPUT);` / `pinMode(Echo,INPUT);`
>
> C ) `pinMode(Trig,OUTPUT);` / `pinMode(Echo,INPUT);`
>
> D ) `pinMode(Trig,INPUT);` / `pinMode(Echo,OUTPUT);`
>
## Problem 2 發出超音波
```arduino=19
digitalWrite(Trig,__2.1__); //高電位
delayMicroseconds(10); //持續10微秒
digitalWrite(Trig,__2.2__); //回到低電位
```
<aside>
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
</aside>
```
__2.1__ / __2.2__
```
> A ) `HIGH` / `LOW`
>
>
> B ) `LOW` / `HIGH`
>
> C ) `INPUT` / `OUTPUT`
>
> D ) `OUTPUT` / `INPUT`
>
## Problem 3 發出超音波
```arduino=22
long duration = pulseIn(Echo,HIGH);
return ___3___; //套公式
```
<aside>
:::success
Problem 3 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `duration * 0.0346`
>
>
> B ) `duration * 346 / 2`
>
> C ) `duration * 0.0346 / 2`
>
> D ) `duration * 346`
>
# Exercise 4 伺服馬達
---

## 程式碼
```arduino=
#include <Servo.h>
Servo servo;
int spin = 10;
int angle = 0;
void setup() {
___1___ //將Servo設定到腳位9
}
void loop() {
servo.write(angle); //把angle寫入servo中
angle += spin;
if(___2___){ //判斷角度是否超出旋轉範圍
spin *= -1; //如果超過範圍就往反方向旋轉
}
delay(500);
}
```
## Problem 1 設定伺服馬達的腳位
```arduino=7
void setup() {
___1___ //將Servo設定到腳位9
}
```
<aside>
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `servo.attach(9);`
>
>
> B ) `servo.write(9);`
>
> C ) `pinMode(9,OUTPUT);`
>
> D ) `pinMode(9,INPUT);`
>
## Problem 2 判斷旋轉角度的範圍
```arduino=14
if(___2___){ //判斷角度是否超出旋轉範圍
spin *= -1; //如果超過範圍就往反方向旋轉
}
```
<aside>
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
</aside>
> A ) `angle<=0`
>
>
> B ) `angle>=180`
>
> C ) `angle<=0 && angle>=180`
>
> D ) `angle<=0 || angle>=180`
>
# Exercise 5 無源蜂鳴器
---

## 程式碼
```arduino=
int TRIG = 9; // 超音波模組的Trig腳位
int ECHO = 10; // 超音波模組的Echo腳位
int BUZZER = 5; // 無源蜂鳴器腳位
double distance();
void setup() {
pinMode(TRIG, __1.1__); //將Trig腳位訂為輸出
pinMode(ECHO, __1.2__); //將Echo腳位訂為輸入
pinMode(BUZZER, __1.3__);
Serial.begin(9600); // 開啟序列埠監視器
}
void loop() {
double d = distance();
/*Debug用
Serial.print("Distance : ");
Serial.print(d);
Serial.println("cm");*/
if (d > 20) { // 大於 20cm,不發出聲音
noTone(BUZZER);
} else if (d > 10) { // 10-20 cm,1 秒 1000Hz,1 秒靜音
tone(BUZZER, __2.1__);
delay(1000);
__2.2__(BUZZER);
delay(1000);
} else { // 0-10 cm,0.5 秒 2000Hz,0.5 秒靜音
tone(BUZZER, __2.3__);
delay(500);
noTone(BUZZER);
delay(500);
}
}
double distance() {
digitalWrite(TRIG,HIGH);//產生高電位脈衝
delayMicroseconds(10); //持續 10 µs
digitalWrite(TRIG,LOW);
long duration = pulseIn(ECHO,HIGH);//時間∆t
return duration * 0.0346 / 2;//距離公式
}
```
## Problem 1 設定蜂鳴器和超音波腳位
```arduino=6
void setup() {
pinMode(TRIG,__1.1__); //將Trig腳位訂為輸出
pinMode(ECHO,__1.2__); //將Echo腳位訂為輸入
pinMode(BUZZER,__1.3__); // 把蜂鳴器設為輸出
Serial.begin(9600); // 開啟序列埠監視器
}
```
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
:::
```
__1.1__ / __1.2__ / ___1.3___
```
> A ) `INPUT` / `OUTPUT` / `INPUT`
>
>
> B ) `OUTPUT` / `INPUT` / `OUTPUT`
>
> C ) `INPUT` / `OUTPUT` / `OUTPUT`
>
> D ) `OUTPUT` / `INPUT` / `INPUT`
>
## Problem 2 讓蜂鳴器發出特定聲音
```arduino=13
void loop() {
double d = distance();
if (d > 20) { // 大於 20cm,不發出聲音
noTone(BUZZER);
} else if (d > 10) { // 10-20 cm,1 秒 1000Hz,1 秒靜音
tone(BUZZER, __2.1__);
delay(1000);
__2.2__(BUZZER);
delay(1000);
} else { // 0-10 cm,0.5 秒 2000Hz,0.5 秒靜音
tone(BUZZER, __2.3__);
delay(500);
noTone(BUZZER);
delay(500);
}
}
```
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
:::
```
__2.1__ / __2.2__ / __2.3__
```
> A ) `1000` / `tone` / `2000`
>
>
> B ) `2000` / `noTone` / `1000`
>
> C ) `1000` / `noTone` / `2000`
>
> D ) `2000` / `tone` / `500`
>
# Exercise 6 搖桿
---



## 程式碼
```arduino=
#include <Servo.h>
int x = A0; // 搖桿 X 軸(控制伺服)
int y = A1; // 搖桿 Y 軸(控制蜂鳴器)
int SERVO = 9; // 伺服馬達接腳
int BUZZER = 6; // 蜂鳴器接腳
Servo servoMotor;
void setup() {
pinMode(x, INPUT);
pinMode(y, INPUT);
pinMode(BUZZER, OUTPUT);
servoMotor.attach(SERVO); // 連接伺服馬達
//Serial.begin(9600);
}
void loop() {
// 讀取搖桿數值(0~1023)
int xValue = __1.1__; // 讀取搖桿x方向數值(0~1023)
int yValue = __1.2__; // 讀取搖桿y方向數值(0~1023)
/*Debug用
Serial.print("Xpos : ");
Serial.println(xValue);
Serial.print("Ypos : ");
Serial.println(yValue);*/
// X 軸控制伺服馬達(對應到 0° ~ 180°)
int servoAngle = __2.1__;
servoMotor.write(servoAngle);
// Y 軸控制蜂鳴器頻率(對應到 1000Hz ~ 1500Hz)
int buzzerFreq = __2.2__;
tone(BUZZER, buzzerFreq);
}
```
## Problem 1 讀取搖桿數值
```arduino=17
int xValue = __1.1__; // 讀取搖桿x方向數值(0~1023)
int yValue = __1.2__; // 讀取搖桿y方向數值(0~1023)
```
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
:::
```
__1.1__ / __1.2__
```
> A ) `analogRead(x)` / `analogRead(y)`
>
>
> B ) `analogread(x)` / `analogread(y)`
>
> C ) `digitalRead(x)` / `digitalRead(y)`
>
> D ) `digitalread(x)` / `digitalread(y)`
>
## Problem 2 搖桿數值轉換
```arduino=20
// X 軸控制伺服馬達(對應到 0° ~ 180°)
int servoAngle = __2.1__;
servoMotor.write(servoAngle);
// Y 軸控制蜂鳴器頻率(對應到 1000Hz ~ 1500Hz)
int buzzerFreq = __2.2__;
tone(BUZZER, buzzerFreq);
```
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
:::
```
__2.1__ / __2.2__
```
> A ) `map(xValue, 0, 180, 0, 1023)` / `map(yValue, 1000, 1500, 0, 1023)`
>
>
> B ) `Map(xValue, 0, 180, 0, 1023)` / `Map(yValue, 1000, 1500, 0, 1023)`
>
> C ) `map(xValue, 0, 1023, 0, 180)` / `map(yValue, 0, 1023, 1000, 1500)`
>
> D ) `Map(xValue, 0, 1023, 0, 180)` / `Map(yValue, 0, 1023, 1000, 1500)`
>
---
# Lab1 平交道
---

## 程式碼
---
```arduino=
#include <Servo.h> // 引入伺服馬達函式庫
int trigPin = 9; // TRIG 腳位:超音波模組
int echoPin = 10; // ECHO 腳位:超音波模組
int servoPin = 6; // 伺服馬達腳位
int redLed = 3; // 紅色 LED
int greenLed = 4; // 綠色 LED
int buzzer = 5; // 蜂鳴器腳位
int button = 7; // 按鈕腳位
Servo servo; // 宣告 Servo 物件控制馬達
void setup() {
Serial.__1__(9600); // 設定序列通訊鮑率為 9600
pinMode(trigPin, OUTPUT); // TRIG 設為輸出
pinMode(echoPin, INPUT); // ECHO 設為輸入
pinMode(redLed, OUTPUT); // 紅色 LED 設為輸出
pinMode(greenLed, OUTPUT); // 綠色 LED 設為輸出
pinMode(buzzer, OUTPUT); // 蜂鳴器設為輸出
pinMode(button, __2__); // 按鈕腳位設為輸入,使用內部上拉電阻
servo.__3__(servoPin); // 將伺服馬達接到指定腳位
servo.write(0); // 初始設為 0 度(柵欄打開)
}
void loop() {
long duration; // 儲存超音波回波時間
float distance; // 計算距離(公分)
int buttonState;
buttonState = digitalRead(button); // 讀取按鈕狀態
/*debug用
Serial.print("距離為: ");
Serial.println(distance);
Serial.print(" 按鈕狀態: ");
Serial.println(buttonState);
*/
if (__4__) { // 如果按鈕被按下
servo.write(0); // 馬達轉到開啟角度
digitalWrite(redLed, HIGH); // 紅燈亮
digitalWrite(greenLed, HIGH);// 綠燈亮
__5.1__(buzzer, 500); // 蜂鳴器發出聲音(150Hz)
Serial.println("狀態:緊急按鈕按下,強制停止");
}
else {
digitalWrite(trigPin, __6.1__); // 送出超音波
delayMicroseconds(10); // 等 10 微秒
digitalWrite(trigPin, __6.2__); // 停止送出超音波
duration = pulseIn(echoPin, HIGH); // 偵測回音時間
distance = __7__ * 0.034 / 2; // 計算距離(cm)
Serial.print("測得距離: ");
Serial.print(distance);
Serial.println(" cm");
__5.2__(buzzer); // 停止蜂鳴器
if (distance > 20) {
delay(500);
servo.write(0); // 開啟柵欄
digitalWrite(redLed, LOW);
digitalWrite(greenLed, LOW);
digitalWrite(buzzer, LOW);
Serial.println("狀態:安全,柵欄開啟");
}
else if (__8__) { // 如果距離在 10~20cm
servo.write(90); // 關閉柵欄
digitalWrite(__9.1__, HIGH); // 紅燈亮
digitalWrite(__9.2__, LOW); // 綠燈關
tone(buzzer,100); // 蜂鳴器響
Serial.println("狀態:危險靠近,警示燈閃爍");
delay(500);
digitalWrite(__9.3__, LOW); // 紅燈關
digitalWrite(__9.4__, HIGH); // 綠燈亮
noTone(buzzer); // 蜂鳴器停
delay(500);
}
else {
servo.write(90); // 非常危險,完全關閉
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
tone(buzzer,125);
Serial.println("狀態:非常危險,快速警示");
__10__; // 快速閃爍,每0.1秒閃爍一次
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
noTone(buzzer);
__10__; // 快速閃爍,每0.1秒閃爍一次
}
}
}
```
## Problem 1 設定序列通訊鮑率
```arduino=13
void setup() {
Serial.__1__(9600); // 設定序列通訊鮑率為 9600
pinMode(trigPin, OUTPUT); // TRIG 設為輸出
pinMode(echoPin, INPUT); // ECHO 設為輸入
pinMode(redLed, OUTPUT); // 紅色 LED 設為輸出
```
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
:::
> A ) `start`
>
>
> B ) `begin`
>
> C ) `end`
>
> D ) `print`
>
## Problem 2 設定上拉電阻
```arduino=19
pinMode(buzzer, OUTPUT); // 蜂鳴器設為輸出
pinMode(button, __2__); // 按鈕腳位設為輸入,使用內部上拉電阻
```
:::success
Problem 2 :
選項 >> 只有一個是對的喔!
:::
> A ) `INPUT`
>
>
> B ) `OUTPUT`
>
> C ) `INPUT_PULLUP`
>
> D ) `OUTPUT_PULLUP`
>
## Problem 3 連接伺服馬達
```arduino=21
servo.__3__(servoPin); // 將伺服馬達接到指定腳位
servo.write(0); // 初始設為 0 度(柵欄打開)
```
:::success
Problem 3 :
選項 >> 只有一個是對的喔!
:::
> A ) `Write`
>
>
> B ) `Attach`
>
> C ) `write`
>
> D ) `attach`
>
## Problem 4 緊急按鈕觸發條件
```arduino=31
if(__4__){ // 如果按鈕被按下
servo.write(0); // 馬達轉到開啟角度
digitalWrite(redLed, HIGH); // 紅燈亮
digitalWrite(greenLed, HIGH); // 綠燈亮
```
:::success
Problem 4 :
選項 >> 只有一個是對的喔!
:::
> A ) `buttonSTATE == LOW`
>
>
> B ) `buttonState == LOW`
>
> C ) `ButtonState == HIGH`
>
> D ) `buttonState == 1`
>
## Problem 5 蜂鳴器發聲
```arduino=34
digitalWrite(greenLed, HIGH);// 綠燈亮
__5.1__(buzzer, 500); // 蜂鳴器發出聲音(500Hz)
Serial.println("狀態:緊急按鈕按下,強制停止");
}
```
```arduino=46
Serial.print("測得距離: ");
Serial.print(distance);
Serial.println(" cm");
__5.2__(buzzer); // 蜂鳴器關閉
```
:::success
Problem 5 :
選項 >> 只有一個是對的喔!
:::
```
__5.1__ / __5.2__
```
> A ) `tone` / `notone`
>
>
> B ) `TONE` / `noTone`
>
> C ) `tone` / `noTone`
>
> D ) `TONE` / `noTone`
>
## Problem 6 發出超音波
```arduino=39
digitalWrite(trigPin, __6.1__); // 送出超音波
delayMicroseconds(10); // 等 10 微秒
digitalWrite(trigPin, __6.2__); // 停止送出超音波
```
:::success
Problem 6 :
選項 >> 只有一個是對的喔!
:::
```
__6.1__ / __6.2__
```
> A ) `High` / `Low`
>
>
> B ) `Low` / `High`
>
> C ) `LOW` / `HIGH`
>
> D ) `HIGH` / `LOW`
>
## Problem 7 距離公式
```arduino=43
duration = pulseIn(echoPin, HIGH); // 偵測回音時間
distance = __7__ * 0.034 / 2; // 計算距離(cm)
```
:::success
Problem 7 :
選項 >> 只有一個是對的喔!
:::
> A ) `duration`
>
>
> B ) `DuRaTiOn`
>
> C ) `dUrAtIoN`
>
> D ) `DURATION`
>
## Problem 8 中距離狀態條件
```arduino=53
digitalWrite(greenLed, LOW);
digitalWrite(buzzer, LOW);
Serial.println("狀態:安全,柵欄開啟");
}
else if (__8__) { // 如果距離在 10~20cm
servo.write(90); // 關閉柵欄
```
:::success
Problem 8 :
選項 >> 只有一個是對的喔!
:::
> A ) `distance <= 10`
>
>
> B ) `distance < 10`
>
> C ) `distance > 10`
>
> D ) `distance > 100`
>
## Problem 9 LED閃爍
```arduino=58
servo.write(90); // 關閉柵欄
digitalWrite(__9.1__, HIGH); // 紅燈亮
digitalWrite(__9.2__, LOW); // 綠燈關
tone(buzzer, 100); // 蜂鳴器響
Serial.println("狀態:危險靠近,警示燈閃爍");
delay(500);
digitalWrite(__9.3__, LOW); // 紅燈關
digitalWrite(__9.4__, HIGH); // 綠燈亮
noTone(buzzer); // 蜂鳴器停
delay(500);
```
:::success
Problem 9 :
選項 >> 只有一個是對的喔!
:::
```
__9.1__ / __9.2__ / __9.3__ / __9.4__
```
> A ) `redLed` / `redLed` / `greenLed` / `greenLed`
>
>
> B ) `redLed` / `greenLed` / `redLed` / `greenLed`
>
> C ) `greenLed` / `greenLed` / `redLed` / `redLed`
>
> D ) `redLed` / `greenLed` / `greenLed`/ `redLed`
>
## Problem 10 LED閃爍時間控制
```arduino=70
else {
servo.write(90); // 非常危險,完全關閉
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
tone(buzzer,125);
Serial.println("狀態:非常危險,快速警示");
__10__; // 快速閃爍,每0.1秒閃爍一次
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
noTone(buzzer);
__10__; // 快速閃爍,每0.1秒閃爍一次
}
```
---
:::success
Problem 10 :
選項 >> 只有一個是對的喔!
:::
> A ) `delay(100)`
>
>
> B ) `delay(0.1)`
>
> C ) `Delay(100)`
>
> D ) `Delay(0.1)`
>
# Lab2 打地鼠



## 程式碼
```arduino=
// 定義四個 LED 的腳位
int UpLed = 2; // 上方LED腳位
int RightLed = 3; // 右方LED腳位
int DownLed = 4; // 下方LED腳位
int LeftLed = 5; // 左方LED腳位
// 定義搖桿的類比輸入腳位
int joyX = A0; // 搖桿 X 軸
int joyY = A1; // 搖桿 Y 軸
int joySw = 7; // 搖桿按鈕
// 蜂鳴器腳位
int buzzer = 6;
// LED 腳位陣列
int ledPins[] = {UpLed, RightLed, LeftLed, DownLed};
int activeLED = -1; // 記錄當前點亮的 LED
int lastLED = -1; // 記錄上一顆點亮的 LED
int validCount = 0; // 記錄正確關閉 LED 次數
int penaltyCount = 0; // 記錄錯誤扣分
int r = 2; // 得分倍率
bool gameStarted = false; // 遊戲是否開始
unsigned long startTime = 0; // 記錄遊戲開始時間
int gameDuration = 15000; // 遊戲時間 15 秒
unsigned long lastButtonPress = 0; // 記錄上次按下按鈕的時間
unsigned long debounceDelay = 200; // Debounce 延遲 200 毫秒
unsigned long lastLedActionTime = 0; // 記錄上次關閉 LED 的時間
unsigned long ledCooldown = 200; // LED 冷卻時間 200 毫秒,避免過快連續操作
//函數宣告
void playStartCountdown();
void lightRandomLED();
void playEndTone();
void turnOffAllLEDs();
void checkJoystick();
void setup() {
__1__(9600); // 設定序列埠,用於輸出訊息
// 設定 LED 腳位為輸出
pinMode(UpLed, OUTPUT);
pinMode(LeftLed, OUTPUT);
pinMode(RightLed, OUTPUT);
pinMode(DownLed, OUTPUT);
pinMode(joySw, __2__ ); // 設定搖桿按鈕為輸入
pinMode(buzzer, OUTPUT); // 設定蜂鳴器腳位為輸出
Serial.println("按下 Joystick 中間鍵開始遊戲");
}
void loop() {
if (!gameStarted) { // 如果遊戲尚未開始
// 等待玩家按下搖桿按鈕啟動遊戲
if ( ( __3__ ) && ( __4__ ) ) { //當(按鈕按下時)且(Debounce)
delay(1000);
lastButtonPress = millis(); // 記錄按下時間
gameStarted = true; // 設定遊戲開始
validCount = 0;
penaltyCount = 0;
startTime = millis(); // 記錄遊戲開始時間
playStartCountdown();
Serial.println("遊戲開始!15 秒內關掉最多 LED");
lightRandomLED(); // 隨機點亮一顆 LED
}
}
else {
// 檢查遊戲是否已達時間限制
if ( __5__ ) {
Serial.print("遊戲結束!你關掉了 ");
Serial.print(validCount);
Serial.print(" 顆 LED,錯誤扣分: ");
Serial.println(penaltyCount);
Serial.print("<總得分>:");
Serial.println(validCount * r + penaltyCount); // 計算總得分
playEndTone();
gameStarted = false; // 遊戲結束
turnOffAllLEDs(); // 關閉所有 LED
Serial.println("按下 Joystick 中間鍵重新開始");
}
else {
checkJoystick(); // 檢查搖桿輸入
}
}
}
void checkJoystick() {
int xVal = analogRead(joyX); // 讀取搖桿 X 軸數值
int yVal = analogRead(joyY); // 讀取搖桿 Y 軸數值
/*debug用
Serial.print("Xpos : ");
Serial.println(xVal);
Serial.print("Ypos : ");
Serial.println(yVal);*/
// 確保 LED 點亮,且符合冷卻時間
if ( __6__ ) {
bool correctMove = false; // 是否為正確的移動
bool moved = false; // 是否有移動搖桿
// 判斷是否有移動搖桿
if ( __7.1__ || __7.2__ || __7.3__ || __7.4__ ) {
moved = true;
}
// 檢查移動方向是否與 LED 位置匹配
if( __8__ ) {
/*
如果點亮的是 UpLed,則應該向上推
如果點亮的是 RightLed,則應該向右推
如果點亮的是 LeftLed,則應該向左推
如果點亮的是 DownLed,則應該向下推
*/
correctMove = true;
}
if (moved) { // 如果有移動搖桿
if (correctMove) { // 如果移動方向正確
turnOffAllLEDs(); // 關閉所有 LED
delay(100);
validCount++; // 增加正確關閉計數
Serial.print("LED 關閉數量: ");
Serial.println(validCount);
lightRandomLED(); // 再次隨機點亮 LED
}
else { // 如果移動方向錯誤
penaltyCount -= 5; // 錯誤扣 5 分
Serial.print("錯誤操作!目前扣分: ");
Serial.println(penaltyCount);
}
lastLedActionTime = millis(); // 記錄這次操作的時間
}
}
}
// 隨機點亮一顆 LED
void lightRandomLED() {
activeLED = random(0, 4); // 產生 0~3 之間的隨機數,選擇要點亮的 LED
digitalWrite( __9.1__, __9.2__ );
}
// 關閉所有 LED
void turnOffAllLEDs() {
for (int i = 0; i < 4; i++) {
__10__ ;
}
}
// 🎵 遊戲開始音效
void playStartCountdown() {
for (int i = 3; i > 0; i--) {
__11.1__
__11.2__ // 發出 1000 Hz 音調 300ms
noTone(buzzer);
delay(1000); // 等待 1 秒
}
__11.3__
__11.4__ // 發出 1500 Hz 音調 500ms
noTone(buzzer);
delay(500);
}
// 🎵 遊戲結束音效
void playEndTone() {
tone(buzzer, 500);
delay(300);
noTone(buzzer);
delay(400);
tone(buzzer, 300);
delay(500);
noTone(buzzer);
}
```
### Problem 1 設定序列埠,用於輸出訊息
```arduino=34
void setup() {
__1__(9600); // 設定序列埠,用於輸出訊息
}
```
:::success
Problem 1 :
選項 >> 只有一個是對的喔!
:::
> A ) `Serial.write`
>
>
> B ) `Serial.print`
>
> C ) `Serial.begin`
>
> D ) `Serial.end`
>
---
### Problem 2 設定搖桿按鈕為輸入
```arduino=41
pinMode(joySw, __2__ ); // 請根據你拿到的搖桿選擇正確答案。
```
### Hint :
**黑色搖桿需要**給予上拉電阻(否則電位會浮動)。
**紅色搖桿不需**給予上拉電阻,只須設定該腳位為輸入。
:::success
Problem 2 :
請根據你拿到的搖桿選擇正確答案。
:::
**黑色搖桿:**`INPUT_PULLUP`
**紅色搖桿:**`INPUT`
### Problem 3 當按鈕按下時
```arduino=49
if ( ( __3__ ) && ( __4__ ) ) { //當(按鈕按下時)且(Debounce)
//code
}
```
### Hint :
**黑色搖桿**有被給予上拉電阻,因此當按鈕按下時,使用digitalRead函式會讀取到低電位。
**紅色搖桿**預設連接到GND,因此當按鈕按下時,使用digitalRead函式會讀取到高電位。
:::success
Problem 3 :
選項 >> 請根據你拿到的搖桿選擇正確答案。
:::
**黑色搖桿:**`digitalRead(joySw) == LOW`
**紅色搖桿:**`digitalRead(joySw) == HIGH`
---
### Problem 4 Debounce
```arduino=49
if ( ( __3__ ) && ( __4__ ) ) { //當(按鈕按下時)且(Debounce)
//code
}
```
:::success
Problem 4 :
選項 >> 只有一個是對的喔!
:::
> A ) `millis() - lastButtonPress < debounceDelay`
>
>
> B ) `millis() - lastButtonPress > debounceDelay`
>
> C ) `lastButtonPress < debounceDelay`
>
> D ) `lastButtonPress > debounceDelay`
>
### Problem 5 檢查遊戲是否已達時間限制
```arduino=62
// 檢查遊戲是否已達時間限制
if ( __5__ ) {
//code
}
```
:::success
Problem 5 :
選項 >> 只有一個是對的喔!
:::
>
> A ) `startTime <= gameDuration`
>
> B ) `startTime > gameDuration`
>
> C ) `millis() - startTime < gameDuration`
>
> D ) `millis() - startTime >= gameDuration`
>
---
### Problem 6 確保 LED 點亮,且符合冷卻時間
```arduino=91
// 確保 LED 點亮,且符合冷卻時間
if ( __6__ ) {
//code
}
```
:::success
Problem 6 :
選項 >> 只有一個是對的喔!
:::
> A ) `activeLED == -1 && (millis() - lastLedActionTime) > ledCooldown`
>
>
> B ) `activeLED != -1 && (millis() - lastLedActionTime) > ledCooldown`
>
> C ) `activeLED == -1 && lastLedActionTime > ledCooldown`
>
> D ) `activeLED != -1 && lastLedActionTime > ledCooldown`
>
### Problem 7 判斷是否有移動搖桿
```arduino=96
// 判斷是否有移動搖桿
if ( __7.1__ || __7.2__ || __7.3__ || __7.4__ ) {
moved = true;
}
```
:::success
Problem 7 :
選項 >> 只有一個是對的喔!
:::
```
__7.1__ || __7.2__ || __7.3__ || __7.4__
```
> A ) `yVal < 200 || yVal > 800 || xVal < 200 || xVal > 800`
>
>
> B ) `yVal < 200 || yVal < 800 || xVal > 200 || xVal > 800`
>
> C ) `yVal > 200 || yVal < 800 || xVal > 200 || xVal < 800`
>
> D ) `yVal > 200 || yVal > 800 || xVal < 200 || xVal < 800`
>
---
### Problem 8 檢查移動方向是否與 LED 位置匹配
```arduino=101
// 檢查移動方向是否與 LED 位置匹配
if( __8__ )
/*
如果點亮的是 UpLed,則應該向上推
如果點亮的是 RightLed,則應該向右推
如果點亮的是 LeftLed,則應該向左推
如果點亮的是 DownLed,則應該向下推
*/
correctMove = true;
}
```
### Hint :

**黑色搖桿:**
1. 往上推:`xVal > 800`
2. 往右推:`yVal > 800`
3. 往左推:`yVal < 200`
4. 往下推:`xVal < 200`
**紅色搖桿:**
1. 往上推:`yVal < 200`
2. 往右推:`xVal > 800`
3. 往左推:`xVal < 200`
4. 往下推:`yVal > 800`
:::success
Problem 8 :
選項 >> 請根據你拿到的搖桿選擇正確答案。
:::
**黑色搖桿:** `( activeLED == 0 && xVal > 800 ) || ( activeLED == 1 && yVal > 800 ) || ( activeLED == 2 && yVal < 200 ) || ( activeLED == 3 && xVal < 200 )`
**紅色搖桿:** `( activeLED == 0 && yVal < 200 ) || ( activeLED == 1 && xVal > 800 ) || ( activeLED == 2 && xVal < 200 ) || ( activeLED == 3 && yVal > 800 )`
### Problem 9 隨機點亮一顆 LED
```arduino=129
// 隨機點亮一顆 LED
void lightRandomLED() {
activeLED = random(0, 4); // 產生 0~3 的隨機數
digitalWrite( __9.1__, __9.2__ );
}
```
:::success
Problem 9 :
選項 >> 只有一個是對的喔!
:::
```
__9.1__ / __9.2__
```
> A ) `ledPins[activeLED] / HIGH`
>
>
> B ) `ledPins[activeLED] / LOW`
>
> C ) `ledPins[millis()] / HIGH`
>
> D ) `ledPins[gameDuration] / LOW`
>
---
### Problem 10 關閉所有 LED
```arduino=135
// 關閉所有 LED
void turnOffAllLEDs() {
for (int i = 0; i < 4; i++) {
__10__;
}
```
:::success
Problem 10 :
選項 >> 只有一個是對的喔!
:::
> A ) `digitalWrite(ledPins[j], LOW)`
>
>
> B ) `digitalWrite(ledPins[j], HIGH)`
>
> C ) `digitalWrite(ledPins[i], LOW)`
>
> D ) `digitalWrite(ledPins[i], HIGH)`
>
### Problem 11 發出 1000 Hz 音調 300ms / 發出 1500 Hz 音調 500ms
```arduino=142
// 🎵 遊戲開始音效
void playStartCountdown() {
for (int i = 3; i > 0; i--) {
__11.1__
__11.2__ // 發出 1000 Hz 音調 300ms
noTone(buzzer);
delay(1000); // 等待 1 秒
}
__11.3__
__11.4__ // 發出 1500 Hz 音調 500ms
noTone(buzzer);
delay(500);
}
```
:::success
Problem 11 :
選項 >> 只有一個是對的喔!
:::
```
__11.1__ / __11.2__ / __11.3__ / __11.4__
```
> A ) `delay(300); / tone(buzzer, 1000); / tone(buzzer, 1500); / delay(500);`
>
>
> B ) `delay(300); / tone(buzzer, 1000); / delay(500); / tone(buzzer, 1500);`
>
> C ) `tone(buzzer, 1000); / delay(300); / tone(buzzer, 1500); / delay(500);`
>
> D ) `tone(buzzer, 1000); / delay(300); / delay(500); / tone(buzzer, 1500);`
>