ESP8266 AP模式 网页配网 arduino ide
ESP8266的AP配网,可以自行配置网络,一个简单的demo,文档最后有所有的代码,已经测试通过.
查看SPIFFS文件管理系统中的文件 账号密码是否存在,如不存在进入AP配网,如存在进入wifi连接模式
// 检查Wi-Fi凭据if (isWiFiConfigured()) {Serial.println("找到Wi-Fi凭据,尝试连接Wi-Fi...");String ssid = loadWiFiSSID();String pass = loadWiFiPassword();WiFi.begin(ssid.c_str(), pass.c_str());unsigned long startAttemptTime = millis();// 等待最多15秒来连接Wi-Fiwhile (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < wifiConnectTimeout) {delay(100);Serial.print(".");}if (WiFi.status() == WL_CONNECTED) {Serial.println("Wi-Fi连接成功!");Serial.print("IP地址: ");Serial.println(WiFi.localIP());} else {Serial.println("Wi-Fi连接失败,进入AP模式...");startAPMode();}} else {Serial.println("未找到Wi-Fi凭据,进入AP模式...");startAPMode();}// 设置Web服务器路由server.on("/", HTTP_GET, handleRoot);server.on("/save", HTTP_POST, handleSaveWiFi);// 启动Web服务器server.begin();
}
启用AP模式
// 启动AP模式,供用户配置Wi-Fi
void startAPMode() {WiFi.softAP(ap_ssid, ap_password);Serial.print("AP模式启动,IP地址:");Serial.println(WiFi.softAPIP());
}
AP配网的网页端代码(这个是直接写入,没有采用SPIFFS管理)
// 网页表单HTML
const char* htmlForm = R"rawliteral(<html><head><title>Wi-Fi 配置</title></head><body><h2>请输入Wi-Fi配置</h2><form action="/save" method="POST"><label for="ssid">SSID:</label><br><input type="text" id="ssid" name="ssid" required><br><br><label for="pass">密码:</label><br><input type="password" id="pass" name="pass" required><br><br><input type="submit" value="保存配置"></form></body></html>
)rawliteral";
总代码(先进入AP配网,将wifi密码输入上去后进入wifi模式,可连接自己的wifi)
// 检查是否有保存的Wi-Fi凭据
bool isWiFiConfigured() {File ssidFile = SPIFFS.open(WIFI_SSID_FILE, "r");File passFile = SPIFFS.open(WIFI_PASS_FILE, "r");return ssidFile && passFile; // 如果两个文件都存在,返回true
}
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>const char* ap_ssid = "ESP8266-Config";
const char* ap_password = "";
const unsigned long wifiConnectTimeout = 20000; // 20秒超时ESP8266WebServer server(80);#define WIFI_SSID_FILE "/wifi_ssid.txt"
#define WIFI_PASS_FILE "/wifi_pass.txt"// 网页表单HTML
const char* htmlForm = R"rawliteral(<html><head><title>Wi-Fi 配置</title></head><body><h2>请输入Wi-Fi配置</h2><form action="/save" method="POST"><label for="ssid">SSID:</label><br><input type="text" id="ssid" name="ssid" required><br><br><label for="pass">密码:</label><br><input type="password" id="pass" name="pass" required><br><br><input type="submit" value="保存配置"></form></body></html>
)rawliteral";void setup() {Serial.begin(115200);delay(1000); // 等待串口初始化// 初始化SPIFFS文件系统if (!SPIFFS.begin()) {Serial.println("文件系统初始化失败!");return;}// 检查Wi-Fi凭据if (isWiFiConfigured()) {Serial.println("找到Wi-Fi凭据,尝试连接Wi-Fi...");String ssid = loadWiFiSSID();String pass = loadWiFiPassword();WiFi.begin(ssid.c_str(), pass.c_str());unsigned long startAttemptTime = millis();// 等待最多15秒来连接Wi-Fiwhile (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < wifiConnectTimeout) {delay(100);Serial.print(".");}if (WiFi.status() == WL_CONNECTED) {Serial.println("Wi-Fi连接成功!");Serial.print("IP地址: ");Serial.println(WiFi.localIP());} else {Serial.println("Wi-Fi连接失败,进入AP模式...");startAPMode();}} else {Serial.println("未找到Wi-Fi凭据,进入AP模式...");startAPMode();}// 设置Web服务器路由server.on("/", HTTP_GET, handleRoot);server.on("/save", HTTP_POST, handleSaveWiFi);// 启动Web服务器server.begin();
}void loop() {server.handleClient();
}// 启动AP模式,供用户配置Wi-Fi
void startAPMode() {WiFi.softAP(ap_ssid, ap_password);Serial.print("AP模式启动,IP地址:");Serial.println(WiFi.softAPIP());
}// 显示Wi-Fi配置页面
void handleRoot() {server.send(200, "text/html", htmlForm);
}// 保存Wi-Fi配置
void handleSaveWiFi() {String ssid = server.arg("ssid");String pass = server.arg("pass");// 保存Wi-Fi配置到SPIFFSsaveWiFiCredentials(ssid.c_str(), pass.c_str());// 返回保存成功的页面String response = "<html><body><h2>Wi-Fi配置已保存!</h2>";Serial.println("Wi-Fi配置已保存!");response += "<p>SSID: " + ssid + "</p>";response += "<p>密码: " + pass + "</p>";response += "</body></html>";server.send(200, "text/html", response);// 保存后重启设备以连接Wi-FiESP.restart();
}// 保存Wi-Fi凭据到SPIFFS
void saveWiFiCredentials(const char* ssid, const char* pass) {File ssidFile = SPIFFS.open(WIFI_SSID_FILE, "w");File passFile = SPIFFS.open(WIFI_PASS_FILE, "w");if (ssidFile) {ssidFile.print(ssid);ssidFile.close();} else {Serial.println("保存SSID失败");}if (passFile) {passFile.print(pass);passFile.close();} else {Serial.println("保存密码失败");}
}// 加载保存的Wi-Fi SSID
String loadWiFiSSID() {File ssidFile = SPIFFS.open(WIFI_SSID_FILE, "r");if (!ssidFile) {Serial.println("无法读取SSID");return "";}String ssid = ssidFile.readString();Serial.print("SSID: ");Serial.println(ssid);ssidFile.close();return ssid;
}// 加载保存的Wi-Fi密码
String loadWiFiPassword() {File passFile = SPIFFS.open(WIFI_PASS_FILE, "r");if (!passFile) {Serial.println("无法读取密码");return "";}String pass = passFile.readString();Serial.print("Password: ");Serial.println(pass);passFile.close();return pass;
}// 检查是否有保存的Wi-Fi凭据
bool isWiFiConfigured() {File ssidFile = SPIFFS.open(WIFI_SSID_FILE, "r");File passFile = SPIFFS.open(WIFI_PASS_FILE, "r");return ssidFile && passFile; // 如果两个文件都存在,返回true
}
相关文章:
ESP8266 AP模式 网页配网 arduino ide
ESP8266的AP配网,可以自行配置网络,一个简单的demo,文档最后有所有的代码,已经测试通过. 查看SPIFFS文件管理系统中的文件 账号密码是否存在,如不存在进入AP配网,如存在进入wifi连接模式 // 检查Wi-Fi凭据if (isWiFiConfigured()) {Serial.println("找到Wi-Fi凭据&#…...

