ESP8266-NodeMCU (3) 开发模式

1 接入点模式(Access Point)

        ESP8266自已做为一个WIFI热点向外界发出WIFI信号,其它无线终端设备(手机,笔记本电脑等)可以连入该WIFI网络

#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
 
const char *ssid = "WIFI-AP"; // 要建立的WiFi名称
 
const char *password = "12345678";  // 这里定义将要建立的WiFi密码
 
// 初始化程序
void setup() {
  Serial.begin(9600);              // 启动串口通讯(波频率9600 bit/s)
 
  WiFi.softAP(ssid, password);     // 重点。用于启动NodeMCU的AP模式(接入点模式)
                                   // 这两个参数具体内容在setup函数之前的位置进行定义。
                                   // 如果只有单参数.softAP(ssid)返回bool值,表示开启AP是否成功
  
  Serial.print("Access Point: ");    // 打印信息
  Serial.println(ssid);              
  Serial.print("IP address: ");      
  Serial.println(WiFi.softAPIP());   // 可以得到NodeMCU的IP地址(默认是192.168.4.1)
}
 
// 主循环程序(类似while(true))
void loop() { 
}

2 无线终端模式(Wireless Station)

        ESP8266可以像其它无线终端设备一样,连入WIFI网络(只可以连接2.4G网络,不能连接5G网络)

2.1 单点无线模式

#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
 
const char* ssid     = "WIFI-WS";      // 连入的WIFI名称
const char* password = "12345678";        
                                            
void setup() {
  Serial.begin(9600);             // 启动串口通讯
  
  WiFi.begin(ssid, password);                  // 重点,连接到WIFI网络
  Serial.print("Connecting to ");              
  Serial.print(ssid); Serial.println(" ..."); 
  
  int i = 0;                                   
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()返回连接状态信息,成功返回"WL_CONNECTED"
    delay(1000);                               // delay(1000)延迟1秒                    
    Serial.print(i++); Serial.println("秒");     
  }                                            
                                               
  Serial.println("");                          
  Serial.println("Connection established!");   
  Serial.print("IP address:    ");             
  Serial.println(WiFi.localIP());              // 返回被分配的局域网IP地址
}
 
void loop() {                                   
}

2.2 多点无线模式

        如果开发板在多个场景切换,需要在不同场景下连入对应WIFI,就需要设置多个密码,让开发板连入WIFI新号最强的WIFI网络

#include <ESP8266WiFi.h>          // 本程序使用ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   // 本程序使用ESP8266WiFiMulti库
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象
 
void setup() {
  Serial.begin(9600);            // 启动串口通讯
 
//通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("WIFI-WS1", "12345678");  // addAP记录多个不同的WiFi信息
  wifiMulti.addAP("WIFI-WS2", "12345678"); 
  wifiMulti.addAP("WIFI-WS3", "12345678"); 
                                                
  Serial.println("Connecting ...");         
  while (wifiMulti.run() != WL_CONNECTED) {  // 连接最强WIFI。连接成功返回“WL_CONNECTED”
    delay(1000);                             
    Serial.print('.');                       
  }                                           
  
  Serial.println('\n');                    
  Serial.print("Connected to ");            
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            
  Serial.println(WiFi.localIP());          
}
 
void loop() { 
}

3 混合开发模式

        即使采用多点无线模式连入WIFI网络,其底层原理也还是将WIFI帐号密码写死在程序中,这种方式始终是不够灵活; 混合开发模式,顾名思义,将ESP8266的两种模式结合,通过网络配置的方式动态输入WIFI帐号密码

3.1 自定义配置WIFI流程图

3.2 向闪存文件系统上传基础数据(网页,txt文件)

        wifiLogin.html

<!DOCTYPE html>
<html lang='zh-CN'>
<head>
  <meta charset='UTF-8'>
  <title>wifi</title>
</head>
<body>
<form name='input' action='/wifiLogin' method='POST'>
  wifi名称: <br>
  <input type='text' name='wifiAccount'><br>
  wifi密码:<br>
  <input type='password' name='wifiPassword'><br>
  <input type='submit' value='保存'>
</form>
</body>
</html>

        3个txt文件(account,password,ip分别保存WIFI帐号,WIFI密码,被分配的IP)

3.3 开发板代码

#include <ESP8266WiFi.h>      
#include <ESP8266WiFiMulti.h> 
#include <ESP8266WebServer.h>  
#include <FS.h>
 
const char *apAccount = "ESP8266-AP";
const char *apPassword = "12345678"; 
boolean wifiLoginFlag = 0;  // 用于标记wifi是否已经连接成功
String wifiLoginName = "CY-ESP8266";
ESP8266WiFiMulti wifiMulti;    
ESP8266WebServer esp8266_server(80);
String wifi_ip_add = "/wifi/wifi_ip.txt";
String wifi_account_add = "/wifi/wifi_account.txt";
String wifi_password_add = "/wifi/wifi_password.txt";

