📝 程式碼詳細解說
讓我們一步步了解這個完整的整合專案!
📚 第一部分:引入函式庫
繼續使用TM1637數碼管函式庫
#include <TM1637Display.h>
🎯 第二部分:腳位定義
這是最完整的專案!我們用到了所有學過的元件
const int buttonPin = 2;
const int redPin = 3;
const int greenPin = 4;
const int bluePin = 5;
const int DIO = 6;
const int CLK = 7;
const int motorPin = 9;
const int buzzerPin = 11;
🎨 第三部分:建立物件和變數
建立數碼管控制器和狀態變數
TM1637Display display(CLK, DIO);
int lastButtonState = HIGH;
bool counting = false;
int counter = 9;
⚙️ 第四部分:setup 開機設定
設定所有接腳,這次多了震動馬達!
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(motorPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
display.setBrightness(7);
display.showNumberDec(0);
allOff();
Serial.begin(9600);
Serial.println("系統準備好了~ 按下按鈕開始倒數!");
}
🔄 第五部分:loop 主要迴圈
按下按鈕時,蜂鳴器和震動馬達會同時運作1秒!
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastButtonState == HIGH) {
if (!counting) {
counting = true;
counter = 9;
tone(buzzerPin, 1000);
digitalWrite(motorPin, HIGH);
delay(1000);
noTone(buzzerPin);
digitalWrite(motorPin, LOW);
Serial.println("開始倒數!");
startCountdown();
}
}
lastButtonState = buttonState;
}
🔄 什麼是震動馬達?
⚡ 震動馬達的原理
震動馬達就是一個小型馬達,軸上裝了一個偏心的重物。當馬達轉動時,這個偏心重物會造成不平衡,產生震動效果!
💡 手機的震動就是這樣來的!
digitalWrite(motorPin, HIGH) - 打開馬達,開始震動
digitalWrite(motorPin, LOW) - 關閉馬達,停止震動
- 也可以用
analogWrite(motorPin, 速度) 控制震動強度(0~255)
🎮 應用場景:
- 遊戲手把的震動回饋
- 手機來電震動
- 提醒裝置(例如手環)
- 觸覺反饋系統
⏱️ 第六部分:倒數函式
執行倒數,控制數碼管和燈光
void startCountdown() {
for (int i = counter; i >= 0; i--) {
display.showNumberDec(i, false);
if (i > 6) {
setColor(0, 0, 1);
} else if (i > 3) {
setColor(1, 0, 0);
} else {
setColor(0, 1, 0);
}
delay(1000);
}
allOff();
display.showNumberDec(0);
Serial.println("倒數結束!");
counting = false;
}
💡 第七部分:輔助函式
控制RGB燈光的函式
void setColor(int r, int g, int b) {
digitalWrite(redPin, r);
digitalWrite(greenPin, g);
digitalWrite(bluePin, b);
}
void allOff() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
🧠 完整系統運作流程
想像你在體驗一個完整的計時系統:
- 🎮 按下按鈕:系統啟動!
- 🔔🔄 蜂鳴器+震動馬達:雙重提示音,告訴你「我準備好了!」(1秒)
- 🔢 數碼管倒數:從9倒數到0,每秒顯示一個數字
- 🚦 燈光變化:
- 藍燈(9~7):冷靜的開始
- 紅燈(6~4):注意!時間過半
- 綠燈(3~0):最後衝刺
- 🏁 倒數結束:所有東西關閉,系統回到待命狀態
💡 為什麼要同時用蜂鳴器和震動馬達?
這叫做「多感官反饋」!聲音+震動可以讓使用者更清楚地感受到系統的狀態變化,就像手機來訊息時會震動+響鈴一樣!
🎯 這個專案整合了你學過的所有技能:
- ✅ 按鈕輸入控制
- ✅ RGB LED 燈光效果
- ✅ TM1637 數碼管顯示
- ✅ tone() 蜂鳴器音效
- ✅ digitalWrite() 馬達控制
- ✅ 狀態機邏輯設計
- ✅ 多元件協同運作
📋 完整程式碼
點擊展開完整程式碼
#include <TM1637Display.h>
const int buttonPin = 2;
const int redPin = 3;
const int greenPin = 4;
const int bluePin = 5;
const int DIO = 6;
const int CLK = 7;
const int motorPin = 9;
const int buzzerPin = 11;
TM1637Display display(CLK, DIO);
int lastButtonState = HIGH;
bool counting = false;
int counter = 9;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(motorPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
display.setBrightness(7);
display.showNumberDec(0);
allOff();
Serial.begin(9600);
Serial.println("系統準備好了~ 按下按鈕開始倒數!");
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastButtonState == HIGH) {
if (!counting) {
counting = true;
counter = 9;
tone(buzzerPin, 1000);
digitalWrite(motorPin, HIGH);
delay(1000);
noTone(buzzerPin);
digitalWrite(motorPin, LOW);
Serial.println("開始倒數!");
startCountdown();
}
}
lastButtonState = buttonState;
}
void startCountdown() {
for (int i = counter; i >= 0; i--) {
display.showNumberDec(i, false);
if (i > 6) {
setColor(0, 0, 1);
} else if (i > 3) {
setColor(1, 0, 0);
} else {
setColor(0, 1, 0);
}
delay(1000);
}
allOff();
display.showNumberDec(0);
Serial.println("倒數結束!");
counting = false;
}
void setColor(int r, int g, int b) {
digitalWrite(redPin, r);
digitalWrite(greenPin, g);
digitalWrite(bluePin, b);
}
void allOff() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}