目录

  • 前言
  • Web配网详解
  • 强制门户详解
  • 完整代码
  • 实验效果

前言

1.Web配网概述
在应用到esp8266的场景,往往与wifi是离不开的,但用户的wifi账号密码又无从知晓,于是乎有了配网。
目前,市面上的配网方式多种多样,但其中博主觉得成功率最高,最方便的方式其实还是Web配网(个人看法),因为Web配网从根本来说就是esp8266开启一个web服务器,在此基础上进行信息交互(POST,GET),所以信息的传输较为稳定,配网成功率高。
2.强制门户概述
强制门户:连接上wifi以后,手机会自动打开一个网页,这就是强制门户。
相信大家遇见过很多拥有免费wifi的地方,连接上wifi以后,就会自动弹出认证界面,在Web配网的基础上,我们加上强制门户,就可以实现连接wifi以后自动打开配网界面,方便用户操作。

Web配网详解

想要实现Web配网,就需要让esp8266开启一个WebServer服务器,需要用到以下函数

ESP8266WebServer();//创建WebServer
begin();//启动WebServer
on();//请求响应回调
onNotFound();//无法响应的请求的回调函数
send();//发送响应数据
hasArg();//是否存在某个参数
args();//获取参数个数

具体WebServer实现代码

const char* AP_NAME = "配网WIFI";//wifi名字
//html网页源码
const char* page_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\<meta charset='UTF-8'>\r\n\<meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\<title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\<form name='input' action='/' method='POST'>\r\n\wifi名称: <br>\r\n\<input type='text' name='ssid'><br>\r\n\wifi密码:<br>\r\n\<input type='text' name='password'><br>\r\n\<input type='submit' value='保存'>\r\n\</form>\r\n\
</body>\r\n\
</html>\r\n\
";IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址
ESP8266WebServer server(80);//创建WebServervoid initBasic(void){//初始化基础Serial.begin(115200);WiFi.hostname("Smart-ESP8266");//设置ESP8266设备名
}void initSoftAP(void){//初始化AP模式WiFi.mode(WIFI_AP);WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));if(WiFi.softAP(AP_NAME)){Serial.println("ESP8266 SoftAP is right");}
}void handleRoot() {//访问主页回调函数server.send(200, "text/html", page_html);
}void handleRootPost() {//Post回调函数Serial.println("handleRootPost");if (server.hasArg("ssid")) {//判断是否有账号参数Serial.print("got ssid:");strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中Serial.println(sta_ssid);} else {//没有参数Serial.println("error, not found ssid");server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");//返回错误页面return;}//密码与账号同理if (server.hasArg("password")) {Serial.print("got password:");strcpy(sta_password, server.arg("password").c_str());Serial.println(sta_password);} else {Serial.println("error, not found password");server.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");return;}server.send(200, "text/html", "<meta charset='UTF-8'>保存成功");//返回保存成功页面delay(2000);//连接wificonnectNewWifi();
}void initWebServer(void){//初始化WebServerserver.on("/", HTTP_GET, handleRoot);//设置主页回调函数server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数server.begin();//启动WebServerSerial.println("WebServer started!");
}void connectNewWifi(void){WiFi.mode(WIFI_STA);//切换为STA模式WiFi.setAutoConnect(true);//设置自动连接WiFi.begin();//连接上一次连接成功的wifiSerial.println("");Serial.print("Connect to wifi");int count = 0;while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}if(WiFi.status() == WL_CONNECTED){//如果连接上 就输出IP信息 防止未连接上break后会误输出Serial.println("");Serial.println("WIFI Connected!");Serial.print("IP address: ");Serial.println(WiFi.localIP());server.stop();}
}void setup() {initBasic();initSoftAP();initWebServer();
}void loop() {server.handleClient();dnsServer.processNextRequest();
}

强制门户详解

要想实现强制门户,就要在以上的普通Web配网的基础上加上DNS服务。
具体实现思路:当手机连接上一个无需密码的wifi后(看上面的initSoftAP就可以发现设置的是无需密码的AP),会访问一个手机内部的网址去查看是否可以上网,在访问此网址的时候会先发起DNS请求,向服务器问域名的IP地址。然后再发起HTTP请求,请求想要的内容。

esp8266充当AP的角色,会收到手机发来的DNS请求,这时将请求的IP地址指向esp8266的地址就可以了。这时手机就会向esp8266发送http请求,esp8266不管收到什么http请求,都将html页面回复过去,就可以实现强制门户功能了。
将请求IP指向esp8266地址代码:

