WiFiSetting.ino 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. *******************************************************************************
  3. * Copyright (c) 2022 by M5Stack
  4. * Equipped with M5Core sample source code
  5. * 配套 M5Core 示例源代码
  6. * Visit for more information: https://docs.m5stack.com/en/core/gray
  7. * 获取更多资料请访问: https://docs.m5stack.com/zh_CN/core/gray
  8. *
  9. * Describe: WiFi connect. wifi连接
  10. * Date: 2021/7/27
  11. *******************************************************************************
  12. */
  13. #include <ESPmDNS.h>
  14. #include <M5Stack.h>
  15. #include <Preferences.h>
  16. #include <WiFi.h>
  17. #include <WiFiClient.h>
  18. #include "WebServer.h"
  19. boolean restoreConfig();
  20. boolean checkConnection();
  21. void startWebServer();
  22. void setupMode();
  23. String makePage(String title, String contents);
  24. String urlDecode(String input);
  25. const IPAddress apIP(
  26. 192, 168, 4, 1); // Define the address of the wireless AP. 定义无线AP的地址
  27. const char* apSSID = "M5STACK_SETUP"; // Define the name of the created
  28. // hotspot. 定义创建热点的名称
  29. boolean settingMode;
  30. String ssidList;
  31. String wifi_ssid; // Store the name of the wireless network. 存储无线网络的名称
  32. String wifi_password; // Store the password of the wireless network.
  33. // 存储无线网络的密码
  34. // DNSServer dnsServer;. webServer的类
  35. WebServer webServer(80);
  36. // wifi config store. wifi配置存储的类
  37. Preferences preferences;
  38. void setup() {
  39. M5.begin(); // Init M5Stack. 初始化M5Stack
  40. M5.Power.begin(); // Init power 初始化电源模块
  41. M5.Lcd.setTextColor(
  42. YELLOW); // Set the font color to yellow. 设置字体颜色为黄色
  43. preferences.begin("wifi-config");
  44. delay(10);
  45. if (restoreConfig()) { // Check if wifi configuration information has been
  46. // stored. 检测是否已存储wifi配置信息
  47. if (checkConnection()) { // Check wifi connection. 检测wifi连接情况
  48. settingMode = false; // Turn off setting mode. 关闭设置模式
  49. startWebServer(); // Turn on network service. 开启网络服务
  50. return; // Exit setup(). 退出setup()
  51. }
  52. }
  53. settingMode =
  54. true; // If there is no stored wifi configuration information, turn on
  55. // the setting mode. 若没有已存储的wifi配置信息,则开启设置模式
  56. setupMode();
  57. }
  58. void loop() {
  59. if (settingMode) {
  60. }
  61. webServer
  62. .handleClient(); // Check that there is no facility to send requests to
  63. // the M5StickC Web server over the network.
  64. // 检查有没有设备通过网络向M5Stack网络服务器发送请求
  65. }
  66. boolean
  67. restoreConfig() { /* Check whether there is wifi configuration information
  68. storage, if there is 1 return, if no return 0.
  69. 检测是否有wifi配置信息存储,若有返回1,无返回0 */
  70. wifi_ssid = preferences.getString("WIFI_SSID");
  71. wifi_password = preferences.getString("WIFI_PASSWD");
  72. M5.Lcd.printf(
  73. "WIFI-SSID: %s\n",
  74. wifi_ssid); // Screen print format string. 屏幕打印格式化字符串
  75. M5.Lcd.printf("WIFI-PASSWD: %s\n", wifi_password);
  76. WiFi.begin(wifi_ssid.c_str(), wifi_password.c_str());
  77. if (wifi_ssid.length() > 0) {
  78. return true;
  79. } else {
  80. return false;
  81. }
  82. }
  83. boolean checkConnection() { // Check wifi connection. 检测wifi连接情况
  84. int count = 0; // count. 计数
  85. M5.Lcd.print("Waiting for Wi-Fi connection");
  86. while (count <
  87. 30) { /* If you fail to connect to wifi within 30*350ms (10.5s),
  88. return false; otherwise return true.
  89. 若在30*500ms(15s)内未能连上wifi,返回false;否则返回true */
  90. if (WiFi.status() == WL_CONNECTED) {
  91. M5.Lcd.printf("\nConnected!\n");
  92. return (true);
  93. }
  94. delay(350);
  95. M5.Lcd.print(".");
  96. count++;
  97. }
  98. M5.Lcd.println("Timed out.");
  99. return false;
  100. }
  101. void startWebServer() { // Open the web service. 打开Web服务
  102. if (settingMode) { // If the setting mode is on. 如果设置模式处于开启状态
  103. M5.Lcd.print("Starting Web Server at: ");
  104. M5.Lcd.print(
  105. WiFi.softAPIP()); // Output AP address (you can change the address
  106. // you want through apIP at the beginning).
  107. // 输出AP地址(可通过开头的apIP更改自己想要的地址)
  108. webServer.on(
  109. "/settings", []() { // AP web interface settings. AP网页界面设置
  110. String s =
  111. "<h1>Wi-Fi Settings</h1><p>Please enter your password by "
  112. "selecting the SSID.</p>";
  113. s += "<form method=\"get\" action=\"setap\"><label>SSID: "
  114. "</label><select name=\"ssid\">";
  115. s += ssidList;
  116. s += "</select><br>Password: <input name=\"pass\" length=64 "
  117. "type=\"password\"><input type=\"submit\"></form>";
  118. webServer.send(200, "text/html", makePage("Wi-Fi Settings", s));
  119. });
  120. webServer.on("/setap", []() {
  121. String ssid = urlDecode(webServer.arg("ssid"));
  122. M5.Lcd.printf("SSID: %s\n", ssid);
  123. String pass = urlDecode(webServer.arg("pass"));
  124. M5.Lcd.printf("Password: %s\n\nWriting SSID to EEPROM...\n", pass);
  125. // Store wifi config. 存储wifi配置信息
  126. M5.Lcd.println("Writing Password to nvr...");
  127. preferences.putString("WIFI_SSID", ssid);
  128. preferences.putString("WIFI_PASSWD", pass);
  129. M5.Lcd.println("Write nvr done!");
  130. String s =
  131. "<h1>Setup complete.</h1><p>device will be connected to \"";
  132. s += ssid;
  133. s += "\" after the restart.";
  134. webServer.send(200, "text/html", makePage("Wi-Fi Settings", s));
  135. delay(2000);
  136. ESP.restart(); // Restart MPU. 重启MPU
  137. });
  138. webServer.onNotFound([]() {
  139. String s =
  140. "<h1>AP mode</h1><p><a href=\"/settings\">Wi-Fi "
  141. "Settings</a></p>";
  142. webServer.send(200, "text/html", makePage("AP mode", s));
  143. });
  144. } else { // If the setting mode is off. 如果设置模式处于关闭状态
  145. M5.Lcd.print("Starting Web Server at ");
  146. M5.Lcd.println(WiFi.localIP());
  147. webServer.on("/", []() { // AP web interface settings. AP网页界面设置
  148. String s =
  149. "<h1>STA mode</h1><p><a href=\"/reset\">Reset Wi-Fi "
  150. "Settings</a></p>";
  151. webServer.send(200, "text/html", makePage("STA mode", s));
  152. });
  153. webServer.on("/reset", []() {
  154. // reset the wifi config
  155. preferences.remove("WIFI_SSID");
  156. preferences.remove("WIFI_PASSWD");
  157. String s =
  158. "<h1>Wi-Fi settings was reset.</h1><p>Please reset device.</p>";
  159. webServer.send(200, "text/html",
  160. makePage("Reset Wi-Fi Settings", s));
  161. delay(2000);
  162. ESP.restart();
  163. });
  164. }
  165. webServer.begin(); // Start web service. 开启web服务
  166. }
  167. void setupMode() {
  168. WiFi.mode(WIFI_MODE_STA); // Set Wi-Fi mode to WIFI_MODE_STA.
  169. // 设置Wi-Fi模式为WIFI_MODE_STA
  170. WiFi.disconnect(); // Disconnect wifi connection. 断开wifi连接
  171. delay(100);
  172. int n = WiFi.scanNetworks(); // Store the number of wifi scanned into n.
  173. // 将扫描到的wifi个数存储到n中
  174. delay(100);
  175. M5.Lcd.println("");
  176. for (int i = 0; i < n; ++i) { // Save each wifi name scanned to ssidList.
  177. // 将扫描到的每个wifi名称保存到ssidList中
  178. ssidList += "<option value=\"";
  179. ssidList += WiFi.SSID(i);
  180. ssidList += "\">";
  181. ssidList += WiFi.SSID(i);
  182. ssidList += "</option>";
  183. }
  184. delay(100);
  185. WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  186. WiFi.softAP(apSSID); // Turn on Ap mode. 开启Ap模式
  187. WiFi.mode(WIFI_MODE_AP); // Set WiFi to soft-AP mode. 设置WiFi为soft-AP模式
  188. startWebServer(); // Open the web service. 打开Web服务
  189. M5.Lcd.printf("\nStarting Access Point at \"%s\"\n\n", apSSID);
  190. }
  191. String makePage(String title, String contents) {
  192. String s = "<!DOCTYPE html><html><head>";
  193. s += "<meta name=\"viewport\" "
  194. "content=\"width=device-width,user-scalable=0\">";
  195. s += "<title>";
  196. s += title;
  197. s += "</title></head><body>";
  198. s += contents;
  199. s += "</body></html>";
  200. return s;
  201. }
  202. String urlDecode(String input) {
  203. String s = input;
  204. s.replace("%20", " ");
  205. s.replace("+", " ");
  206. s.replace("%21", "!");
  207. s.replace("%22", "\"");
  208. s.replace("%23", "#");
  209. s.replace("%24", "$");
  210. s.replace("%25", "%");
  211. s.replace("%26", "&");
  212. s.replace("%27", "\'");
  213. s.replace("%28", "(");
  214. s.replace("%29", ")");
  215. s.replace("%30", "*");
  216. s.replace("%31", "+");
  217. s.replace("%2C", ",");
  218. s.replace("%2E", ".");
  219. s.replace("%2F", "/");
  220. s.replace("%2C", ",");
  221. s.replace("%3A", ":");
  222. s.replace("%3A", ";");
  223. s.replace("%3C", "<");
  224. s.replace("%3D", "=");
  225. s.replace("%3E", ">");
  226. s.replace("%3F", "?");
  227. s.replace("%40", "@");
  228. s.replace("%5B", "[");
  229. s.replace("%5C", "\\");
  230. s.replace("%5D", "]");
  231. s.replace("%5E", "^");
  232. s.replace("%5F", "-");
  233. s.replace("%60", "`");
  234. return s;
  235. }