OpenCV基础:获取子矩阵的几种方式
目录 相关阅读 方法一:使用切片操作 方法二:使用高级索引 方法三:使用条件筛选 方法四:使用 numpy 的 take 函数 相关阅读 OpenCV基础:矩阵的创建、检索与赋值-CSDN博客 OpenCV基础:图像运算-CSDN博客…...
C++ 之多线程相关总结
C 之多线程相关总结 1.多线程相关基础知识 1.1 线程的创建和管理 1. std::thread 类: 用于创建和管理线程。通过将可调用对象(如函数、函数对象、lambda 表达式)作为参数传递给 std::thread 的构造函数,可以创建一个新的线程。…...

EF Core全局查询筛选器
目录 概述 用法 添加全局查询筛选器 禁用全局查询筛选器 概述 全局查询筛选器:EF Core 会自动将这个查询筛选器应用于涉及这个实体类型的所有 LINQ 查询。 场景:软删除、多租户。 什么是软删除? 逻辑删除,并不是真正地从数…...

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)
本文项目编号 T 141 ,文末自助获取源码 \color{red}{T141,文末自助获取源码} T141,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
Objective-C语言的数据库交互
Objective-C语言的数据库交互 引言 在现代应用程序开发过程中,数据库在数据存储和管理方面起着至关重要的作用。对于iOS应用开发者而言,掌握如何在Objective-C中与数据库交互显得尤为重要。本文将全面探讨Objective-C的数据库交互,包括SQLi…...

基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践
在现代 Web 开发中,前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台,涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8:稳定且广泛使用的 Java 版本。 Spring…...
笔记(数据运营方向)
以下是一些在工作过程中的小笔记,写的比较杂乱,后续再进行分类~ 1、掌握sql窗口函数 窗口函数又名开窗函数,属于分析函数的一种。用于解决复杂报表统计需求的功能强大的函数。窗口函数用于计算基于组的某种聚合值,它和聚合函数的…...

qt vs ios开发应用环境搭建和上架商店的记录
qt 下载链接如下 https://download.qt.io/new_archive/qt/5.14/5.14.2/qt-opensource-mac-x64-5.14.2.dmg 安装选项全勾选就行,这里特别说明下qt5.14.2/qml qt5.14.2对qml支持还算成熟,但很多特性还得qt6才行,这里用qt5.14.2主要是考虑到服…...
[cg] glDrawBuffers MRT的应用
glDrawBuffers 是 OpenGL 中的一个函数,用于指定渲染结果输出到哪些颜色缓冲区。它通常在多渲染目标(MRT, Multiple Render Targets)中使用,允许一个渲染操作同时将结果输出到多个颜色缓冲区,而不是默认情况下的单个颜…...

IO模型与NIO基础二
抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和res…...

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
单例模式 作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全,调用效率高 ,但是不能延迟加载懒汉式线程安全,调用效率不高,能延迟加载双重检…...
T-SQL语言的数据库交互
T-SQL语言的数据库交互 引言 随着信息技术的不断发展,数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL(Transact-SQL)作为微软SQL Server的重要扩展语言…...

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)
inode 和 block 的映射 该博文中有详细解释:【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题: 问题一: 我们访问文件,都是用的文件名,没用过 inode 号啊? 之前总是说可以通过一个…...

慧集通(DataLinkX)iPaaS集成平台-业务建模之域
通过左侧导航菜单〖业务建模〗→〖域〗,进入该界面;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面,点击【新建】按钮进入新建页面;输入编码,名称、模块以及对应数据类…...
【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题
【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络,通过对抗生成网络生成少数类样本,平衡欺诈数据中正类样本极…...
android wifi framework与wpa_supplicant的交互
android frmework直接与wpa_supplicant进行交互,使用aidl或者hidl 二、事件 framework注册事件的地方: packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...

初学stm32 --- flash模仿eeprom
目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作
栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解
本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...