//---------------------------------------------------------------
#include <WiFi.h>
#include <time.h> // 新增:用於內建 NTP 時間功能
const char *ssid = "DAAN-CONTROL-2.4G-South"; // 連上無線基地臺的SSID
const char *password = "27541146-ctrl"; // 連上無線基地臺的密碼
//---------------------------------------------------------------
void connect_to_wifi()
{
WiFi.begin(ssid, password); // 啟動WiFi連線
Serial.printf("Connecting to %s ", ssid);
while(WiFi.status() != WL_CONNECTED) // 只要WiFi連線狀態不正常
{
delay(500); // 每0.5秒印出一個點
Serial.print(".");
}
Serial.println(" CONNECTED!");
Serial.print("SSID: ");
Serial.println(WiFi.SSID()); // 印出SSID
Serial.print("IP: ");
Serial.println(WiFi.localIP()); // 印出IP
Serial.print("Subnet Mask IP: ");
Serial.println(WiFi.subnetMask()); // 印出子網路遮罩
Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP()); // 印出閘道IP
Serial.print("DNS IP: ");
Serial.println(WiFi.dnsIP()); // 印出DNS IP
}
//---------------------------------------------------------------
#include <HTTPClient.h> // 發送http請求,取得網站資料
HTTPClient http;
// 將網址中的城市、地區、API金鑰設定為變數,以方便後續程式操控
String city = "Taipei";
String countryCode = "TW";
String ApiKey = "5bbce2816e2be856a372d97cc01a0ab7";
String url = "https://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric&appid=" + ApiKey; // 網址
//---------------------------------------------------------------
#include <ArduinoJson.h> // 解析JSON資料
String weatherDescription; // 天氣概況
String temp; // 溫度
String pressure; // 大氣壓力
String humidity; // 溼度
//---------------------------------------------------------------
// 新增:計時器變數(用來記錄上一次執行的時間點)
unsigned long lastTimeUpdate = 0;
unsigned long lastWeatherUpdate = 0;
// 新增:NTP 時間伺服器設定(設定台灣時區 UTC+8)
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600; // 台灣時區:8小時 * 3600秒
const int daylightOffset_sec = 0; // 台灣沒有夏令時間
//---------------------------------------------------------------
void get_weather_data()
{
http.begin(url); // 開始連接網頁
int httpCode = http.GET(); // 執行GET請求,回傳碼儲存於httpCode
if (httpCode == HTTP_CODE_OK) // 如果連線正常
{
String payload = http.getString(); // 傳回的網頁內容儲存於字串變數payload(承載量)
// OpenWeatherMap JSON格式解析
DynamicJsonDocument WeatherJson(payload.length() * 2); // 宣告一個Json文件
deserializeJson(WeatherJson, payload); // 解析payload為JSON
weatherDescription = WeatherJson["weather"][0]["description"].as<String>(); // 取得天氣概況
temp = WeatherJson["main"]["temp"].as<String>(); // 取得溫度
pressure = WeatherJson["main"]["pressure"].as<String>(); // 取得氣壓
humidity = WeatherJson["main"]["humidity"].as<String>(); // 取得溼度
Serial.println("\n=== [天氣更新] ===");
Serial.print("Weather: "); Serial.println(weatherDescription);
Serial.print("Temp: "); Serial.print(temp); Serial.println(" °C");
Serial.print("Pressure: "); Serial.print(pressure); Serial.println(" hPa");
Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %");
Serial.println("==================\n");
}
else
{
Serial.print("HTTP GET failed, error code: "); // 印出錯誤訊息
Serial.println(httpCode);
}
http.end(); // 結束連線
}
// 新增:取得並顯示當前時間的函式
void display_current_time()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
// 格式化輸出: 年-月-日 時:分:秒
Serial.printf("現在時間: %04d-%02d-%02d %02d:%02d:%02d\n",
timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
}
void setup()
{
Serial.begin(9600); // 啟用串列埠監看視窗
connect_to_wifi(); // 連線到WiFi
// 初始化時間設定 (向 NTP 伺服器校時)
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.println("正在同步網路時間...");
// 為了讓剛開機就能立刻看到第一次數據,先執行一次
display_current_time();
get_weather_data();
// 記錄初次執行的時間
lastTimeUpdate = millis();
lastWeatherUpdate = millis();
}
void loop()
{
unsigned long currentTime = millis(); // 取得當前系統運行時間(毫秒)
if (currentTime - lastTimeUpdate >= 1000) {
display_current_time();
lastTimeUpdate = currentTime; // 更新記錄點
}
if (currentTime - lastWeatherUpdate >= 10000) {
get_weather_data();
lastWeatherUpdate = currentTime; // 更新記錄點
}
}