📝 程式碼詳細解說
讓我們一步步了解這個倒數計時器是怎麼運作的!
📚 第一部分:引入函式庫
TM1637是控制四位數碼管的特殊晶片,我們需要它的專用函式庫
#include <TM1637Display.h>
💡 什麼是函式庫?
就像玩具的「說明書」,裡面有很多已經寫好的指令,讓我們可以輕鬆控制數碼管,不用自己從頭寫複雜的程式。
如何安裝?
在Arduino IDE中,點選「草稿碼」→「匯入程式庫」→「管理程式庫」,搜尋「TM1637」並安裝。
🎯 第二部分:腳位定義
告訴Arduino每個元件接在哪個接腳上
const int buttonPin = 2;
const int redPin = 3;
const int bluePin = 4;
const int greenPin = 5;
const int DIO = 6;
const int CLK = 7;
🎨 第三部分:建立數碼管物件
創建一個「數碼管控制器」,就像遙控器一樣可以控制顯示器
TM1637Display display(CLK, DIO);
💡 什麼是「物件」?
想像你有一個萬能遙控器(display),它可以控制電視顯示什麼畫面。這裡的 display 就是用來控制數碼管要顯示什麼數字的「遙控器」。
📊 第四部分:建立變數(記憶盒子)
程式需要記住一些資訊:按鈕狀態、是否正在倒數、現在數到幾
int lastButtonState = HIGH;
bool counting = false;
int counter = 9;
⚙️ 第五部分:setup 開機設定
Arduino一開機時的初始設定
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
display.setBrightness(7);
display.showNumberDec(0);
allOff();
Serial.begin(9600);
Serial.println("Ready! 按下按鈕開始倒數~");
}
🔄 第六部分:loop 主要工作迴圈
Arduino會不停重複執行這段程式,檢查按鈕有沒有被按下
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastButtonState == HIGH) {
if (!counting) {
counting = true;
counter = 9;
Serial.println("開始倒數!");
startCountdown();
}
}
lastButtonState = buttonState;
}
⏱️ 第七部分:倒數函式(最重要!)
這是倒數計時的核心程式,控制數字顯示和燈光變化
void startCountdown() {
for (int i = counter; i >= 0; i--) {
display.showNumberDec(i, false);
if (i > 6) {
setColor(1, 0, 0);
} else if (i > 3) {
setColor(0, 1, 0);
} else if (i >= 0) {
setColor(0, 0, 1);
}
delay(1000);
}
allOff();
display.showNumberDec(0);
Serial.println("倒數結束!");
counting = false;
}
💡 第八部分:控制燈光的函式
這兩個函式負責控制RGB燈的開關
void setColor(int r, int b, int g) {
digitalWrite(redPin, r);
digitalWrite(bluePin, b);
digitalWrite(greenPin, g);
}
void allOff() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
🧠 程式運作原理(用故事來理解)
想像你在玩倒數遊戲:
- 🎮 按鈕是開關:按一下就開始倒數
- 🔢 數碼管是計分板:顯示現在倒數到幾
- 🚦 RGB燈是交通號誌:
- 紅燈(9~7):像紅燈停止,還有很多時間
- 藍燈(6~4):中間階段,準備加速
- 綠燈(3~0):綠燈通行,時間快到了!
- ⏱️ delay(1000):每秒換一個數字,就像時鐘的秒針
- 🔁 for迴圈:自動幫我們從9數到0,不用寫9次程式碼
為什麼要用函式(function)?
就像把常用的動作取個名字。例如「關燈」這個動作需要關紅、藍、綠三個燈,我們把它包成 allOff() 函式,之後只要呼叫 allOff() 就能一次關掉所有燈,很方便!
📋 完整程式碼
點擊展開完整程式碼
#include <TM1637Display.h>
const int buttonPin = 2;
const int redPin = 3;
const int bluePin = 4;
const int greenPin = 5;
const int DIO = 6;
const int CLK = 7;
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);
display.setBrightness(7);
display.showNumberDec(0);
allOff();
Serial.begin(9600);
Serial.println("Ready! 按下按鈕開始倒數~");
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == LOW && lastButtonState == HIGH) {
if (!counting) {
counting = true;
counter = 9;
Serial.println("開始倒數!");
startCountdown();
}
}
lastButtonState = buttonState;
}
void startCountdown() {
for (int i = counter; i >= 0; i--) {
display.showNumberDec(i, false);
if (i > 6) {
setColor(1, 0, 0);
} else if (i > 3) {
setColor(0, 1, 0);
} else if (i >= 0) {
setColor(0, 0, 1);
}
delay(1000);
}
allOff();
display.showNumberDec(0);
Serial.println("倒數結束!");
counting = false;
}
void setColor(int r, int b, int g) {
digitalWrite(redPin, r);
digitalWrite(bluePin, b);
digitalWrite(greenPin, g);
}
void allOff() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}