DNSServer dnsServer;//创建dnsServer实例
IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址
const byte DNS_PORT = 53;//DNS端口号dnsServer.start(DNS_PORT, "*", apIP)

不管收到什么http请求,都将html页面回复过去

  ESP8266WebServer server(80);//创建WebServer//server.on("/",handleRoot);//上面那行必须在第二个参数上添加上HTTP_GET才能不影响强制门户,防止有些设备无法弹出强制门户,要用域名访问,如果不加第二个参数,就只能实现域名访问而无法强制门户//在无法响应的http请求响应回调设置为主页的回调函数,才可以强制门户server.on("/", HTTP_GET, handleRoot);//设置主页回调函数server.onNotFound(handleRoot);//设置无法响应的http请求的回调函数server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数server.begin();//启动WebServer

完整代码

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>const char* AP_NAME = "配网WIFI";//wifi名字
//暂时存储wifi账号密码
char sta_ssid[32] = {0};
char sta_password[64] = {0};
//配网页面代码
const char* page_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\<meta charset='UTF-8'>\r\n\<meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\<title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\<form name='input' action='/' method='POST'>\r\n\wifi名称: <br>\r\n\<input type='text' name='ssid'><br>\r\n\wifi密码:<br>\r\n\<input type='text' name='password'><br>\r\n\<input type='submit' value='保存'>\r\n\</form>\r\n\
</body>\r\n\
</html>\r\n\
";const byte DNS_PORT = 53;//DNS端口号
IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址
DNSServer dnsServer;//创建dnsServer实例
ESP8266WebServer server(80);//创建WebServervoid handleRoot() {//访问主页回调函数server.send(200, "text/html", page_html);
}void handleRootPost() {//Post回调函数Serial.println("handleRootPost");if (server.hasArg("ssid")) {//判断是否有账号参数Serial.print("got ssid:");strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中Serial.println(sta_ssid);} else {//没有参数Serial.println("error, not found ssid");server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");//返回错误页面return;}//密码与账号同理if (server.hasArg("password")) {Serial.print("got password:");strcpy(sta_password, server.arg("password").c_str());Serial.println(sta_password);} else {Serial.println("error, not found password");server.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");return;}server.send(200, "text/html", "<meta charset='UTF-8'>保存成功");//返回保存成功页面delay(2000);//连接wificonnectNewWifi();
}void initBasic(void){//初始化基础Serial.begin(115200);WiFi.hostname("Smart-ESP8266");//设置ESP8266设备名
}void initSoftAP(void){//初始化AP模式WiFi.mode(WIFI_AP);WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));if(WiFi.softAP(AP_NAME)){Serial.println("ESP8266 SoftAP is right");}
}void initWebServer(void){//初始化WebServer//server.on("/",handleRoot);//上面那行必须以下面这种格式去写否则无法强制门户server.on("/", HTTP_GET, handleRoot);//设置主页回调函数server.onNotFound(handleRoot);//设置无法响应的http请求的回调函数server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数server.begin();//启动WebServerSerial.println("WebServer started!");
}void initDNS(void){//初始化DNS服务器if(dnsServer.start(DNS_PORT, "*", apIP)){//判断将所有地址映射到esp8266的ip上是否成功Serial.println("start dnsserver success.");}else Serial.println("start dnsserver failed.");
}void connectNewWifi(void){WiFi.mode(WIFI_STA);//切换为STA模式WiFi.setAutoConnect(true);//设置自动连接WiFi.begin();//连接上一次连接成功的wifiSerial.println("");Serial.print("Connect to wifi");int count = 0;while (WiFi.status() != WL_CONNECTED) {delay(500);count++;if(count > 10){//如果5秒内没有连上,就开启Web配网 可适当调整这个时间initSoftAP();initWebServer();initDNS();break;//跳出 防止无限初始化}Serial.print(".");}Serial.println("");if(WiFi.status() == WL_CONNECTED){//如果连接上 就输出IP信息 防止未连接上break后会误输出Serial.println("WIFI Connected!");Serial.print("IP address: ");Serial.println(WiFi.localIP());//打印esp8266的IP地址server.stop();}
}void setup() {initBasic();connectNewWifi();
}void loop() {server.handleClient();dnsServer.processNextRequest();
}

实验效果


