ESP32利用WebServer进行设备配置

目标需求

利用esp32的WebServer功能,展示一个网页,对里面的参数进行配置,并以json文本格式保存到flash里面。

1、定义HTML

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <title>采集器配置</title>
    <link rel="stylesheet" href="http://www.kanzz.net/res/eve.css">
</head>
<body>
<form id="config-form" autocomplete="off">
            <div class="form-item">
                <label for="versioin">软件版本:</label>
                <input type="text" id="versioin" name="versioin" value="%VERSION%" value="1.0">
            </div>
            <div class="form-item">
                <label for="sn">编号:</label>
                <input type="text" id="sn" name="sn" value="%SN%" required>
            </div>
            <div class="form-item">
                <label for="ip">IP 地址:</label>
                <input type="text" id="ip" name="ip" value="%MYIP%" required>
            </div>
            <div class="form-item">
                <label for="mask">子网掩码:</label>
                <input type="text" id="mask" name="mask" value="%MYMASK%" required>
            </div>
            <div class="form-item">
                <label for="gateway">网关:</label>
                <input type="text" id="gateway" name="gateway" value="%GATEWAY%" required>
            </div>
            <div class="form-item">
                <label for="ssid">WiFi SSID:</label>
                <input type="text" id="ssid" name="ssid" value="%SSID%" required>
            </div>
            <div class="form-item">
                <label for="wifipwd">WiFi Password:</label>
                <input type="text" id="wifipwd" name="wifipwd" value="%WIFIPWD%">
            </div>
            <div class="form-item">
                <label for="waittime">拉取时间(秒):</label>
                <input type="text" id="waittime" name="waittime" value="%WAITTIME%">
            </div>
            <div class="form-item">
                <label for="apiurl">推送接⼝:</label>
                <input type="text" id="apiurl" name="apiurl" value="%APIURL%">
            </div>
            <div class="form-item">
                <label for="appid">AppID:</label>
                <input type="text" id="appid" name="appid" value="%APPID%">
            </div>
            <div class="form-item">
                <label for="secret">Secret:</label>
                <input type="text" id="secret" name="secret" value="%SECRET%">
            </div>
            <div class="form-item">
                <button type="submit">保存配置</button>
            </div>
        </form>
</body>
</html>
)rawliteral";
const char info_html[] PROGMEM = R"rawliteral(
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
            <title>采集器配置</title>
            <link rel="stylesheet" href="http://www.kanzz.net/res/eve.css">
        </head>
        <body>
            <div style="margin:100px auto;width:400px;">
                <div style="color: #060;font-size: 16px;line-height: 30px;margin: 20px 0;">修改完成!</div>
                <div class="button"><button id="back" style="width: 160px;height: 40px;line-height: 30px;border: 1px solid #999;color: #fff;background-color: #5cd6b2;border: none;border-radius: 4px;box-shadow: 4px 4px 4px #999;cursor: pointer;">返回</button></div>
            </div>
            <script>        
                document.getElementById('back').addEventListener('click', function(event) {
                    location.href = '/';
                })
            </script>
        </body>
        </html>
)rawliteral";

其中定义了一些变量,展示页面的时候会用变量来替代,如:

<div class="form-item">
    <label for="ssid">WiFi SSID:</label>
    <input type="text" id="ssid" name="ssid" value="%SSID%" required>
</div>

代码中的 value="%SSID%"

2、安装ESPAsyncWebServer

3、定义JSON字符串

String jsonStr = "{\"version\": \"1.1\", \"sn\":\"2021\", \"mask\":\"255.255.255.0\", \"gateway\":\"192.168.0.1\", \"waittime\":\"0.5\", \"apiurl\":\"https://\", \"appid\":\"appid12345\", \"secret\":\"secret\"}";

4、读取Flash中的JSON文件

String readJsonFile()
{
  File configFile = SPIFFS.open("/config.json", FILE_READ);
  if (!configFile) {
    Serial.println("Failed to open config file");
    return "";
  }
  if(configFile.available())
  {
    String line = configFile.readString();
    configFile.close();
    return line;
  }
}

5、保存JSON文件到Flash中

void saveJsonFile()
{
  File configFile = SPIFFS.open("/config.json", "w");
  if (!configFile) {
    Serial.println("Failed to open config file for writing");
    return;
  }
  configFile.println(jsonStr);
  configFile.close();
  Serial.println("Config file saved");
}

6、处理HTML模板中的变量

