From 9a8162228d93ca0e427e058fffb7402caf67829b Mon Sep 17 00:00:00 2001 From: Wuqiyang312 Date: Tue, 13 Aug 2024 11:05:20 +0800 Subject: [PATCH] =?UTF-8?q?"=E5=9F=BA=E4=BA=8E=E6=8F=90=E4=BE=9B=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=B7=AE=E5=BC=82=EF=BC=8C=E6=9C=AC=E6=AC=A1?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=9E=84=E5=BB=BA=E4=BA=86=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E7=9A=84IoT=E9=A1=B9=E7=9B=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=EF=BC=8C=E5=8C=85=E5=90=AB=E4=BA=86PlatformIO?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E3=80=81IDE=E9=9B=86=E6=88=90=E3=80=81Web?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=92=8CWiFi=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=E5=AE=9E=E7=8E=B0=E3=80=82=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=8C=85=E6=8B=AC=E4=BD=86=E4=B8=8D=E9=99=90=E4=BA=8E?= =?UTF-8?q?.gitignore=E6=96=87=E4=BB=B6=E7=9A=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E3=80=81PlatformIO=E7=8E=AF=E5=A2=83=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E3=80=81=E6=9D=82=E9=A1=B9=E9=85=8D=E7=BD=AE=E3=80=81=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E3=80=81=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E9=85=8D=E7=BD=AE=E3=80=81=E4=BB=A3=E7=A0=81=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=AD=89=E3=80=82=E6=AD=A4=E6=AC=A1=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E7=A1=AE=E4=BF=9D=E4=BA=86=E9=A1=B9=E7=9B=AE=E7=9A=84=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E8=AE=BE=E7=BD=AE=E5=AE=8C=E6=95=B4=EF=BC=8C?= =?UTF-8?q?=E4=B8=BA=E5=90=8E=E7=BB=AD=E7=9A=84=E7=89=A9=E8=81=94=E7=BD=91?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=BC=80=E5=8F=91=E6=8F=90=E4=BE=9B=E4=BA=86?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E3=80=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .idea/.gitignore | 8 ++ .idea/deployment.xml | 83 ++++++++++++ .idea/misc.xml | 17 +++ .idea/vcs.xml | 6 + html/index.html | 98 ++++++++++++++ include/README | 39 ++++++ lib/README | 46 +++++++ platformio.ini | 14 ++ src/component/nonBlocking.cpp | 13 ++ src/component/nonBlocking.h | 11 ++ src/component/wifi.cpp | 243 ++++++++++++++++++++++++++++++++++ src/component/wifi.h | 32 +++++ src/config.cpp | 24 ++++ src/config.h | 28 ++++ src/main.cpp | 15 +++ src/main.h | 10 ++ test/README | 11 ++ 18 files changed, 699 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/deployment.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 html/index.html create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/component/nonBlocking.cpp create mode 100644 src/component/nonBlocking.h create mode 100644 src/component/wifi.cpp create mode 100644 src/component/wifi.h create mode 100644 src/config.cpp create mode 100644 src/config.h create mode 100644 src/main.cpp create mode 100644 src/main.h create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..662f08c --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d858eb1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..ea2da5f --- /dev/null +++ b/html/index.html @@ -0,0 +1,98 @@ + + + + + + ESP32-wifi配置页面 + + + +
+
+

ESP32 AP

+

wifi配置页面

+
+
+
+

选择WIFI:

