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 条件编译 程序的翻译环境和执行环…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
flow_controllers
关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...