void setup() {
  Serial.begin(9600);
  // 读取"闪存文件系统",获取WIFI帐号,WIFI密码
  SPIFFS.begin();
  // 开启AP模式
  WiFi.softAP(apAccount, apPassword);
  Serial.println(apAccount);
  Serial.println(WiFi.softAPIP());   // 可以得到NodeMCU的IP地址(默认是192.168.4.1)
  esp8266_server.begin();                   //  启动"网络服务器"
  esp8266_server.on("/", handleRoot);
  esp8266_server.on("/wifiLogin", handleWifiLogin);
  esp8266_server.on("/readWifiStatus", handleReadWifiStatus);
  esp8266_server.onNotFound(handleNotFound);
  // 检查闪存文件系统中保存的WIFI连接信息,用 这些信息连接WIFI
  if (SPIFFS.exists(wifi_ip_add)&&SPIFFS.exists(wifi_account_add)&&SPIFFS.exists(wifi_password_add)){
    String wifiAccount = readFile(wifi_account_add).c_str();   // String转换为const char*之间的转化 str.c_str()
                                                               // const char*转换为String用.toString()方法
    String wifiPassword = readFile(wifi_password_add).c_str();
    WiFi.hostname(wifiLoginName);  // 连入WIFI网络后,开发板自己的名字
    WiFi.begin(wifiAccount, wifiPassword);
    Serial.print("Connecting to ");  Serial.println(wifiAccount);
    // 连接WIFI最多10秒
    for(int i=1;i<=10;i++){
      if(WiFi.status() == WL_CONNECTED){
        wifiLoginFlag = 1;
        break;
      }
      delay(1000);
      Serial.print(i); Serial.println("秒");
    }
  } else {
    Serial.println("文件不存在");
  }
  
  // 如果连接WIFI成功,将wifiIp写入闪存文件系统
  if(WiFi.status()==WL_CONNECTED){
    wifiLoginFlag = 1;
    writeFile(wifi_ip_add,WiFi.localIP().toString());
  } else {
    Serial.println("首次启动Wifi连接失败");
  }
}
 
void loop() { 
  esp8266_server.handleClient();
}
void handleRoot(){
  // 默认访问WIFI登录页面wifiLogin.html
  String path = "/wifiLogin.html";
  String contentType = getContentType(path);
  if(SPIFFS.exists(path)){
    File file = SPIFFS.open(path,"r");  
    esp8266_server.streamFile(file, contentType);
    file.close();
  } else {
    esp8266_server.send(404, "text/plain", "404 Not Found");  
  }
}

void handleWifiLogin(){
  // 获取页面传来的参数,连接WIFI
  // 如果成功就将WIFI帐号秘密写入闪存文件系统,返回成功提示,如果失败访问handleRoot
  String wifiAccount = esp8266_server.arg("wifiAccount");
  String wifiPassword = esp8266_server.arg("wifiPassword");
  WiFi.hostname(wifiLoginName);
  WiFi.begin(wifiAccount, wifiPassword);
  esp8266_server.send(200, "text/plain", "连接中");   // 要先给浏览器响应,否则浏览器会一直发起访问
  for(int i=1;i<=10;i++){
    if(WiFi.status() == WL_CONNECTED){
      wifiLoginFlag = 1;
      break;
    }
    delay(1000);
    Serial.print("新连接"); Serial.print(i); Serial.println("秒");
  }
  if(WiFi.status() == WL_CONNECTED){
    wifiLoginFlag = 1;
    // 将新的WIFI帐号,密码,路由器分配的IP地址写入闪存文件系统,向网页返回成功提示
    writeFile(wifi_ip_add,WiFi.localIP().toString());
    writeFile(wifi_account_add,wifiAccount);
    writeFile(wifi_password_add,wifiPassword);
    Serial.println("连接成功");
  } else {
    Serial.println("连接失败");
  }
}

// 读取当前wifi连接状态,以及闪存文件系统中储存的wifi信息
void handleReadWifiStatus(){
  String wifiStatus = "";
  wifiStatus += "wifi连接状态:";
  wifiStatus += wifiLoginFlag;
  wifiStatus += "\r\n开发板被分配的IP地址:";
  wifiStatus += readFile(wifi_ip_add);
  wifiStatus += "\r\nwifi帐号";
  wifiStatus += readFile(wifi_account_add);
  wifiStatus += "\r\nwifi密码";
  wifiStatus += readFile(wifi_password_add);
  esp8266_server.send(200, "text/plain", wifiStatus);
}

void handleNotFound(){
  esp8266_server.send(404, "text/plain", "404: Not found");
}

// 根据文件地址,读取文件中的字符串String
String readFile(String fileAddress){
  File file = SPIFFS.open(fileAddress, "r");
  String readStrings; 
  for(int i=0; i<file.size(); i++){
    readStrings+=(char)file.read();
  }
  return readStrings;
}

// 根据文件地址和文字内容,向文件中的写入字符串String
String writeFile(String fileAddress,String fileContent){
  File wifiIpFile = SPIFFS.open(fileAddress, "w");
  wifiIpFile.print(fileContent);
}

// 获取文件类型
String getContentType(String filename){
  if(filename.endsWith(".htm")) return "text/html";
  else if(filename.endsWith(".html")) return "text/html";
  else if(filename.endsWith(".css")) return "text/css";
  else if(filename.endsWith(".js")) return "application/javascript";
  else if(filename.endsWith(".png")) return "image/png";
  else if(filename.endsWith(".gif")) return "image/gif";
  else if(filename.endsWith(".jpg")) return "image/jpeg";
  else if(filename.endsWith(".ico")) return "image/x-icon";
  else if(filename.endsWith(".xml")) return "text/xml";
  else if(filename.endsWith(".pdf")) return "application/x-pdf";
  else if(filename.endsWith(".zip")) return "application/x-zip";
  else if(filename.endsWith(".gz")) return "application/x-gzip";
  return "text/plain";
}

3.4 使用示例

        WIFI登录界面(/接口)

         查询WIFI状态(/readWifiStatus接口) 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值