WiFi簡介:工作站模式—取得NTP時間資料

ESP32使用WiFi功能時,需要引用內建的WiFi函式庫

#include <WiFi.h>

可以透過 WiFi.mode() 設定不同的工作模式:(預設為STA模式

  1. WIFI_STA,工作站模式(Station):當作普通設備,連接外部無線網路(如路由器)。
  2. WIFI_AP,熱點模式(Access Point):當作熱點供其他設備連接(如手機、電腦)。
  3. WIFI_AP_STA,混合模式(AP + Station):能連接外部無線網路,也能當作熱點供其他設備連接。

掃描WiFi基地臺

建立WiFi連線前,可先掃瞄網路,找到SSID名稱:

#include "WiFi.h"      // 引用 ESP32的WiFi函式庫

void setup()
{
  // --------------------------------------------------
  Serial.begin(9600);           // 啟用串列埠監看視窗
  // --------------------------------------------------
  WiFi.mode(WIFI_STA);          // 設為工作站模式
  WiFi.disconnect();            // 斷開之前可能保存的WiFi
  delay(100);                   // 等待100ms
  Serial.println("Setup done"); // 顯示初始化完成
  // --------------------------------------------------
}

void loop()
{
  Serial.println("scan start"); // 提示開始掃描網路
  int n = WiFi.scanNetworks();  // 掃描附近WiFi網路,找到的網路數量儲存為 n
  Serial.println("scan done");  // 掃描完成提示

  if (n == 0) // 如果沒有找到任何網路
  {                 
    Serial.println("no networks found");
  }
  else        // 找到網路時
  {
    // 顯示找到的網路數量
    Serial.print(n);
    Serial.println(" networks found");

    // 顯示所有找到的網路資訊
    for (int i = 0; i < n; ++i)
    {
      Serial.print(i + 1);        // 顯示序號
      Serial.print(": ");
      Serial.print(WiFi.SSID(i)); // 顯示網路名稱(SSID)
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i)); // 顯示信號強度(單位dBm,數值越接近0越強)
      Serial.print(")");

      // 判斷加密類型:開放網路顯示空格,加密網路顯示*
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");

      delay(10);      // 短暫延遲防止硬體處理過載
    }
  }
  Serial.println(""); // 輸出空行分隔每次掃描結果

  delay(5000);  // 5秒後重新掃描
}

連線到WiFi基地臺

透過下列方式,在設定好無線基地臺SSID及密碼後,即可連接上外部無線網路,並傳回連線狀態。

#include <WiFi.h>
const char *ssid = "SSID";       // 連上無線基地臺的SSID
const char *password = "密碼";   // 連上無線基地臺的密碼

void setup() {
  //----------------------------------------------------------
  Serial.begin(9600);                   // 啟用串列埠監看視窗
  //----------------------------------------------------------
  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 
  //----------------------------------------------------------
}

void loop() {
}
Connecting to iPhone ... CONNECTED!
SSID: iPhone
IP: 172.20.10.2
Subnet Mask IP: 255.255.255.240
Gateway IP: 172.20.10.1
DNS IP: 172.20.10.1

範例:連接到 NTP ( Network Time Protocol ) 伺服器,取得時間資料。

//---------------------------------------------------------------
#include <WiFi.h>
const char *ssid = "SSID";       // 連上無線基地臺的SSID
const char *password = "密碼";   // 連上無線基地臺的密碼
//---------------------------------------------------------------
#include "time.h"
#include "sntp.h"
const char* ntpServer1 = "pool.ntp.org";        // NTP伺服器網址1
const char* ntpServer2 = "time.nist.gov";       // NTP伺服器網址2
const char* ntpServer3 = "time.stdtime.gov.tw"; // NTP伺服器網址3
const long  gmtOffset_sec = 28800;        // GMT+8,28800秒=8小時
const int   daylightOffset_sec = 0;       // 日光節約時間
//---------------------------------------------------------------
void printLocalTime()
{
  struct tm timeinfo;           //建立一個時間結構,名稱為 timeinfo
  if(!getLocalTime(&timeinfo))  // 向NTP伺服器取得時間資料,若未取得時間資料,則返回
  {   
    Serial.println("No time available (yet)");   
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");   // 印出時間資料(格式參數)
  Serial.println(&timeinfo, "%F, %r");   // 印出時間資料(格式參數)
}
//---------------------------------------------------------------

void setup()
{
  //----------------------------------------------------------
  Serial.begin(9600);                   // 啟用串列埠監看視窗
  //----------------------------------------------------------
  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 
  //----------------------------------------------------------  
  // 設定NTP伺服器及參數
  // configTime(GMT偏移秒數, 日光節約偏移秒數, 伺服器網址)
  //----------------------------------------------------------
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2, ntpServer3);
  //----------------------------------------------------------
}

void loop()
{
  printLocalTime();     // 印出時間資料
  delay(5000);
}
Connecting to iPhone ... CONNECTED!
SSID: iPhone
IP: 172.20.10.2
Subnet Mask IP: 255.255.255.240
Gateway IP: 172.20.10.1
DNS IP: 172.20.10.1
Thursday, May 22 2025 15:17:35  ←— 第1種資料格式
2025-05-22, 03:17:35 PM  ←— 第2種資料格式