+ +
+ + + + + + + + + + + + +
名称信号(RSSI)是否需要密码操作
+
+
+ + + \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..4b30716 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,14 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino diff --git a/src/component/nonBlocking.cpp b/src/component/nonBlocking.cpp new file mode 100644 index 0000000..85ace88 --- /dev/null +++ b/src/component/nonBlocking.cpp @@ -0,0 +1,13 @@ +// +// Created by wuqiyang on 24-8-9. +// +#include "nonBlocking.h" + +void runEveryInterval(void (*function)(), unsigned long *previousMillis, long interval) { + // 判断当前时间与上一次调用的时间间隔是否达到了设定的间隔时间 + if (nowMillis - *previousMillis >= interval) { + // 如果达到了间隔时间,更新上一次调用的时间为当前时间 + *previousMillis = nowMillis; + function(); + } +} \ No newline at end of file diff --git a/src/component/nonBlocking.h b/src/component/nonBlocking.h new file mode 100644 index 0000000..def3df2 --- /dev/null +++ b/src/component/nonBlocking.h @@ -0,0 +1,11 @@ +// +// Created by wuqiyang on 24-8-9. +// + +#ifndef ESPT0_NONBLOCKING_H +#define ESPT0_NONBLOCKING_H +#include "config.h" + +void runEveryInterval(void (*function)(), unsigned long *previousMillis, long interval); + +#endif //ESPT0_NONBLOCKING_H diff --git a/src/component/wifi.cpp b/src/component/wifi.cpp new file mode 100644 index 0000000..a150178 --- /dev/null +++ b/src/component/wifi.cpp @@ -0,0 +1,243 @@ +// +// Created by wuqiyang on 24-8-9. +// +#include "wifi.h" + +/** + * 初始化WiFi连接 + */ +void wifi_init() { +#if WIFI_CONFIG_SETUP + WiFiClass::mode(WIFI_STA); + // 连接到指定的WiFi网络 + WiFi.begin(ssid, password); + // 不断重试 + while (WiFiClass::status() != WL_CONNECT){ + delay(1000); + Serial.print("."); + } +#else + Preferences preferences; + preferences.begin("app-wifi", true); + String ssid = preferences.getString("ssid", ""); + String password = preferences.getString("password", ""); + preferences.end(); + + if (ssid.length() == 0) { + // 如果没有设置WiFi信息 打开AP模式 + wifi_ap_setup(); + } + WiFiClass::mode(WIFI_STA); + // 连接到指定的WiFi网络 + WiFi.begin(ssid, password); + + // 重试20次,如果依旧无法连接,则重新初始化Wi-Fi + // 循环直到WiFi连接成功 + for (int i = 0; i < 20; i++) { + // 每3秒检查一次WiFi状态,以减少CPU资源消耗 + delay(3000); + Serial.printf("尝试连接WiFi: %s 第%d次\n", ssid.c_str(), i + 1); + if (WiFiClass::status() == WL_CONNECTED) { + break; + } + } + if (WiFiClass::status() != WL_CONNECTED) { + // 设置WiFi信息为空串 + wifi_set_ssid_password("", ""); + // 重启 + ESP.restart(); + } +#endif + Serial.println("\nWiFi connected"); + IPAddress ip = WiFi.localIP(); + Serial.printf("IP address: %s \n", ip.toString().c_str()); +} + +/** + * wifi_loop函数用于确保Wi-Fi连接状态为已连接。 + * 如果Wi-Fi连接断开,将重新初始化Wi-Fi。 + */ +void wifi_loop() { + // 检查当前Wi-Fi连接状态,如果不处于连接状态,则调用wifi_init函数重新初始化Wi-Fi + if (WiFiClass::status() != WL_IDLE_STATUS) { + if (WiFiClass::status() != WL_CONNECTED) { + wifi_init(); + } + } +} + + +/** + * 获取当前连接情况 + * 如果没有连接,则返回等待连接成功并返回 + */ +void wifi_get_status() { + while (WiFiClass::status() != WL_CONNECTED) { + delay(1000); + } +} + +#if WIFI_CONFIG_SETUP +#else + +const byte DNS_PORT = 53; +DNSServer dnsServer; +WebServer server(80); + +// AP模式下,等待用户输入WiFi信息 +void wifi_ap_setup() { + Serial.println("WiFi AP Mode"); + WiFiClass::mode(WIFI_AP); + WiFi.softAP("ESP_AP", "12345678"); + IPAddress apIP = WiFi.softAPIP(); + dnsServer.start(DNS_PORT, "*", apIP); + + server.on("/", []() { + server.send(200, "text/html", "\n" + "\n" + "\n" + " \n" + " \n" + " ESP32-wifi配置页面\n" + " \n" + "\n" + "\n" + "
\n" + "
\n" + "

ESP32 AP

\n" + "

wifi配置页面

\n" + "
\n" + "
\n" + "
\n" + "

选择WIFI:

\n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "
名称信号(RSSI)是否需要密码操作
\n" + "
\n" + "
\n" + "\n" + "\n" + ""); + }); + server.on("/scan", []() { + String json = "["; + for (int i = 0; i < WiFi.scanNetworks(); i++) { + if (i) { + json += ","; + } + json += R"({"ssid":")" + WiFi.SSID(i) + R"(","rssi":")" + WiFi.RSSI(i) + R"(","password_required":)" + + (WiFi.encryptionType(i) != WIFI_AUTH_OPEN ? "true" : "false") + "}"; + } + json += "]"; + server.send(200, "application/json", json); + }); + server.on("/set", []() { + String ssid = server.arg("ssid"); + String password = server.arg("password"); + if (ssid.length() > 0 && password.length() > 0) { + wifi_set_ssid_password(ssid, password); + server.send(200, "text/html", "

WiFi设置成功

重新启动ESP32中

"); + delay(500); + ESP.restart(); + } else { + server.send(200, "text/html", "

WiFi设置失败

请重新输入WiFi信息。

"); + } + }); + server.onNotFound([]() { + server.sendHeader("Location", "/", true); // true参数表示进行301永久重定向 + server.send(302, "text/plain", "Redirecting to /"); + }); + + server.begin(); + Serial.println("HTTP server started"); + while (true) { + dnsServer.processNextRequest(); + server.handleClient(); + } +} + +/** + * 设置wifi的ssid和password + */ +void wifi_set_ssid_password(const String &ssid, const String &password) { + Preferences preferences; + preferences.begin("app-wifi", false); + preferences.putString("ssid", ssid); + preferences.putString("password", password); + preferences.end(); +} + +#endif \ No newline at end of file diff --git a/src/component/wifi.h b/src/component/wifi.h new file mode 100644 index 0000000..609b45d --- /dev/null +++ b/src/component/wifi.h @@ -0,0 +1,32 @@ +// +// Created by wuqiyang on 24-8-9. +// + +#ifndef ESPT0_WIFI_H +#define ESPT0_WIFI_H + +#include +#include +#include "config.h" + +void wifi_init(); + +void wifi_loop(); + +void wifi_get_status(); + +// 根据编译条件配置WIFI设置 +#if WIFI_CONFIG_SETUP +#else + +#include +#include + +void wifi_set_ssid_password(const String &ssid, const String &password); + +// 初始化Wi-Fi AP模式的设置 +void wifi_ap_setup(); + +#endif + +#endif //ESPT0_WIFI_H diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..da920fb --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,24 @@ +// +// Created by wuqiyang on 24-8-9. +// +#include +#include +#include "config.h" + +// 当前毫秒数 +unsigned long nowMillis; + +// 串口 +const int serialBaud = 9600; + +// wifi +unsigned long wifiLoopMillis; +#if WIFI_CONFIG_SETUP +const String ssid = "debian-wqy"; +const String password = "qwq@wuqiyang"; +#endif +void setupParameter() { + Serial.begin(serialBaud); + Serial.println("Hallo"); + wifiLoopMillis = millis(); +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..21336f8 --- /dev/null +++ b/src/config.h @@ -0,0 +1,28 @@ +// +// Created by wuqiyang on 24-8-9. +// + +// wifi 设置默认信息 固定配网=1 动态配网=0 +#define WIFI_CONFIG_SETUP 0 + +#ifndef ESPT0_CONFIG_H +#define ESPT0_CONFIG_H + +#include +#include "main.h" + +extern unsigned long nowMillis; +extern const int serialBaud; + +// wifi +extern unsigned long wifiLoopMillis; +// 根据WIFI_CONFIG_SETUP宏的定义情况,声明全局常量字符串ssid和password +#if WIFI_CONFIG_SETUP +extern const String ssid; +extern const String password; +#endif + + +void setupParameter(); + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ae35992 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,15 @@ +#include "main.h" +#include "config.h" +#include "component/nonBlocking.h" +#include "component/wifi.h" + +void setup() { + setupParameter(); + // wifi + wifi_init(); +} + +void loop() { + nowMillis = millis(); + runEveryInterval(wifi_loop, &wifiLoopMillis, 1000); +} \ No newline at end of file diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..e7844cb --- /dev/null +++ b/src/main.h @@ -0,0 +1,10 @@ +// +// Created by wuqiyang on 24-8-9. +// + +#ifndef ESPT0_MAIN_H +#define ESPT0_MAIN_H + +#include + +#endif //ESPT0_MAIN_H diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html