String processor(const String& var)
{
  jsonConfig config = transTojson();
  if (var == "VERSION")
  {
    return config.version;
  }
  if (var == "SN")
  {
    return config.sn;
  }
  if (var == "MYIP")
  {
    return ip;
  }
  if (var == "MYMASK")
  {
    return config.mask;
  }
  if (var == "GATEWAY")
  {
    return config.gateway;
  }
  if (var == "SSID")
  {
    return ssid;
  }
  if (var == "WIFIPWD")
  {
    return password;
  }
  if (var == "WAITTIME")
  {
    return config.waittime;
  }
  if (var == "APIURL")
  {
    return config.apiurl;
  }
  if (var == "APPID")
  {
    return config.appid;
  }
  if (var == "SECRET")
  {
    return config.secret;
  }
  return String();
}

7、WebServer的监听

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
server.on("/save", HTTP_POST, [](AsyncWebServerRequest *request){
    String version, sn, mask, gateway, waittime, apiurl, appid, secret;
    if (request->hasParam("version", true)) {
        version = request->getParam("version", true)->value();
    } else {
        version = "-";
    }
    if (request->hasParam("sn", true)) {
        sn = request->getParam("sn", true)->value();
    } else {
        sn = "-";
    }
    if (request->hasParam("mask", true)) {
        mask = request->getParam("mask", true)->value();
    } else {
        mask = "-";
    }
    if (request->hasParam("gateway", true)) {
        gateway = request->getParam("gateway", true)->value();
    } else {
        gateway = "-";
    }
    if (request->hasParam("waittime", true)) {
        waittime = request->getParam("waittime", true)->value();
    } else {
        waittime = "-";
    }
    if (request->hasParam("apiurl", true)) {
        apiurl = request->getParam("apiurl", true)->value();
    } else {
        apiurl = "-";
    }
    if (request->hasParam("appid", true)) {
        appid = request->getParam("appid", true)->value();
    } else {
        appid = "-";
    }
    if (request->hasParam("secret", true)) {
        secret = request->getParam("secret", true)->value();
    } else {
        secret = "-";
    }
    jsonStr = "{\"version\": \"" + version + "\", \"sn\":\"" + sn + "\", \"mask\":\"" + mask + "\", \"gateway\":\"" + gateway + "\", \"waittime\":\"" + waittime + "\", \"apiurl\":\"" + apiurl + "\", \"appid\":\"" + appid + "\", \"secret\":\"" + secret + "\"}";
    saveJsonFile();
    delay(100);
    request->send_P(200, "text/html", info_html);
  });

根据逻辑整合起来后,测试成功!

### 关于使用PlatformIO开发ESP32 Web服务器 对于希望利用PlatformIO平台来构建基于ESP32Web服务器应用的开发者而言,可以参考一系列有价值的资料和实践指导。ESP32由于其内置Wi-Fi模块和支持多协议的特点,在创建网络应用程序方面具有天然优势[^1]。 #### 平台配置与初始化 在开始之前,确保已经安装好PlatformIO IDE插件,并通过命令`pio platform install espressif32`完成针对ESP32的支持包下载。这一步骤为后续编写代码奠定了基础环境准备的工作。 #### 创建基本HTTP服务器实例 下面是一个简单的例子展示如何建立一个最基础版本的HTTP Server: ```cpp #include <WiFi.h> #include <WebServer.h> const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; WebServer server(80); void handleRoot() { String html = "<html><body>Hello from ESP32!</body></html>"; server.send(200, "text/html", html); } void setup(){ Serial.begin(115200); WiFi.begin(ssid, password); // 连接到无线网络 while (WiFi.status() != WL_CONNECTED) { // 等待连接成功 delay(1000); Serial.println("Connecting to WiFi.."); } Serial.print("Connected to the Wi-Fi network with IP address: "); Serial.println(WiFi.localIP()); server.on("/", HTTP_GET, handleRoot); // 设置根路径处理器 server.begin(); // 启动web服务端口监听 } void loop(){ server.handleClient(); // 处理客户端请求 } ``` 此段程序展示了怎样设置Wi-Fi连接以及定义了一个处理GET请求的方法用于响应访问主页的情况。当浏览器向设备发送请求时,它会返回一段HTML字符串作为回应内容[^4]。 #### 高级特性集成 随着项目的复杂度增加,可能还需要考虑加入诸如WebSocket支持、文件上传/下载等功能。这些都可以借助Arduino库或者第三方库实现扩展。例如,可以通过引入`AsyncTCP`和`ESPAsyncWebServer`库来提升异步处理能力,从而提高效率和服务质量。 #### 参考文档获取途径 除了上述提及的内容外,还可以查阅官方提供的《ESP-IDF编程指南》中文版v4.3中的相关章节了解更详细的API说明和技术细节;另外,《esp32idf编程指南.pdf》也是一份不可多得的学习材料,其中包含了大量实用的操作指引和案例研究[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东成2022

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值