小組組員:411214209 吳宇瀚 411214217 歐邑衡
自製以七段顯示器為主的時鐘,並加上許多小功能,例如可以得知當下的溫度,蜂鳴器在整點的時候會發出多段的聲響來告知時間...
程式碼
#include <SimpleDHT.h>
#include <TM1637Display.h>
#include <DS1302.h>
// ------- 感測器/顯示器腳位定義 -------
#define DHT11_PIN 2
#define TM1_CLK 3
#define TM1_DIO 4
#define TM2_CLK 5
#define TM2_DIO 6
#define BUTTON_PIN 7
#define BUZZER_PIN 8
// ------- RTC DS1302 腳位定義 -------
DS1302 rtc(11, 10, 9); // CE, IO, SCLK
// ------- 物件初始化 -------
SimpleDHT11 dht11(DHT11_PIN);
TM1637Display displayDate(TM1_CLK, TM1_DIO);
TM1637Display displayTime(TM2_CLK, TM2_DIO);
// ------- 切換狀態 -------
bool showTemperature = false;
unsigned long lastSwitchTime = 0;
const unsigned long displayTempDuration = 5000;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
displayDate.setBrightness(5);
displayTime.setBrightness(5);
rtc.halt(false);
rtc.writeProtect(false);
Serial.println("系統啟動完成");
Serial.println("若需設定時間,請輸入格式:T:HH,MM,SS,WEEKDAY,DAY,MONTH,YEAR");
}
void loop() {
static bool lastButtonState = HIGH;
bool currentButtonState = digitalRead(BUTTON_PIN);
// 讀取按鈕切換顯示模式
if (lastButtonState == HIGH && currentButtonState == LOW) {
showTemperature = true;
lastSwitchTime = millis();
beep(1);
}
lastButtonState = currentButtonState;
// 顯示模式切換與顯示內容
if (showTemperature) {
showTempAndFeelsLike();
if (millis() - lastSwitchTime >= displayTempDuration) {
showTemperature = false;
}
} else {
showDateTime();
}
// 讀取 Serial 設定時間
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input.startsWith("T:")) {
setTimeFromSerial(input);
}
}
delay(500);
}
// ------- 顯示日期與時間 -------
void showDateTime() {
Time t = rtc.time();
int dateVal = t.mon * 100 + t.date;
int timeVal = t.hr * 100 + t.min;
displayDate.showNumberDecEx(dateVal, 0x40, true); // MM.DD
displayTime.showNumberDecEx(timeVal, 0x40, true); // HH:MM
Serial.print("日期:"); Serial.print(t.mon); Serial.print("/"); Serial.print(t.date);
Serial.print(" 時間:"); Serial.print(t.hr); Serial.print(":"); Serial.println(t.min);
}
// ------- 顯示溫度與體感溫度 -------
void showTempAndFeelsLike() {
byte temperature = 0;
byte humidity = 0;
if (dht11.read(&temperature, &humidity, NULL) != SimpleDHTErrSuccess) {
Serial.println("讀取 DHT11 失敗");
return;
}
int feelsLike = temperature - ((100 - humidity) / 5); // 簡易體感溫度計算
displayDate.showNumberDec(temperature, true);
displayTime.showNumberDec(feelsLike, true);
Serial.print("溫度:"); Serial.print((int)temperature);
Serial.print("°C 體感:"); Serial.print((int)feelsLike); Serial.println("°C");
}
// ------- 蜂鳴器提示音 -------
void beep(int times) {
for (int i = 0; i < times; i++) {
tone(BUZZER_PIN, 1000);
delay(100);
noTone(BUZZER_PIN);
delay(100);
}
}
// ------- 解析序列字串並設定時間 -------
void setTimeFromSerial(String input) {
input.remove(0, 2); // 移除 "T:"
int hh, mm, ss, wd, dd, mo, yy;
int parsed = sscanf(input.c_str(), "%d,%d,%d,%d,%d,%d,%d", &hh, &mm, &ss, &wd, &dd, &mo, &yy);
if (parsed == 7) {
Time newTime(ss, mm, hh, wd, dd, mo, yy);
rtc.time(newTime);
Serial.println("✔ 時間已更新");
beep(2);
} else {
Serial.println("❌ 格式錯誤!請使用:T:HH,MM,SS,WEEKDAY,DAY,MONTH,YEAR");
beep(3);
}
}
所需材料:
Arduino Uno 1個 主控制器
DS3231 RTC模組 1個 日期時間來源
DHT11 感測器 1個 溫濕度量測
七段顯示器 2個 顯示時間/溫度
按鈕 1個 切換模式用
蜂鳴器 1個 音效提示
跳線、電阻、面包板等 若干 連接用
按一下按鈕就可以切換成當前溫度和體感溫度
心得:
吳宇瀚
這次需要自己從採買材料開始到製作出成果都需要自己處理,這個體驗讓我覺得很有趣。製作過程中遇到的困難主要是:需要重新設定時間,所以在程式碼中增加了可以隨時設定時間的功能,這樣就不需要每次都煩惱時間的問題了。做出整個成品相當有成就感。
歐邑衡:
這次的VIP專題讓我們體驗了從構思、材料採購、程式撰寫到裝置組裝的完整流程,深刻感受到從零打造實用作品的挑戰與成就。我們以七段顯示器設計了一台能顯示時間與溫度的智慧時鐘,並加入蜂鳴器整點報時的功能。雖然外觀簡單,但模組整合與邏輯撰寫頗具挑戰。
過程中,最棘手的問題是RTC模組的時間設定。為解決每次重新上電後回到初始時間的問題,我們撰寫了可手動設定時間的程式,並搭配按鈕調整,大大提升了實用性。
這次實作讓我熟悉了Arduino開發與感測器應用,包括七段顯示器控制、蜂鳴器設定與DHT11資料讀取等。每完成一項功能都帶來滿滿成就感,也培養了解決問題與整合系統的能力。未來若面對跨領域挑戰,我也更有信心應對。