⏰ 數碼管倒數計時器

學會控制七段顯示器,製作一個真實的倒數計時器!

🔌 本功課所需杜邦線

含數碼管模組與麵包板接線,請依下表準備(直接對照右側「收納位置」欄到收納盒取線即可)。上方為數量表,下方為接線圖

顏色長度規格數量收納位置
20 cm公母1C2
20 cm公母1C2
10 cm公公1C1
20 cm公母1C2
20 cm公母1C2
功課二倒數計時器:電路接線圖

圖:功課二(倒數計時器/數碼管)接線圖

🎯 挑戰任務

製作一個按鈕控制的倒數計時器,結合數碼管和RGB燈光效果:

按下按鈕 → 從9開始倒數 → 9,8,7...配合燈光變化 → 0 → 全部熄滅

🤖

與ChatGPT協作

你可以試著問ChatGPT這些問題來獲得幫助和完整程式碼:

我想用Arduino製作一個倒數計時器,使用TM1637四位數碼管顯示數字, 並搭配RGB燈光效果。 功能需求: 1. 按下按鈕開始從9倒數到0 2. 倒數時顯示器顯示數字 3. 根據倒數數字顯示不同顏色燈光: - 9~7:紅燈 - 6~4:藍燈 - 3~0:綠燈 4. 倒數結束後全部關閉 硬體接線: - 按鈕接在接腳2 - 紅色LED接在接腳3 - 藍色LED接在接腳4 - 綠色LED接在接腳5 - TM1637的DIO接在接腳6 - TM1637的CLK接在接腳7 請幫我寫Arduino程式碼,並且加上詳細的註解說明。

💡 提問技巧

  • 說明你使用的硬體模組(TM1637數碼管)
  • 告訴ChatGPT需要安裝什麼函式庫
  • 描述清楚燈光變化的規則
  • 如果不懂某個函式,可以請ChatGPT詳細解釋

📝 程式碼詳細解說

讓我們一步步了解這個倒數計時器是怎麼運作的!

📚 第一部分:引入函式庫

TM1637是控制四位數碼管的特殊晶片,我們需要它的專用函式庫

#include <TM1637Display.h> // 引入TM1637數碼管控制函式庫

💡 什麼是函式庫?
就像玩具的「說明書」,裡面有很多已經寫好的指令,讓我們可以輕鬆控制數碼管,不用自己從頭寫複雜的程式。

如何安裝?
在Arduino IDE中,點選「草稿碼」→「匯入程式庫」→「管理程式庫」,搜尋「TM1637」並安裝。

🎯 第二部分:腳位定義

告訴Arduino每個元件接在哪個接腳上

// --- 腳位定義 --- const int buttonPin = 2; // 按鈕接在2號接腳 const int redPin = 3; // 紅燈接在3號接腳 const int bluePin = 4; // 藍燈接在4號接腳 const int greenPin = 5; // 綠燈接在5號接腳 const int DIO = 6; // 數碼管的資料線(DIO)接在6號接腳 const int CLK = 7; // 數碼管的時鐘線(CLK)接在7號接腳

🎨 第三部分:建立數碼管物件

創建一個「數碼管控制器」,就像遙控器一樣可以控制顯示器

// --- 物件建立 --- TM1637Display display(CLK, DIO); // 建立數碼管控制物件

💡 什麼是「物件」?
想像你有一個萬能遙控器(display),它可以控制電視顯示什麼畫面。這裡的 display 就是用來控制數碼管要顯示什麼數字的「遙控器」。

📊 第四部分:建立變數(記憶盒子)

程式需要記住一些資訊:按鈕狀態、是否正在倒數、現在數到幾

// --- 變數 --- int lastButtonState = HIGH; // 記住上一次按鈕的狀態 bool counting = false; // 是否正在倒數中(true=是,false=否) int counter = 9; // 倒數計數器,從9開始

⚙️ 第五部分:setup 開機設定

Arduino一開機時的初始設定

