ESP8266 AP模式 网页配网 arduino ide

news2025/1/18 17:23:03

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-Fi
    while (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-Fi
    while (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配置到SPIFFS
  saveWiFiCredentials(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-Fi
  ESP.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
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2278559.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国家统计局湖北调查总队副总队长张小青一行调研珈和科技农业遥感调查智能化算法

1月15日上午&#xff0c;国家统计局湖北调查总队党组成员、副总队长张小青一行莅临珈和科技开展调研。调研期间&#xff0c;张小青一行实地了解了珈和科技在自动化作物分布提取技术领域的最新成果&#xff0c;深入探讨了作物自动化处理模型在农业调查上应用的创新价值及优化方向…

基于微信小程序的电子点菜系统设计与实现(KLW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

SQL Server 导入Excel数据

1、选中指定要导入到哪个数据库&#xff0c;右键选择 》任务 》导入数据 2、数据源 选择Excel&#xff0c;点击 下一步(Next) 3、目前 选择OLE DB Provider &#xff0c;点击 下一步&#xff08;Next&#xff09; 4、默认 &#xff0c;点击 下一步&#xff08;Next&#xff09;…

【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列

Excel VBA 双列排序 功能概述 这段VBA代码实现了Excel中的双列排序功能&#xff0c;具体是&#xff1a; 跳过前3行表头先按C列数据从大到小排序在C列值相同的情况下&#xff0c;按B列从大到小排序排序时保持整行数据的完整性 流程图 #mermaid-svg-XJERemQluZlM4K8l {font-fa…

【C++】构造函数与析构函数

写在前面 构造函数与析构函数都是属于类的默认成员函数&#xff01; 默认成员函数是程序猿不显示声明定义&#xff0c;编译器会中生成。 构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的&#xff0c;关于类与对象不才在前面笔记中有详细的介绍&#xff1a;点我…

1月17日星期五今日早报简报微语报早读

1月17日星期五&#xff0c;农历腊月十八&#xff0c;早报#微语早读。 1、广东明确旅馆承担防偷拍责任&#xff1a;应确保客房没有偷窥等设备&#xff1b; 2、商务部&#xff1a;手机补贴不用交旧手机&#xff1b; 3、中国汽车工业协会&#xff1a;坚决反对拜登政府禁止使用中…

【Linux】gdb_进程概念

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

深入内核讲明白Android Binder【二】

深入内核讲明白Android Binder【二】 前言一、Binder通信内核源码整体思路概述1. 客户端向服务端发送数据流程概述1.1 binder_ref1.2 binder_node1.3 binder_proc1.4 binder_thread 2. 服务端的binder_node是什么时候被创建的呢&#xff1f;2.1 Binder驱动程序为服务创建binder…

记录一次微信小程序使用云能力开发的过程

对于开发微信小程序云开发不知从何起的同学们&#xff0c;可以当作一次参考。虽说官方有文档&#xff0c;有模板示例&#xff0c;但是这些都是片段或者完整的结果展示。对于初学或者开发经验较少的同学们&#xff0c;可能不知先从那里入手进行第一步的开发。下面解析下构建微信…

初学stm32 --- SPI驱动25Q128 NOR Flash

目录 SPI介绍 SPI结构框图介绍 SPI外设对应的引脚 SPI数据发送与接收 SPI工作原理 SPI 全双工模式的通信机制 从机返回主机之前保存的数据 SPI工作模式介绍 SPI相关寄存器介绍&#xff08;F1 / F4 / F7&#xff09; SPI控制寄存器1&#xff08;SPI_CR1&#xff09; SPI状…

数据库基础练习1(创建表,设置外键,检查,不为空,主键等约束)安装mysql详细步骤

安装MySQL详细步骤 1. 下载 MySQL 安装程序 访问 MySQL 官方网站&#xff1a;MySQL Downloads。在下载页面&#xff0c;选择 "MySQL Community (GPL) Downloads"。在 "MySQL Community Server" 部分&#xff0c;根据你的操作系统&#xff08;Windows&…

[c语言日寄](bit)位检查——初探字节之下

哈喽大家好啊&#xff0c;在今天的快乐刷题中&#xff0c;我遇到了一个很有意思的题目&#xff1a; 题目 统计二进制中1的个数 基本思路 没错……这道题的对象比较特殊。 不同于过去常见的题目&#xff0c;之前的题目的对象都是基本数据类型&#xff0c;而这道题的对象却是…

基于SpringCloud的广告系统设计与实现(一)

一、广告系统概论 广告系统中计费方式&#xff1a;CPM 千次广告展现收费/CPT 按时间段/CPC用户点击类广告收费。 Mysql&#xff1a;进行广告数据的存储&#xff0c;以及检索系统监听Mysql做增量索引 Kafka:实现各微服务之间的通信 比如地域维度&#xff0c;时间维度 二、微服务…

React Native的现状与未来:从发展到展望

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Python在多个Excel文件中找出缺失数据行数多的文件

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;基于其中每一个文件内、某一列数据的特征&#xff0c;对其加以筛选&#xff0c;并将符合要求与不符合要求的文件分别复制到另外两个新的文件夹中的方法。 首先&#xff0c;我们来明确一下本…

【JSqlParser】Java使用JSqlParser解析SQL语句总结

简述 Java解析SQL语句有很多工具都可以做到&#xff0c;比如Mybatis、Druid、目前用来用去最全面的仍然是Jsqlparser&#xff0c;它是一个Github上的开源项目&#xff0c;JSqlParser是一个用于解析SQL语句的Java库&#xff0c;它可以帮助开发者分析和操作SQL语句的结构。无论是…

WINFORM - DevExpress -> alertControl1提示信息框

第一个按钮为常规按钮, 单击触发 ButtonClick 事件. 第二个按钮有选中和未选中状态. 单击触发 ButtonDownChanged 事件。 if (e.ButtonName "alertButton2") { } 在dev用户界面中进行提示(usecontrolwinform) AlertInfo info new AlertInfo("提示",…

springboot全局异常处理示例

这种错误交给前端无法处理。 需要自定义一些错误响应类给前端 package cn.yam.bloomfilter.exception;import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.ht…

Windows远程桌面网关出现重大漏洞

微软披露了其Windows远程桌面网关&#xff08;RD Gateway&#xff09;中的一个重大漏洞&#xff0c;该漏洞可能允许攻击者利用竞争条件&#xff0c;导致拒绝服务&#xff08;DoS&#xff09;攻击。该漏洞被标识为CVE-2025-21225&#xff0c;已在2025年1月的补丁星期二更新中得到…

Shell正则表达式与文本处理三剑客(grep、sed、awk)

一、正则表达式 Shell正则表达式分为两种&#xff1a; 基础正则表达式&#xff1a;BRE&#xff08;basic regular express&#xff09; 扩展正则表达式&#xff1a;ERE&#xff08;extend regular express&#xff09;&#xff0c;扩展的表达式有、?、|和() 1.1 基本正则表…