ESP8266Web配网,利用FS闪存文件系统+EEPROM双重记录配网信息和其他相关参数设定

FS闪存文件系统和EEPROM的使用时二选一的,可以任意一种作为你的备选存储相关参数的方案来实施。
每个人的个性化需求不一样,可以根据个人的需求做相关的移植即可,已经相当精简,内容只涉及配网和存储案例参数设定的,移植也非常方便。
EEPROM读写函数都是现成写好的,直接拿来使用即可,比起自己来写的话,不一定能写出这么优秀无bug的代码,站在巨人的肩膀上实现自己的小目标要比一个人摸索要快捷省力,而且高效,容易得多。
注意事项:利用闪存文件系统配置,上传完程序后,再点击工具-esp8266 Sketch Date Upload上传配置后,才可以打开相关的Web配置页面,进行配置,
本代码已经成功验证,并且反复断电,验证读取FS和EEPROM是否正确。
配网页面大同小异,如下图:

至强ESP8266Web配网,利用FS闪存文件系统+EEPROM双重记录配网信息和其他相关参数设定_第1张图片

至强ESP8266Web配网,利用FS闪存文件系统+EEPROM双重记录配网信息和其他相关参数设定_第2张图片

配置完成后,串口打印信息:

至强ESP8266Web配网,利用FS闪存文件系统+EEPROM双重记录配网信息和其他相关参数设定_第3张图片

 

#include 
#include 
#include  //闪存文件系统
#include //json数据处理库(第三方)
#include  
#define button D8  //设置手动清除FS闪存内容按键,loop里面已注释,未开启。
String ssid,password,location0,apikey0;

ESP8266WebServer server(80); //创建Web服务端口为80


void setup() {
     
  pinMode(LED_BUILTIN, OUTPUT);//板载led
  pinMode(button,INPUT);
  digitalWrite(button,HIGH); 
  Serial.begin(115200);
  EEPROM.begin(1024);
Serial.println("以下为EEPROM读取的信息:");
String count=Read_String(EEPROM.read(800),816);
delay(50);
Serial.println(count);
String pass=Read_String(EEPROM.read(804),856); 
delay(50);
Serial.println(pass);
String loca= Read_String(EEPROM.read(808),884);
delay(50);
Serial.println(loca);
String api=Read_String(EEPROM.read(812),932);
delay(50);
Serial.println(api);
 //Serial.println("");
  if (SPIFFS.begin()) {
      // 打开闪存文件系统,记得在你连接板子下载的过程中选Flash Size的时候不要选no SPIFFS,你可以选1M、2M、3M都无所谓,因为两个文件都很小
    Serial.println("闪存文件系统打开成功");
  } else {
     
    Serial.println("闪存文件系统打开失败");
  }
  if (SPIFFS.exists("/config.json")) {
      // 判断有没有config.json这个文件
    Serial.println("存在配置信息,正在自动连接");
    const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + 156; //分配一个内存空间
    DynamicJsonDocument doc(capacity);// 声明json处理对象
    File configJson = SPIFFS.open("/config.json", "r");
    deserializeJson(doc, configJson); // json数据序列化
    const char* ssid = doc["ssid"];
    Serial.println(ssid);
    const char* password = doc["password"];
    Serial.println(password);
    const char* location = doc["location0"];
    Serial.println(location);
    const char* apikey = doc["apikey0"];
    Serial.println(apikey);


    WiFi.mode(WIFI_STA); // 更换wifi模式
    //WiFi.mode(WIFI_AP_STA);//设置模式为AP+STA
    digitalWrite(LED_BUILTIN, HIGH);

    WiFi.begin(ssid, password); // 连接wifi
    Serial.println("AP设置完成");
    while (WiFi.status() != WL_CONNECTED) {
     
      delay(500);
      Serial.print(".");
    }
    configJson.close();
    Serial.println(WiFi.localIP());
  } else {
     
    Serial.println("不存在配置信息,正在打开web配网模式");
    IPAddress softLocal(192, 168, 1, 1);
    IPAddress softGateway(192, 168, 1, 1);
    IPAddress softSubnet(255, 255, 255, 0);
    WiFi.softAPConfig(softLocal, softGateway, softSubnet);
    WiFi.softAP("esp8266", "12345678"); //这里是配网模式下热点的名字和密码
    Serial.println(WiFi.softAPIP());
  }
  server.on("/", handleRoot);//web首页监听
  server.on("/set", handleConnect); // 配置ssid密码监听,感觉跟express的路由好像
  server.begin();
}

void loop() {
     
  
  server.handleClient();
//  if (digitalRead(button) == 0) { //按键扫描,开启后,会监测按键是否按下,按下后,将会清楚FS闪存,下次重启将进入配网。
//    removeConfig();
//  }
}