如果有什么不懂的可以评论咨询,看到会回复,欢迎讨论!

ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)相关推荐

  1. 用esp8266实现强制门户(连接WiFi自动打开网页)

    1.首先你准备材料 一块Esb8266 NodeMCU CH340开发版(淘宝十几块钱买一个)一块0.96寸OLED 屏幕(4针)4根杜邦线电脑 这个是我用esp8266做的一个小时钟 2.有了材料后 ...

  2. ESP8266Web配网(连接wifi自动打开网页)

    前言 1.Web配网概述 在应用到esp8266的场景,往往与wifi是离不开的,但用户的wifi账号密码又无从知晓,于是乎有了配网. 目前,市面上的配网方式多种多样,但其中博主觉得成功率最高,最方便 ...

  3. ESP32 强制门户 WEB配网

    修改自此博主代码 参考博客 参考WEB配网的网页代码 ESP32学习笔记(23)--NVS(非易失性存储)接口使用 目录 前言 一.工程创建 1.获取源代码 2.新建一个ESP32的工程 3.移植代码 ...

  4. ESP8266开发之旅 网络篇⑭ web配网

    文章目录 1. 前言 2. Web配网(AP配网) 2.1 自定义AP配网 2.2 WiFiManager 3. 总结 授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大 ...

  5. 验证可用的ESP32/8266配网方式,开源代码,web配网,smartconfig配网

    web配网 设备内做了个小web服务器通过网页交换SSID和PWD.这个方式比较友好,不依赖外部app或小程序,保密性更好,产品可用性更好(苹果等个别手机不能打开配网页面可直接浏览器登陆192.168 ...

  6. ESP8266 SmartConfig一键配网

    ESP8266 SmartConfig一键配网   Wi-Fi 配网,指由外部向 Wi-Fi 设备提供 SSID 和密码(PSW),让 Wi-Fi 设备可以连接指定的热点或路由器,并加入后者所建立的 ...

  7. ESP8266_21基于ESP8266的一键配网

    ESP8266_01搭建开发环境 ESP8266_02程序的编译与下载 ESP8266_03SDK与Makefile的基本用法 ESP8266_04管脚控制与软件定时器 ESP8266_05 ESP8 ...

  8. ESP8266微信一键配网smartconfig,esp32可用

    ESP8266微信一键配网 第一步 下载程序 微信配网 恢复出厂设置 ESP32 接入 第一步 下载程序 简单配网例程:点击下载 配网并控制LED例程:点击下载 例程下载后,需要使用arduino i ...

  9. ESP8266 web配网微信小程序配网 全平台配网库 arduino 傻瓜式通用库

    wifi_link_tool esp8266通用配网库 (arduino) 库地址:点击进入GitHub 这是一个为esp8266设计的通用配网库 该库免费提供 使用请注明出处 允许毕业设计使用本库 ...

最新文章

  1. 如何显示jQuery中的加载微调器?
  2. python 画log曲线
  3. 手写简版spring --9--对象作用域和FactoryBean
  4. boost::mpl模块实现is_placeholder相关的测试程序
  5. python find函数_Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案
  6. 语音信号处理基础(四)—语音编辑
  7. redis介绍和安装
  8. Java线程池 面试考点
  9. 重庆医科大学赵浏阳教授招收博士、招聘博士后
  10. 迪士尼挖角波士顿动力,耗时3年打造漫威英雄机器人,1:1复刻效果堪比CG
  11. 初探强化学习(7)基于模型的强化学习的应用综述
  12. 度过漫长又艰辛的 2020 年,我收集了 1273 人的年度感悟
  13. Java--网络编程(利用TCP实现简单的双人聊天)
  14. 问题解决:Excel中依据某一列数据进行匹配
  15. 大数据学习之环境构建
  16. 单片机DAC输出方波简易实验
  17. 在IOS设备上调试(真机调试)
  18. 最全Pycharm教程(2)——代码风格
  19. 周志华老师报告Boasting 25years
  20. 维基解密网站总编辑身世被解密

热门文章

  1. 操作系统进程调度算法——吸烟者问题
  2. 电脑技巧:电脑键盘F1~F12按键的妙用
  3. 造个轮子,动手实现一个复杂场景的表格组件(UniApp)
  4. 如何使用OBS开启直播
  5. 指法练习软件ECAI使用指南
  6. vue push html,html5 - Vue 2.0 javaScript 数组循环push json 对象问题
  7. js中怎样把ASCII码中的字符与十进制的数相互转换-学习笔记
  8. 【文件包含漏洞03】文件包含漏洞的空字符绕过及六种利用方式
  9. Hadoop3.x版本安装及其应用部署
  10. php表格弄成隔两行变色,Excel表格实现隔行填充背景颜色的三种方法