ESP32 Arduino异步HTTP服务器教程:通过PROGMEM提供HTM...-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3265|回复: 0

ESP32 Arduino异步HTTP服务器教程:通过PROGMEM提供HTM...

[复制链接]
发表于 2019-6-6 10:49 | 显示全部楼层 |阅读模式
本帖最后由 dfrobot 于 2019-5-30 21:50 编辑

本ESP32教程的测试是使用集成在ESP32开发板中的DFRobot的ESP-WROOM-32设备进行的。

简介
此文章旨在解释如何使用Arduino核心通过ESP32开发板提供简单的HTML页面。您可以查看上一篇文章,了解如何设置创建HTTP服务器所需的库。
我们的网页将是一个简单的HTML表单,我们将通过异步HTTP服务器提供该表单。请注意,我们不会为我们的表单样式创建任何CSS,因此它将是非常原始的,仅仅是为了说明如何提供HTML。

HTML代码
我们将通过独立于Arduino代码的方式设计HTML代码。然后,我们将使用一些工具将其转换为能够在ESP32上使用的紧凑字符串格式。
HTML代码的详细解释以及工作原理都超出了本文的范畴。所以,基本上我们将创建一个带两种输入和一个提交按钮的非常简单的表单,如下所示。

[mw_shl_code=applescript,true]
<form>

    <label class="label">Network Name</label>

    <input type = "text" name = "ssid"/>

    <br/>

    <label>Password</label>

    <input type = "text" name = "pass"/>

    <br/>

    <input type="submit" value="Submit">

</form>[/mw_shl_code]

我们将输入标记为“网络名称”和“密码”,因此这可能是实现网络Wi-Fi凭据输入的表单形式。
请注意,在此教程中,我们将仅介绍显示HTML内容的部分,因此我们不打算开发端点以通过表单接收数据。因此,我们执行event.preventDefault()调用,这样当单击按钮时实际上没有任何操作。
由于我们是针对资源受限的微控制器设备进行开发的,我们可以将以前的HTML压缩成单行格式,从而摆脱所有不必要的标签和新行。
尽管这会不方便代码阅读,但是对于将解释这些代码并节约ESP32空间的客户端没有任何区别。
如需执行此操作,我们可以使用此在线工具,这将精简我们的HTML代码。为了防止出现任何问题,当处理复杂的HTML页面时,我建议您在压缩后始终在本地尝试代码运行,以确认整个过程不会出现任何问题。
为此,您只需将精简的代码粘贴到文本文件中,使用.html扩展名保存并使用Web浏览器打开。如果一切正常,那么您可以在ESP32上使用它。
您可以通过以下图1查看使用上述在线工具精简代码的结果。




图1  - 精简HTML代码。

尽管如此,我们不能将此代码直接用作Arduino的字符串,因为它包含各种引用。因此,我们需要避免这些。
由于HTML代码通常包含大量引用,因此获取转义版本的最简单方法是使用此在线工具。
因此,如需转义代码,只需复制先前精简版本的HTML并将其粘贴到工具上,在开始操作之前取消选中“拆分输出为多行”选项。您可以在图2中查看预期结果。

图2  - 在线工具中转义精简HTML代码。

现在我们将HTML代码作为单行转义的C语言字符串,我们可以继续使用Arduino代码。

代码
本教程的代码与前一个代码类似,但我们现在将提供更复杂的HTML代码,我们将在PROGMEM中存储这些代码。
由于HTML内容是静态的,因此将其放在PROGMEM(程序存储器)上可以避免消耗RAM,从而使该资源能够用于其他目的。当我们的程序服务于大量静态页面时,这非常有用,因此如果没有放在PROGMEM中,会消耗大量的RAM。
如需启动代码,我们将编写加入所有需要的库。我们还将连接到Wi-Fi网络所需的凭证声明为全局变量。

[mw_shl_code=applescript,true]#include <WiFi.h>

#include <FS.h>

#include <AsyncTCP.h>

#include <ESPAsyncWebServer.h>



const char* ssid = "yourNetworkSSID";
const char* password =  "yourNetworkPass";[/mw_shl_code]

接下来,我们将声明一个AsyncWebServer类的对象,我们将使用它对服务器进行设置。请注意,作为构造函数输入,我们需要传递服务器将侦听请求的端口。

[mw_shl_code=applescript,true]AsyncWebServer server(80);[/mw_shl_code]

为了完成全局声明,我们将在PROGMEM中创建一个包含我们准备的HTML代码的变量。

[mw_shl_code=applescript,true]const char HTML[] PROGMEM = "<form onSubmit=\"event.preventDefault()\"><label class=\"label\">Network Name</label><input type=\"text\" name=\"ssid\"/><br/><label>Password</label><input type=\"text\" name=\"pass\"/><br/><input type=\"submit\" value=\"Submit\"></form>";

[/mw_shl_code]

继续设置功能,我们将首先打开一个串行接口,然后将ESP32连接到Wi-Fi网络。您可以在此处查看如何将ESP32连接到Wi-Fi网络的更多详情。

[mw_shl_code=applescript,true]Serial.begin(115200);



WiFi.begin(ssid, password);



while (WiFi.status() != WL_CONNECTED) {

    delay(1000);

    Serial.println("Connecting to WiFi..");

}



Serial.println(WiFi.localIP());[/mw_shl_code]

连接到Wi-Fi网络后,我们将负责网络服务器设置。因此,我们需要将服务器路由绑定到一个处理函数,该函数将返回客户端发出请求时定义的HTML。我们将使用“/html”路线。
如果您需要关于函数签名以及绑定如何工作的更加详细的说明,请参阅此前一篇文章。

[mw_shl_code=applescript,true]server.on("/html", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send(200, "text/html", HTML);

});[/mw_shl_code]

请注意,我们将返回内容类型指定为“text/html”,因此客户端(在我们的例子中它将是Web浏览器)知道它必须解释所接收的内容。
另外,谨记send函数最后一个参数是我们实际返回给客户端的内容,在我们的例子中,它是我们提前定义的HTML变量。
现在我们已经完成了服务器配置,我们只需在服务器对象上调用begin函数,因此它开始监听传入的HTTP请求。由于服务器异步工作,我们无需在主循环上执行任何调用,这可能是空的。

您可以查看以下完整的源代码。

[mw_shl_code=applescript,true]#include <WiFi.h>

#include <FS.h>

#include <AsyncTCP.h>

#include <ESPAsyncWebServer.h>

  

const char* ssid = "yourNetworkSSID";

const char* password =  "yourNetworkPassword";

  

AsyncWebServer server(80);



const char HTML[] PROGMEM = "<form onSubmit=\"event.preventDefault()\"><label class=\"label\">Network Name</label><input type=\"text\" name=\"ssid\"/><br/><label>Password</label><input type=\"text\" name=\"pass\"/><br/><input type=\"submit\" value=\"Submit\"></form>";



void setup(){

  Serial.begin(115200);

  

  WiFi.begin(ssid, password);

  

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);

    Serial.println("Connecting to WiFi..");

  }

  

  Serial.println(WiFi.localIP());

  

  server.on("/html", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send(200, "text/html", HTML);

  });

  

  server.begin();

}

  

void loop(){

}

[/mw_shl_code]


测试代码
如需测试代码,您只需编译它并使用Arduino IDE将其上传到您的设备即可。准备就绪后,只需打开串行监视器并等待与Wi-Fi网络的连接。
完成后,无线网络上ESP32的本地IP应打印到串行监视器。复制该IP,因为我们需要它连接到服务器。
然后,打开您选择的Web浏览器并在地址栏上写下以下URL,通过您刚刚获得的IP进行更改{yourEspIp}。
您应该得到类似于图3的输出,它显示了浏览器提供和呈现的HTML页面。




图3  - 浏览器中呈现的HTML表单。

注:本文作者是Nuno Santos,他是一位和蔼可亲的电子和计算机工程师,住在葡萄牙里斯本 (Lisbon)。
他写了200多篇有关ESP32、ESP8266的有用的教程和项目。

查看更多ESP32/ESP8266教程和项目:
中文版教程 : ESP32教程 合集
英文版教程 : ESP32 tutorial 合集


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 14:33 , Processed in 0.073733 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表