void handleRoot() {
      //展示网页的关键代码
  if (SPIFFS.exists("/index.html")) {
     
    File index = SPIFFS.open("/index.html", "r");
    server.streamFile(index, "text/html");
    index.close();
  }
}

void handleConnect() {
      //处理配置信息的函数
   ssid = server.arg("ssid");   //arg是获取请求参数
   password = server.arg("password");
   location0 = server.arg("location"); //从JavaScript发送的数据中找laction的值
   apikey0 = server.arg("apikey"); //从JavaScript发送的数据中找apikey的值
 EEPROM.begin(1024);
  Serial.println(ssid);
  Write_String(800,816,ssid);
  delay(30);
  
  Serial.println(password);
  Write_String(804,856,password);
   delay(30); 
  Serial.println(location0);
  Write_String(808,884,location0);
    delay(30);
  Serial.println(apikey0);
  Write_String(812,932,apikey0);
  delay(30);
  server.send(300, "text/plain", "OK");
  WiFi.mode(WIFI_STA); //改变wifi模式
  WiFi.begin(ssid.c_str(), password.c_str());//String类型直接用会报错,不要问为什么,转成char *就行了。
  while (WiFi.status() != WL_CONNECTED) {
     
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());
  removeConfig(); // 不管有没有配置先删除一次再说。
  String payload; // 拼接构造一段字符串形式的json数据长{"ssid":"xxxxx","password":"xxxxxxxxxxx"}
  payload += "{\"ssid\":\"";
  payload += ssid;
  payload += "\",\"password\":\"";
  payload += password;
  payload += "\",\"location0\":\"";
  payload += location0;
  payload += "\",\"apikey0\":\"";
  payload += apikey0;
  payload += "\"}";
  File wifiConfig = SPIFFS.open("/config.json", "w");
  wifiConfig.println(payload);//将数据写入config.json文件中
  wifiConfig.close();
}

void removeConfig() {
     
  if (SPIFFS.exists("/config.json")) {
      // 判断有没有config.json这个文件
    if (SPIFFS.remove("/config.json")) {
     
      Serial.println("删除旧配置");
    } else {
     
      Serial.println("删除旧配置失败");
    }
  }
}

//a写入字符串长度,b是起始位,str为要保存的字符串
void Write_String(int a,int b,String str){
     
  EEPROM.write(a, str.length());//EEPROM第a位,写入str字符串的长度
  //把str所有数据逐个保存在EEPROM
  for (int i = 0; i < str.length(); i++){
     
    EEPROM.write(b + i, str[i]);
  }
  EEPROM.commit();
}
//a位是字符串长度,b是起始位
String Read_String(int a, int b){
      
  String data = "";
  //从EEPROM中逐个取出每一位的值,并链接
  for (int i = 0; i < a; i++){
     
    data += char(EEPROM.read(b + i));
  }
  return data;
}

配网.html代码:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WIFI配网</title>
</head>
<body>
    <div class="main">
        <h2>WIFI配网</h2>
        <br>
        <input class="input ssid" type="text" placeholder="SSID" name="ssid">
        <input class="input password" type="password" placeholder="密码" name="password">
        <button class="button" onclick="sendData()">配置</button>
    </div>
</body>
<script>
    function sendData(){
     
        let ssid = document.querySelector(".ssid").value
        let password = document.querySelector(".password").value
        if(ssid == "" || password == ""){
     
            return
        }
        console.log(ssid,password)
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
     
            if (this.readyState == 4 && this.status == 200) {
     
                console.log("配置成功")
                alert("配置成功");
            }
        };
        xhttp.open("GET", "set?ssid="+ssid+"&password="+password, true);
        xhttp.send();
    }
</script>
<style>
    html,body{
     
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }
    .main{
     
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        text-align: center;
    }
    .button{
     
        outline: none;
        box-sizing: border-box;
        background: #f5f5f5;
        border: 1px solid#bdbdbd;
        border-radius: 18px;
        color: #434343;
        cursor: pointer;
        display: block;
        font-family: inherit;
        font-size: 16px;
        font-variant: normal;
        font-weight: 400;
        height: 2.14285714em;
        line-height: 1.42857143;
        margin: 18px auto;
        padding: 4px 30px;
        text-decoration: none;
        white-space: nowrap;
    }
    .input{
     
        resize: none;
        outline: none;
        margin: 4px auto;
        height: 45px;
        width: 80%;
        border: 1px solid #d0d1ce;
        padding-left: 15px;
        font-size: 14px;
        color: #000;
        margin-left: 10px;
        border-radius: 10px;
        border: 1px solid #dcdfe6;
        background-color: #fff;
    }
    
    
</style>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值