{"id":1890,"date":"2025-10-22T08:47:37","date_gmt":"2025-10-22T00:47:37","guid":{"rendered":"https:\/\/www.640629.xyz\/?p=1890"},"modified":"2025-10-22T08:47:38","modified_gmt":"2025-10-22T00:47:38","slug":"wifi%e7%b7%b4%e7%bf%92%ef%bc%9a%e6%b7%b7%e5%90%88%e6%a8%a1%e5%bc%8f","status":"publish","type":"post","link":"https:\/\/www.640629.xyz\/?p=1890","title":{"rendered":"WiFi\u7df4\u7fd2\uff1a \u6df7\u5408\u6a21\u5f0f\u2014 WebServer + DHT22 + NTP + OpenWeatherMap"},"content":{"rendered":"\n<p>ESP32\u4f7f\u7528WiFi\u529f\u80fd\u6642\uff0c\u67093\u7a2e\u6a21\u5f0f\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>WIFI_STA\uff0c\u5de5\u4f5c\u7ad9\u6a21\u5f0f(Station)\uff1a\u7576\u4f5c\u666e\u901a\u8a2d\u5099\uff0c\u9023\u63a5\u5916\u90e8\u7121\u7dda\u7db2\u8def(\u5982\u8def\u7531\u5668)\u3002<\/li>\n\n\n\n<li>WIFI_AP\uff0c\u71b1\u9ede\u6a21\u5f0f(Access Point)\uff1a\u7576\u4f5c\u71b1\u9ede\u4f9b\u5176\u4ed6\u8a2d\u5099\u9023\u63a5(\u5982\u624b\u6a5f\u3001\u96fb\u8166)\u3002<\/li>\n\n\n\n<li>WIFI_AP_STA\uff0c\u6df7\u5408\u6a21\u5f0f(AP + Station)\uff1a\u80fd\u9023\u63a5\u5916\u90e8\u7121\u7dda\u7db2\u8def\uff0c\u4e5f\u80fd\u7576\u4f5c\u71b1\u9ede\u4f9b\u5176\u4ed6\u8a2d\u5099\u9023\u63a5\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u672c\u6b21\u7df4\u7fd2\u63a1\u7528 WIFI_AP_STA \u6df7\u5408\u6a21\u5f0f\uff0c\u5e0c\u671b\u9054\u6210\u4e0b\u5217\u529f\u80fd\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u4ee5\u524d\u6b21\u7df4\u7fd2\u7684\u300c\u9664\u6fd5\u6a5f\u6a21\u64ec\u7cfb\u7d71\u300d\u70ba\u57fa\u790e\uff0c ESP32 \u672c\u6a5f\u900f\u904e DHT22 \u6eab\u6fd5\u5ea6\u611f\u6e2c\u5668\uff0c\u53ef\u53d6\u5f97\u6eab\u5ea6\u3001\u6fd5\u5ea6\u7b49\u6578\u64da\u3002<\/li>\n\n\n\n<li>WiFi \u8a2d\u5b9a\u70ba\u6df7\u5408\u6a21\u5f0f\u3002<\/li>\n\n\n\n<li>\u900f\u904e\u5de5\u4f5c\u7ad9\u6a21\u5f0f\uff0c\u9023\u63a5\u5916\u90e8\u7121\u7dda\u7db2\u8def\uff0c\u53d6\u5f97 NTP \u7db2\u8def\u6642\u9593\uff0c\u4ee5\u53ca OpenWeatherMap \u7db2\u7ad9\u7684\u5373\u6642\u5929\u6c23\u3001\u6eab\u5ea6\u3001\u6fd5\u5ea6\u3001\u58d3\u529b\u7b49\u6578\u64da\u3002<\/li>\n\n\n\n<li>\u900f\u904e\u71b1\u9ede\u6a21\u5f0f\uff0c\u4f9b\u5176\u4ed6\u8a2d\u5099\u9023\u63a5\uff0c\u67e5\u770b\u5404\u9805\u6578\u64da\u3002<\/li>\n\n\n\n<li>\u900f\u904e Web Server \u7db2\u9801\u4ecb\u9762\uff0c\u652f\u63f4 AJAX \u5373\u6642\u66f4\u65b0\uff0c\u80fd\u986f\u793a\uff1a<br>(1) \u672c\u6a5f\u6fd5\u5ea6\u3001\u6eab\u5ea6\u3001\u9ad4\u611f\u6eab\u5ea6\u3001\u904b\u8f49\u72c0\u614b\u8207\u6a21\u5f0f\u3002<br>(2) NTP \u7db2\u8def\u6642\u9593\u3002<br>(3) OpenWeatherMap \u7db2\u7ad9\u4e0a\u7684\u5373\u6642\u5929\u6c23\u3001\u6eab\u5ea6\u3001\u6fd5\u5ea6\u3001\u58d3\u529b\u7b49\u8a0a\u606f\u3002<\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\">\n<figure class=\"alignleft size-large\"><img decoding=\"async\" src=\"https:\/\/img.640629.xyz\/i\/68f726e222552.png\" alt=\"\"\/><\/figure>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\">\n<figure class=\"alignleft size-large\"><img decoding=\"async\" src=\"https:\/\/img.640629.xyz\/i\/68f726e2c73d0.png\" alt=\"\"\/><\/figure>\n<\/div><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>WIFI\u6df7\u5408\u6a21\u5f0f<\/strong>\u7bc4\u4f8b\u7a0b\u5f0f<\/h2>\n\n\n\n<pre title=\"wifi_setup.h\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ \u4fdd\u8b77\u6a19\u982d\u6a94\uff0c\u907f\u514d\u540c\u4e00\u500b .h \u6a19\u982d\u6a94\u88ab\u91cd\u8907\u5f15\u7528\n#ifndef WIFI_SETUP_H\n#define WIFI_SETUP_H\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include &lt;WiFi.h&gt;                         \/\/ \u5f15\u7528WiFi\u51fd\u5f0f\u5eab\nconst char *sta_ssid = \"SSID\";            \/\/ \u7121\u7dda\u57fa\u5730\u81fa\u540d\u7a31(\u5de5\u4f5c\u7ad9\u6a21\u5f0f)\nconst char *sta_password = \"\u5bc6\u78bc\";         \/\/ \u7121\u7dda\u57fa\u5730\u81fa\u5bc6\u78bc(\u5de5\u4f5c\u7ad9\u6a21\u5f0f)\nconst char *ap_ssid = \"\u71b1\u9ede\u540d\u7a31\";          \/\/ \u71b1\u9ede\u540d\u7a31(\u71b1\u9ede\u6a21\u5f0f)\nconst char *ap_password = \"\u71b1\u9ede\u5bc6\u78bc\";      \/\/ \u71b1\u9ede\u5bc6\u78bc(\u71b1\u9ede\u6a21\u5f0f)\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void connect_to_wifi()    \/\/ \u9023\u7dda\u5230WiFi(\u5de5\u4f5c\u7ad9\u6a21\u5f0f)\n{\n  WiFi.begin(sta_ssid, sta_password);     \/\/ \u555f\u52d5WiFi\u9023\u7dda(\u5de5\u4f5c\u7ad9\u6a21\u5f0f)\n  Serial.println(\"\\n----------------------------------\");\n  Serial.printf(\"Connecting to %s \", sta_ssid);\n  while(WiFi.status() != WL_CONNECTED)    \/\/ \u53ea\u8981WiFi\u9023\u7dda\u72c0\u614b\u4e0d\u6b63\u5e38\n  {\n    delay(500);                           \/\/ \u6bcf0.5\u79d2\u5370\u51fa\u4e00\u500b\u9ede\n    Serial.print(\".\");\n  }\n  Serial.println(\" CONNECTED!\");\n  Serial.print(\"SSID: \");\n  Serial.println(WiFi.SSID());            \/\/ \u5370\u51faSSID\n  Serial.print(\"IP: \");\n  Serial.println(WiFi.localIP());         \/\/ \u5370\u51faIP\n  Serial.print(\"Subnet Mask IP: \");\n  Serial.println(WiFi.subnetMask());      \/\/ \u5370\u51fa\u5b50\u7db2\u8def\u906e\u7f69\n  Serial.print(\"Gateway IP: \");\n  Serial.println(WiFi.gatewayIP());       \/\/ \u5370\u51fa\u9598\u9053IP\n  Serial.print(\"DNS IP: \");\n  Serial.println(WiFi.dnsIP());           \/\/ \u5370\u51faDNS IP  \n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void startAP()  \/\/ \u555f\u7528\u71b1\u9ede\n{\n  while (!WiFi.softAP(ap_ssid, ap_password))  \/\/ \u82e5\u71b1\u9ede\u5c1a\u672a\u555f\u52d5\uff0c\u5247\u6bcf0.5\u79d2\u5370\u51fa\u4e00\u500b\u9ede\n  {\n    delay(500);\n    Serial.print(\".\");\n  }\n  Serial.println(\"\\n----------------------------------\");\n  Serial.println(\"\u71b1\u9ede\u555f\u52d5\u6210\u529f\");\n  Serial.print(\"IP Address: \");\n  Serial.println(WiFi.softAPIP());  \/\/ \u5370\u51fa\u71b1\u9ede\u7684IP\u4f4d\u5740\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include &lt;esp_wifi.h&gt;                \/\/ \u5f15\u7528esp_wifi\u51fd\u5f0f\u5eab\ninline void listConnectedStations()  \/\/ \u5370\u51fa\u5df2\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae\n{\n  wifi_sta_list_t station_list;             \/\/ \u5132\u5b58\u9023\u7dda\u88dd\u7f6e\u5217\u8868\u7684\u7d50\u69cb\n  esp_wifi_ap_get_sta_list(&amp;station_list);  \/\/ \u7372\u53d6\u7576\u524d\u9023\u63a5\u5230AP\u7684\u6240\u6709\u88dd\u7f6e\u5217\u8868\n\n  Serial.println(\"--------- \u7576\u524d\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae ---------\");\n  Serial.print(\"\u9023\u7dda\u88dd\u7f6e\u6578\u91cf: \");\n  Serial.println(station_list.num);\n  Serial.println(\"----------------------------------\");\n\n  if (station_list.num &gt; 0) {\n    Serial.println(\"\u7de8\u865f       MAC \u4f4d\u5740       IP \u4f4d\u5740\");\n    Serial.println(\"----------------------------------\");\n\n    for (int i = 0; i &lt; station_list.num; i++) {\n      wifi_sta_info_t station = station_list.sta[i];\n\n      \/\/ \u53d6\u5f97 MAC \u4f4d\u5740\n      char macStr[18];\n      snprintf(macStr, sizeof(macStr), \"%02X:%02X:%02X:%02X:%02X:%02X\", station.mac[0], station.mac[1], station.mac[2], station.mac[3], station.mac[4], station.mac[5]);\n\n      \/\/ \u53d6\u5f97 IP \u4f4d\u5740 (\u9700\u8981\u900f\u904e DHCP \u79df\u7d04\u5217\u8868)\n      IPAddress ip = WiFi.softAPIP();\n      ip[3] = i + 2;  \/\/ \u9810\u8a2d\u5206\u914d\u5f9e .2 \u958b\u59cb\n\n      \/\/ \u986f\u793a\u88dd\u7f6e\u8cc7\u8a0a\n      Serial.printf(\"%2d  %s  %s\\n\", i + 1, macStr, ip.toString().c_str());\n    }\n  } else {\n    Serial.println(\"\u76ee\u524d\u6c92\u6709\u88dd\u7f6e\u9023\u7dda\");\n  }\n\n  Serial.println(\"----------------------------------\");\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void WiFiEvent(WiFiEvent_t event, arduino_event_info_t info)  \/\/ WiFi\u4e8b\u4ef6\u8655\u7406\u51fd\u5f0f\n{\n  uint8_t *mac = nullptr;   \/\/ \u5ba3\u544aMAC\u4f4d\u5740\u6307\u6a19\n  char macStr[18] = { 0 };  \/\/ \u5132\u5b58\u683c\u5f0f\u5316MAC\u4f4d\u5740\u7684\u5b57\u4e32\u7de9\u885d\u5340\n\n  switch (event) {\n    case ARDUINO_EVENT_WIFI_AP_STACONNECTED:  \/\/ \u88dd\u7f6e\u5df2\u9023\u7dda\n      \/\/ \u5f9e\u4e8b\u4ef6\u8cc7\u8a0a\u4e2d\u63d0\u53d6MAC\u4f4d\u5740\uff0c\u4e26\u5c07MAC\u4f4d\u5740\u683c\u5f0f\u5316\u70ba\u5b57\u4e32(XX:XX:XX:XX:XX:XX)\n      mac = info.wifi_ap_staconnected.mac;\n      snprintf(macStr, sizeof(macStr), \"%02X:%02X:%02X:%02X:%02X:%02X\", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);\n      Serial.println(\"\\n[\u4e8b\u4ef6] \u88dd\u7f6e\u5df2\u9023\u7dda\");\n      Serial.print(\"MAC: \");\n      Serial.println(macStr);\n      listConnectedStations();  \/\/ \u66f4\u65b0\u4e26\u986f\u793a\u7576\u524d\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae\n      break;\n\n    case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:  \/\/ \u88dd\u7f6e\u65b7\u958b\u9023\u7dda\n      \/\/ \u5f9e\u4e8b\u4ef6\u8cc7\u8a0a\u4e2d\u63d0\u53d6MAC\u4f4d\u5740\uff0c\u4e26\u5c07MAC\u4f4d\u5740\u683c\u5f0f\u5316\u70ba\u5b57\u4e32(XX:XX:XX:XX:XX:XX)\n      mac = info.wifi_ap_stadisconnected.mac;\n      snprintf(macStr, sizeof(macStr), \"%02X:%02X:%02X:%02X:%02X:%02X\", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);\n      Serial.println(\"\\n[\u4e8b\u4ef6] \u88dd\u7f6e\u5df2\u65b7\u958b\u9023\u7dda\");\n      Serial.print(\"MAC: \");\n      Serial.println(macStr);\n      listConnectedStations();  \/\/ \u66f4\u65b0\u4e26\u986f\u793a\u7576\u524d\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae\n      break;\n  }\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#endif<\/code><\/pre>\n\n\n\n<pre title=\"\u3008WIFI_AP_STA \u6df7\u5408\u6a21\u5f0f\u3009\u7a0b\u5f0f\u67b6\u69cb\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/-----------------------------------------------------------------------\n#include \"wifi_setup.h\"     \/\/ \u5f15\u7528 \"wifi_setup.h\"\n\/\/-----------------------------------------------------------------------\n\nvoid setup() {\n  \/\/----------------------------------------------------------------------------------------\n  Serial.begin(9600);       \/\/ \u555f\u7528\u4e32\u5217\u57e0\u76e3\u770b\u8996\u7a97\n  \/\/----------------------------------------------------------------------------------------\n  WiFi.mode(WIFI_AP_STA);   \/\/ \u8a2d\u5b9a\u70ba\u6df7\u5408\u6a21\u5f0f\n  \/\/--------------------------------- \u9023\u63a5WiFi\u8a2d\u5b9a ------------------------------------------\n  connect_to_wifi();        \/\/ \u9023\u7dda\u5230WiFi\n  \/\/--------------------------------- softAP\u8a2d\u5b9a --------------------------------------------\n  startAP();                \/\/ \u555f\u7528\u71b1\u9ede\n  WiFi.onEvent(WiFiEvent);  \/\/ \u555f\u7528WiFi\u4e8b\u4ef6\u8655\u7406\n  listConnectedStations();  \/\/ \u5370\u51fa\u5df2\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae  \n  \/\/----------------------------------------------------------------------------------------\n}\n\nvoid loop() {\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">DHT \u7bc4\u4f8b\u7a0b\u5f0f<\/h2>\n\n\n\n<pre title=\"dht_setup.h\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ \u4fdd\u8b77\u6a19\u982d\u6a94\uff0c\u907f\u514d\u540c\u4e00\u500b .h \u6a19\u982d\u6a94\u88ab\u91cd\u8907\u5f15\u7528\n#ifndef DHT_SETUP_H\n#define DHT_SETUP_H\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include \"DHT.h\"            \/\/ \u5f15\u7528\u5916\u90e8\u51fd\u5f0f\u5eab\uff0c\u540d\u7a31DHT\n#define DHTPIN 23           \/\/ Digital pin connected to the DHT sensor\n#define DHTTYPE DHT22       \/\/ DHT 22\nDHT dht(DHTPIN, DHTTYPE);   \/\/ \u5efa\u7acbDHT\u7269\u4ef6\uff0c\u540d\u70badht\nfloat h;    \/\/ \u6fd5\u5ea6\u8cc7\u6599\nfloat t;    \/\/ \u651d\u6c0f\u6eab\u5ea6\nfloat f;    \/\/ \u83ef\u6c0f\u6eab\u5ea6\nfloat hic;  \/\/ \u651d\u6c0f\u9ad4\u611f\u6eab\u5ea6\nfloat hif;  \/\/ \u83ef\u6c0f\u9ad4\u611f\u6eab\u5ea6\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void get_dht()   \/\/ \u53d6\u5f97dht\u8cc7\u6599\n{\n\th = dht.readHumidity();         \/\/ \u53d6\u5f97\u6fd5\u5ea6\u8cc7\u6599\n\tt = dht.readTemperature();      \/\/ \u53d6\u5f97\u651d\u6c0f\u6eab\u5ea6\n\tf = dht.readTemperature(true);  \/\/ \u53d6\u5f97\u83ef\u6c0f\u6eab\u5ea6\n\n\t\/\/ \u82e5\u8b80\u4e0d\u5230\u8cc7\u6599\uff0c\u5247\u986f\u793a\u932f\u8aa4\u8a0a\u606f\uff0c\u4e26\u96e2\u958b\n\tif (isnan(h) || isnan(t) || isnan(f))\n\t{\n\t  Serial.println(\"Failed to read from DHT sensor!\");\n\t  return;\n\t}\n\n\thic = dht.computeHeatIndex(t, h, false);  \/\/ \u651d\u6c0f\u9ad4\u611f\u6eab\u5ea6\n\thif = dht.computeHeatIndex(f, h, true);   \/\/ \u83ef\u6c0f\u9ad4\u611f\u6eab\u5ea6\n\n\t\/\/ \u5c07\u6eab\u6fd5\u5ea6\u6578\u64da\u986f\u793a\u5728\u76e3\u770b\u8996\u7a97\n\tSerial.print(\"\u6fd5\u5ea6: \");\n\tSerial.print(h);\n\tSerial.print(\"%,  \u6eab\u5ea6: \");\n\tSerial.print(t);\n\tSerial.print(\"\u00b0C \");\n\tSerial.print(f);\n\tSerial.print(\"\u00b0F,  \u9ad4\u611f\u6eab\u5ea6: \");\n\tSerial.print(hic);\n\tSerial.print(\"\u00b0C \");\n\tSerial.print(hif);\n\tSerial.println(\"\u00b0F\");  \n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#endif<\/code><\/pre>\n\n\n\n<pre title=\"\u3008\u53d6\u5f97 DHT \u6eab\u6fd5\u5ea6\u6578\u64da\u3009\u7a0b\u5f0f\u67b6\u69cb\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/-----------------------------------------------------------------------\n#include \"dht_setup.h\"      \/\/ \u5f15\u7528 \"dht_setup.h\"\n\/\/-----------------------------------------------------------------------\nunsigned long previousMillis = 0;    \/\/ \u524d\u4e00\u6b21\u7684millis()\u6642\u9593\nconst long interval = 2000;          \/\/ \u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n\/\/-----------------------------------------------------------------------\n\nvoid setup() {\n  \/\/----------------------------------------------------------------------------------------\n  Serial.begin(9600);       \/\/ \u555f\u7528\u4e32\u5217\u57e0\u76e3\u770b\u8996\u7a97\n  \/\/--------------------------------- \u9023\u63a5 DHT22 --------------------------------------------\n  dht.begin();              \/\/ \u555f\u7528dht\u7269\u4ef6\n  \/\/----------------------------------------------------------------------------------------\n}\n\nvoid loop() {\n  unsigned long currentMillis = millis();          \/\/ \u7576\u524d\u7684millis()\u6642\u9593\n  \/\/---------------------------------------------------------------------\n  if (currentMillis - previousMillis &gt;= interval)  \/\/ \u6bcf\u7d93\u904e\u4e00\u500binterval\u7684\u6642\u9593\n  {\n    get_dht();                        \/\/ \u53d6\u5f97dht\u8cc7\u6599\n    previousMillis = currentMillis;   \/\/ \u66f4\u65b0\u524d\u4e00\u6b21\u7684millis()\u6642\u9593\n  }\n  \/\/---------------------------------------------------------------------\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">NTP \u7bc4\u4f8b\u7a0b\u5f0f<\/h2>\n\n\n\n<pre title=\"ntp_setup.h\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ \u4fdd\u8b77\u6a19\u982d\u6a94\uff0c\u907f\u514d\u540c\u4e00\u500b .h \u6a19\u982d\u6a94\u88ab\u91cd\u8907\u5f15\u7528\n#ifndef NTP_SETUP_H\n#define NTP_SETUP_H\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include \"time.h\"\n#include \"sntp.h\"\nconst char* ntpServer1 = \"pool.ntp.org\";        \/\/ NTP\u4f3a\u670d\u5668\u7db2\u57401\nconst char* ntpServer2 = \"time.nist.gov\";       \/\/ NTP\u4f3a\u670d\u5668\u7db2\u57402\nconst char* ntpServer3 = \"time.stdtime.gov.tw\"; \/\/ NTP\u4f3a\u670d\u5668\u7db2\u57403\nconst long  gmtOffset_sec = 28800;        \/\/ GMT+8\uff0c28800\u79d2=8\u5c0f\u6642\nconst int   daylightOffset_sec = 0;       \/\/ \u65e5\u5149\u7bc0\u7d04\u6642\u9593\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void configNTP()  \/\/ \u8a2d\u5b9aNTP\u4f3a\u670d\u5668\u53ca\u53c3\u6578\n{\n  \/\/ configTime(GMT\u504f\u79fb\u79d2\u6578, \u65e5\u5149\u7bc0\u7d04\u504f\u79fb\u79d2\u6578, \u4f3a\u670d\u5668\u7db2\u57401, \u4f3a\u670d\u5668\u7db2\u57402, \u4f3a\u670d\u5668\u7db2\u57403)\n  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2, ntpServer3);\n} \n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void printLocalTime()\t\/\/ \u5370\u51fa\u6642\u9593\u8cc7\u6599\n{\n  struct tm timeinfo;           \/\/ \u5efa\u7acb\u4e00\u500b\u6642\u9593\u7d50\u69cb\uff0c\u540d\u7a31\u70ba timeinfo\n  if(!getLocalTime(&amp;timeinfo))  \/\/ \u5411NTP\u4f3a\u670d\u5668\u53d6\u5f97\u6642\u9593\u8cc7\u6599\uff0c\u82e5\u672a\u53d6\u5f97\u6642\u9593\u8cc7\u6599\uff0c\u5247\u8fd4\u56de\n  {   \n    Serial.println(\"No time available (yet)\");   \n    return;\n  }\n  Serial.println(&amp;timeinfo, \"%A, %B %d %Y %H:%M:%S\");   \/\/ \u5370\u51fa\u6642\u9593\u8cc7\u6599(\u7b2c1\u7a2e\u8cc7\u6599\u683c\u5f0f)\n  Serial.println(&amp;timeinfo, \"%F, %r\");   \/\/ \u5370\u51fa\u6642\u9593\u8cc7\u6599(\u7b2c2\u7a2e\u8cc7\u6599\u683c\u5f0f)\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#endif<\/code><\/pre>\n\n\n\n<pre title=\"\u3008\u53d6\u5f97 NTP \u670d\u52d9\u5668\u6642\u9593\u3009\u7a0b\u5f0f\u67b6\u69cb\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/-----------------------------------------------------------------------\n#include \"wifi_setup.h\"     \/\/ \u5f15\u7528 \"wifi_setup.h\"\n\/\/-----------------------------------------------------------------------\n#include \"ntp_setup.h\"      \/\/ \u5f15\u7528 \"ntp_setup.h\"\n\/\/-----------------------------------------------------------------------\nunsigned long previousMillis = 0;    \/\/ \u524d\u4e00\u6b21\u7684millis()\u6642\u9593\nconst long interval = 1000;          \/\/ \u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n\/\/-----------------------------------------------------------------------\nvoid setup() {\n  \/\/----------------------------------------------------------------------------------------\n  Serial.begin(9600);       \/\/ \u555f\u7528\u4e32\u5217\u57e0\u76e3\u770b\u8996\u7a97\n  \/\/----------------------------------------------------------------------------------------\n  WiFi.mode(WIFI_AP_STA);   \/\/ \u8a2d\u5b9a\u70ba\u6df7\u5408\u6a21\u5f0f\n  \/\/--------------------------------- \u9023\u63a5WiFi\u8a2d\u5b9a ------------------------------------------\n  connect_to_wifi();        \/\/ \u9023\u7dda\u5230WiFi\n  \/\/-------------------------------- NTP\u4f3a\u670d\u5668\u8a2d\u5b9a ------------------------------------------\n  configNTP();              \/\/ NTP\u4f3a\u670d\u5668\u8a2d\u5b9a\n  \/\/----------------------------------------------------------------------------------------\n}\n\nvoid loop() {\n  unsigned long currentMillis = millis();          \/\/ \u7576\u524d\u7684millis()\u6642\u9593\n  \/\/---------------------------------------------------------------------\n  if (currentMillis - previousMillis &gt;= interval)  \/\/ \u6bcf\u7d93\u904e\u4e00\u500binterval\u7684\u6642\u9593\n  {\n    printLocalTime();                 \/\/ \u5370\u51fa NTP \u6642\u9593\u8cc7\u6599\n    previousMillis = currentMillis;   \/\/ \u66f4\u65b0\u524d\u4e00\u6b21\u7684millis()\u6642\u9593\n  }\n  \/\/---------------------------------------------------------------------  \n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">OpenWeatherMap \u7bc4\u4f8b\u7a0b\u5f0f<\/h2>\n\n\n\n<pre title=\"weather_setup.h\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ \u4fdd\u8b77\u6a19\u982d\u6a94\uff0c\u907f\u514d\u540c\u4e00\u500b .h \u6a19\u982d\u6a94\u88ab\u91cd\u8907\u5f15\u7528\n#ifndef WEATHER_SETUP_H\n#define WEATHER_SETUP_H\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include &lt;HTTPClient.h&gt;                 \/\/ \u767c\u9001http\u8acb\u6c42\uff0c\u53d6\u5f97\u7db2\u7ad9\u8cc7\u6599\nHTTPClient http;\n\/\/ String url = \"https:\/\/api.openweathermap.org\/data\/2.5\/weather?q=Taipei,TW&amp;units=metric&amp;appid=API\u91d1\u9470\";   \/\/ \u7db2\u5740\n\/\/ \u5c07\u7db2\u5740\u4e2d\u7684\u57ce\u5e02\u3001\u5730\u5340\u3001API\u91d1\u9470\u8a2d\u5b9a\u70ba\u8b8a\u6578\uff0c\u4ee5\u65b9\u4fbf\u5f8c\u7e8c\u7a0b\u5f0f\u64cd\u63a7\nString city = \"Taipei\";\nString countryCode = \"TW\";\nString ApiKey = \"API\u91d1\u9470\";\nString url = \"https:\/\/api.openweathermap.org\/data\/2.5\/weather?q=\" + city + \",\" + countryCode + \"&amp;units=metric&amp;appid=\" + ApiKey; \/\/ \u7db2\u5740\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include &lt;ArduinoJson.h&gt;                \/\/ \u89e3\u6790JSON\u8cc7\u6599\nString weatherDescription;              \/\/ \u5929\u6c23\u6982\u6cc1\nString temp;                            \/\/ \u6eab\u5ea6\nString pressure;                        \/\/ \u5927\u6c23\u58d3\u529b\nString humidity;                        \/\/ \u6ebc\u5ea6\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void get_weather_data()          \/\/ \u53d6\u5f97\u5929\u6c23\u8cc7\u6599\n{\n  http.begin(url);                      \/\/ \u958b\u59cb\u9023\u63a5\u7db2\u9801\n  int httpCode = http.GET();            \/\/ \u57f7\u884cGET\u8acb\u6c42\uff0c\u56de\u50b3\u78bc\u5132\u5b58\u65bchttpCode\n\n  if (httpCode == HTTP_CODE_OK)         \/\/ \u5982\u679c\u9023\u7dda\u6b63\u5e38\n  {\n    String payload = http.getString();  \/\/ \u50b3\u56de\u7684\u7db2\u9801\u5167\u5bb9\u5132\u5b58\u65bc\u5b57\u4e32\u8b8a\u6578payload(\u627f\u8f09\u91cf)\n    \/\/ Serial.println(payload);         \/\/ \u5370\u51fa\u50b3\u56de\u7684\u7db2\u9801\u5167\u5bb9\n    \n    \/\/ -------------------------------------------------------------\n    \/\/ OpenWeatherMap JSON\u683c\u5f0f\u89e3\u6790\n    \/\/ -------------------------------------------------------------\n    DynamicJsonDocument WeatherJson(payload.length() * 2);    \/\/ \u5ba3\u544a\u4e00\u500bJson\u6587\u4ef6\uff0c\u540d\u7a31\u70baWeatherJson\uff08\u9663\u5217\u683c\u5f0f\uff09\n    deserializeJson(WeatherJson, payload);                    \/\/ \u89e3\u6790payload\u70baJSON Array\u683c\u5f0f\n\n    weatherDescription = WeatherJson[\"weather\"][0][\"description\"].as&lt;String&gt;();   \/\/ \u53d6\u5f97\u5929\u6c23\u6982\u6cc1\uff0cweather\u662f\u9663\u5217\uff0c[0]\u662f\u7d22\u5f15\u503c\n    temp = WeatherJson[\"main\"][\"temp\"].as&lt;String&gt;();          \/\/ \u53d6\u5f97\u6eab\u5ea6\n    pressure = WeatherJson[\"main\"][\"pressure\"].as&lt;String&gt;();  \/\/ \u53d6\u5f97\u6c23\u58d3\n    humidity = WeatherJson[\"main\"][\"humidity\"].as&lt;String&gt;();  \/\/ \u53d6\u5f97\u6ebc\u5ea6\n    Serial.println(\"----------------------------------\");\n    Serial.print(\"Weather description: \");\n    Serial.println(weatherDescription);\n    Serial.print(\"Temp: \");\n    Serial.print(temp);\n    Serial.println(\" \u00b0C\");\n    Serial.print(\"Pressure: \");\n    Serial.print(pressure);\n    Serial.println(\" hPa\");\n    Serial.print(\"Humidity: \");\n    Serial.print(humidity);\n    Serial.println(\" %\");\n    Serial.println(\"----------------------------------\");\n  }\n  else\n  {\n    Serial.print(\"HTTP GET failed, error code: \");      \/\/ \u5370\u51fa\u932f\u8aa4\u8a0a\u606f\n    Serial.println(httpCode);\n  } \n  \n  http.end();                           \/\/ \u7d50\u675f\u9023\u7dda\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#endif<\/code><\/pre>\n\n\n\n<pre title=\"\u3008\u53d6\u5f97 OpenWeatherMap \u6c23\u8c61\u8cc7\u8a0a\u3009\u7a0b\u5f0f\u67b6\u69cb\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/-----------------------------------------------------------------------\n#include \"wifi_setup.h\"     \/\/ \u5f15\u7528 \"wifi_setup.h\"\n\/\/-----------------------------------------------------------------------\n#include \"weather_setup.h\"  \/\/ \u5f15\u7528 \"weather_setup.h\"\n\/\/-----------------------------------------------------------------------\nunsigned long previousMillis = 0;    \/\/ \u524d\u4e00\u6b21\u7684millis()\u6642\u9593\nconst long interval = 5000;          \/\/ \u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n\/\/-----------------------------------------------------------------------\n\nvoid setup() {\n  \/\/----------------------------------------------------------------------------------------\n  Serial.begin(9600);       \/\/ \u555f\u7528\u4e32\u5217\u57e0\u76e3\u770b\u8996\u7a97\n  \/\/----------------------------------------------------------------------------------------\n  WiFi.mode(WIFI_AP_STA);   \/\/ \u8a2d\u5b9a\u70ba\u6df7\u5408\u6a21\u5f0f\n  \/\/--------------------------------- \u9023\u63a5WiFi\u8a2d\u5b9a ------------------------------------------\n  connect_to_wifi();        \/\/ \u9023\u7dda\u5230WiFi  \n  \/\/----------------------------------------------------------------------------------------\n}\n\nvoid loop() {\n  unsigned long currentMillis = millis();          \/\/ \u7576\u524d\u7684millis()\u6642\u9593\n  \/\/---------------------------------------------------------------------\n  if (currentMillis - previousMillis &gt;= interval)  \/\/ \u82e5\u9054\u5230\u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n  {\n    get_weather_data();               \/\/ \u53d6\u5f97\u5929\u6c23\u8cc7\u6599\n    previousMillis = currentMillis;   \/\/ \u66f4\u65b0\u524d\u4e00\u6b21\u7684millis()\u6642\u9593\n  }\n  \/\/---------------------------------------------------------------------\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>WebServer <\/strong>\u7bc4\u4f8b\u7a0b\u5f0f<\/h2>\n\n\n\n<pre title=\"web_setup.h\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ \u4fdd\u8b77\u6a19\u982d\u6a94\uff0c\u907f\u514d\u540c\u4e00\u500b .h \u6a94\u88ab\u91cd\u8907\u5f15\u7528\n#ifndef WEB_SETUP_H\n#define WEB_SETUP_H\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#include &lt;WebServer.h>    \/\/ \u5f15\u7528WebServer\u51fd\u5f0f\u5eab\n#include \"dht_setup.h\"    \/\/ \u5f15\u7528dht_setup.h\n\/\/-------------------------------------------------------------------------------------------------------------------------\n\/\/ \u5916\u90e8\u8b8a\u6578\u5ba3\u544a\uff0c\u5f15\u7528\u4e3b\u7a0b\u5f0f\u4e2d\u7684\u8b8a\u6578\nextern const int ledPin;  \/\/ LED \u6a21\u64ec\u9664\u6fd5\u6a5f\nextern bool ledState;     \/\/ LED(\u9664\u6fd5\u6a5f)\u72c0\u614b\nextern bool mode;         \/\/ \u63a7\u5236\u6a21\u5f0f\uff0cfalse = \u81ea\u52d5(auto), true = \u624b\u52d5(manual)\n\/\/-------------------------------------------------------------------------------------------------------------------------\nWebServer server(80);     \/\/ \u5efa\u7acbWebServer\u7269\u4ef6 (port 80)\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleRoot()  \/\/ \u9996\u9801\n{\n  String html = \"&lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\"\n                \"&lt;h2>ESP32 \u9664\u6fd5\u6a5f\u6a21\u64ec\u7cfb\u7d71&lt;\/h2>\"\n                \"&lt;ul>\"\n                \"&lt;li>&lt;a href=\\\"\/on\\\">\u624b\u52d5\u555f\u52d5\u9664\u6fd5\u6a5f&lt;\/a>&lt;\/li>\"\n                \"&lt;li>&lt;a href=\\\"\/off\\\">\u624b\u52d5\u505c\u6b62\u9664\u6fd5\u6a5f&lt;\/a>&lt;\/li>\"\n                \"&lt;li>&lt;a href=\\\"\/auto\\\">\u5207\u56de\u81ea\u52d5\u6a21\u5f0f&lt;\/a>&lt;\/li>\"\n                \"&lt;\/ul>\"\n                \"&lt;div id=\\\"status\\\">AJAX \u8b80\u53d6\u4e2d...&lt;\/div>\"\n                \"&lt;script>\"\n                \"function updateStatus(){\"\n                \"  fetch('\/status')\"\n                \"    .then(response => response.json())\"\n                \"    .then(data => {\"\n                \"      let html = '';\"\n                \"      html += '\u6fd5\u5ea6\uff1a' + data.humidity + '%&lt;br>';\"\n                \"      html += '\u6eab\u5ea6\uff1a' + data.tempC + '\u00b0C \/ ' + data.tempF + '\u00b0F&lt;br>';\"\n                \"      html += '\u9ad4\u611f\u6eab\u5ea6\uff1a' + data.heatIndexC + '\u00b0C \/ ' + data.heatIndexF + '\u00b0F&lt;br>';\"\n                \"      html += '\u9664\u6fd5\u6a5f\u72c0\u614b\uff1a' + data.dehumidifier + '&lt;br>';\"\n                \"      html += '\u63a7\u5236\u6a21\u5f0f\uff1a' + data.mode;\"\n                \"      document.getElementById('status').innerHTML = html;\"\n                \"    });\"\n                \"}\"\n                \"setInterval(updateStatus,2000);\"\n                \"updateStatus();\"\n                \"&lt;\/script>\";\n\n  server.send(200, \"text\/html; charset=UTF-8\", html);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleOn()      \/\/ \u624b\u52d5\u555f\u52d5\u9664\u6fd5\u6a5f\n{\n  mode = true;        \/\/ \u5207\u5230\u624b\u52d5\u6a21\u5f0f\n  ledState = true;    \/\/ \u958b\u555f\u9664\u6fd5\u6a5f\n  server.sendHeader(\"Location\", \"\/\");\n  server.send(303);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleOff()     \/\/ \u624b\u52d5\u505c\u6b62\u9664\u6fd5\u6a5f\n{\n  mode = true;        \/\/ \u5207\u5230\u624b\u52d5\u6a21\u5f0f\n  ledState = false;   \/\/ \u95dc\u9589\u9664\u6fd5\u6a5f\n  server.sendHeader(\"Location\", \"\/\");\n  server.send(303);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleAuto()    \/\/ \u5207\u63db\u81ea\u52d5\u6a21\u5f0f\n{\n  mode = false;       \/\/ \u5207\u56de\u81ea\u52d5\u6a21\u5f0f\n  server.sendHeader(\"Location\", \"\/\");\n  server.send(303);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleStatus()  \/\/ \u66f4\u65b0\u72c0\u614b\u8a0a\u606f\n{\n  String json = \"{\";\n  json += \"\\\"humidity\\\":\" + String(h, 1) + \",\";\n  json += \"\\\"tempC\\\":\" + String(t, 1) + \",\";\n  json += \"\\\"tempF\\\":\" + String(f, 1) + \",\";\n  json += \"\\\"heatIndexC\\\":\" + String(hic, 1) + \",\";\n  json += \"\\\"heatIndexF\\\":\" + String(hif, 1) + \",\";\n  json += \"\\\"dehumidifier\\\":\\\"\" + String(ledState ? \"\u904b\u8f49\u4e2d\" : \"\u505c\u6b62\") + \"\\\",\";\n  json += \"\\\"mode\\\":\\\"\" + String(mode ? \"\u624b\u52d5\" : \"\u81ea\u52d5\") + \"\\\"\";\n  json += \"}\";\n  server.send(200, \"application\/json\", json);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void handleNotFound()  \/\/ \u627e\u4e0d\u5230\u7db2\u9801\n{\n  String html = \"&lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\u627e\u4e0d\u5230\u7db2\u9801\";\n  server.send(404, \"text\/html; charset=UTF-8\", html);\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void webServerSetup()  \/\/ WebServer\u8a2d\u5b9a\n{\n  server.on(\"\/\", handleRoot);         \/\/ \u9996\u9801\n  server.on(\"\/on\", handleOn);         \/\/ \u624b\u52d5\u555f\u52d5\u9664\u6fd5\u6a5f\n  server.on(\"\/off\", handleOff);       \/\/ \u624b\u52d5\u505c\u6b62\u9664\u6fd5\u6a5f\n  server.on(\"\/status\", handleStatus); \/\/ \u66f4\u65b0\u72c0\u614b\u8a0a\u606f\n  server.on(\"\/auto\", handleAuto);     \/\/ \u5207\u63db\u81ea\u52d5\u6a21\u5f0f\n  server.onNotFound(handleNotFound);  \/\/ \u627e\u4e0d\u5230\u7db2\u9801\n  server.begin();                     \/\/ \u555f\u52d5webServer\n  Serial.println(\"Server\u5df2\u555f\u52d5\");      \/\/ \u5370\u51fa\u63d0\u793a\u6587\u5b57\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\ninline void webServerHandle()   \/\/ \u76e3\u807d\u5ba2\u6236\u7aef\u8acb\u6c42\n{\n  server.handleClient();  \/\/ \u6aa2\u67e5\u662f\u5426\u6709\u5ba2\u6236\u7aef\u5411ESP32 WebServer\u767c\u9001\u8acb\u6c42\n}\n\/\/-------------------------------------------------------------------------------------------------------------------------\n#endif<\/code><\/pre>\n\n\n\n<pre title=\"\u3008\u9664\u6fd5\u6a5f\u6a21\u64ec\u7cfb\u7d71\u3009\u7a0b\u5f0f\u67b6\u69cb\" class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/-----------------------------------------------------------------------\nconst int ledPin = 2;       \/\/ LED \u6a21\u64ec\u9664\u6fd5\u6a5f\nbool ledState = false;      \/\/ LED(\u9664\u6fd5\u6a5f)\u72c0\u614b\nbool mode = false;          \/\/ \u63a7\u5236\u6a21\u5f0f\uff0cfalse = \u81ea\u52d5(auto), true = \u624b\u52d5(manual)\n\/\/-----------------------------------------------------------------------\n#include \"wifi_setup.h\"     \/\/ \u5f15\u7528 \"wifi_setup.h\"\n\/\/-----------------------------------------------------------------------\n#include \"dht_setup.h\"      \/\/ \u5f15\u7528 \"dht_setup.h\"\n\/\/-----------------------------------------------------------------------\n#include \"web_setup.h\"      \/\/ \u5f15\u7528 \"web_setup.h\"\n\/\/-----------------------------------------------------------------------\nunsigned long previousMillis = 0;    \/\/ \u524d\u4e00\u6b21\u7684millis()\u6642\u9593\nconst long interval = 2000;          \/\/ \u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n\/\/-----------------------------------------------------------------------\n\nvoid setup() {\n  \/\/---------------------------------------------------\n  pinMode(ledPin, OUTPUT);  \/\/ \u8a2d\u5b9aLED\u70ba\u8f38\u51fa\u8173\uff0c\u6a21\u64ec\u9664\u6fd5\u6a5f\n  \/\/---------------------------------------------------\n  Serial.begin(9600);       \/\/ \u555f\u7528\u4e32\u5217\u57e0\u76e3\u770b\u8996\u7a97\n  \/\/---------------------------------------------------\n  WiFi.mode(WIFI_AP_STA);   \/\/ \u8a2d\u5b9a\u70ba\u6df7\u5408\u6a21\u5f0f\n  \/\/---------------------------------------------------\n  connect_to_wifi();        \/\/ \u9023\u7dda\u5230WiFi\n  \/\/------------------- softAP\u8a2d\u5b9a --------------------\n  startAP();                \/\/ \u555f\u7528\u71b1\u9ede\n  WiFi.onEvent(WiFiEvent);  \/\/ \u555f\u7528WiFi\u4e8b\u4ef6\u8655\u7406\n  listConnectedStations();  \/\/ \u5370\u51fa\u5df2\u9023\u7dda\u88dd\u7f6e\u6e05\u55ae   \n  \/\/---------------------------------------------------\n  dht.begin();              \/\/ \u555f\u7528dht\u7269\u4ef6\uff0c\u9023\u63a5 DHT22\n  \/\/---------------------------------------------------\n  webServerSetup();         \/\/ WebServer\u8a2d\u5b9a\n  \/\/---------------------------------------------------\n}\n\nvoid loop() {\n  unsigned long currentMillis = millis();          \/\/ \u7576\u524d\u7684millis()\u6642\u9593\n  \/\/---------------------------------------------------------------------\n  if (currentMillis - previousMillis >= interval)  \/\/ \u82e5\u9054\u5230\u9810\u8a2d\u8a08\u6642\u7684\u6642\u9593\n  {\n    \/\/---------------------------------------------------\n    get_dht();    \/\/ \u6bcf\u7d93\u904e\u4e00\u500binterval\u7684\u6642\u9593\uff0c\u53d6\u5f97dht\u8cc7\u6599\n    \n    if (mode == 0)   \/\/ \u81ea\u52d5\u9664\u6fd5\u63a7\u5236\n    {\n      if (h > 75) ledState = true;\n      else if (h &lt; 50) ledState = false;\n    }\n    \n    digitalWrite(ledPin, ledState);   \/\/ LED \u6a21\u64ec\u9664\u6fd5\u6a5f\u904b\u4f5c\n    \/\/---------------------------------------------------\n    \n    previousMillis = currentMillis;   \/\/ \u66f4\u65b0\u524d\u4e00\u6b21\u7684millis()\u6642\u9593\n  }\n  \/\/---------------------------------------------------------------------\n\n  webServerHandle();        \/\/ \u76e3\u807d\u5ba2\u6236\u7aef\u8acb\u6c42\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ESP32\u4f7f\u7528WiFi\u529f\u80fd\u6642\uff0c\u67093\u7a2e\u6a21\u5f0f\uff1a \u672c\u6b21\u7df4\u7fd2\u63a1\u7528 WIFI_AP_STA \u6df7\u5408\u6a21\u5f0f\uff0c\u5e0c\u671b\u9054\u6210\u4e0b\u5217\u529f\u80fd\uff1a<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-1890","post","type-post","status-publish","format-standard","hentry","category-microcontroller-practice"],"_links":{"self":[{"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1890","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1890"}],"version-history":[{"count":39,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1890\/revisions"}],"predecessor-version":[{"id":2215,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=\/wp\/v2\/posts\/1890\/revisions\/2215"}],"wp:attachment":[{"href":"https:\/\/www.640629.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1890"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1890"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.640629.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1890"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}