void setup() { // 設定接腳模式 pinMode(buttonPin, INPUT_PULLUP); // 按鈕接腳設為輸入,使用內建上拉電阻 pinMode(redPin, OUTPUT); // 紅燈接腳設為輸出 pinMode(greenPin, OUTPUT); // 綠燈接腳設為輸出 pinMode(bluePin, OUTPUT); // 藍燈接腳設為輸出 display.setBrightness(7); // 設定數碼管亮度,0最暗,7最亮 // 初始化:一開始顯示0,所有燈都關閉 display.showNumberDec(0); // 在數碼管上顯示數字0 allOff(); // 呼叫allOff函式,把所有燈關掉 // 開啟序列監視器,可以在電腦上看到訊息 Serial.begin(9600); Serial.println("Ready! 按下按鈕開始倒數~"); }

🔄 第六部分:loop 主要工作迴圈

Arduino會不停重複執行這段程式,檢查按鈕有沒有被按下

void loop() { int buttonState = digitalRead(buttonPin); // 讀取按鈕現在的狀態 // 偵測按鈕按下(由HIGH變LOW) if (buttonState == LOW && lastButtonState == HIGH) { if (!counting) { // 如果沒有在倒數中 counting = true; // 開始倒數 counter = 9; // 從9開始 Serial.println("開始倒數!"); startCountdown(); // 呼叫倒數函式 } } lastButtonState = buttonState; // 記住這次的按鈕狀態 }

⏱️ 第七部分:倒數函式(最重要!)

這是倒數計時的核心程式,控制數字顯示和燈光變化

// --- 倒數函式 --- void startCountdown() { // 用for迴圈從counter倒數到0 for (int i = counter; i >= 0; i--) { display.showNumberDec(i, false); // 在數碼管上顯示數字i // 根據數字決定要亮什麼顏色的燈 if (i > 6) { setColor(1, 0, 0); // 9,8,7 → 亮紅燈 } else if (i > 3) { setColor(0, 1, 0); // 6,5,4 → 亮藍燈 } else if (i >= 0) { setColor(0, 0, 1); // 3,2,1,0 → 亮綠燈 } delay(1000); // 等待1000毫秒(1秒)再繼續 } // 倒數結束後 allOff(); // 關閉所有燈 display.showNumberDec(0); // 顯示0 Serial.println("倒數結束!"); counting = false; // 標記倒數已結束 }

💡 第八部分:控制燈光的函式

這兩個函式負責控制RGB燈的開關

// --- 控制燈光 --- void setColor(int r, int b, int g) { digitalWrite(redPin, r); // r=1就打開紅燈,r=0就關閉紅燈 digitalWrite(bluePin, b); // b=1就打開藍燈,b=0就關閉藍燈 digitalWrite(greenPin, g); // g=1就打開綠燈,g=0就關閉綠燈 } // --- 全部關燈 --- void allOff() { digitalWrite(redPin, LOW); // 關閉紅燈 digitalWrite(greenPin, LOW); // 關閉綠燈 digitalWrite(bluePin, LOW); // 關閉藍燈 }

🧠 程式運作原理(用故事來理解)

想像你在玩倒數遊戲:

  1. 🎮 按鈕是開關:按一下就開始倒數
  2. 🔢 數碼管是計分板:顯示現在倒數到幾
  3. 🚦 RGB燈是交通號誌
    • 紅燈(9~7):像紅燈停止,還有很多時間
    • 藍燈(6~4):中間階段,準備加速
    • 綠燈(3~0):綠燈通行,時間快到了!
  4. ⏱️ delay(1000):每秒換一個數字,就像時鐘的秒針
  5. 🔁 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); // 亮度0~7 // 初始化 display.showNumberDec(0); allOff(); Serial.begin(9600); Serial.println("Ready! 按下按鈕開始倒數~"); } void loop() { int buttonState = digitalRead(buttonPin); // 偵測按鈕按下(由HIGH變LOW) 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); }

🎉 完成挑戰後

恭喜你完成了進階的倒數計時器專案!現在你學會了: