在许多物联网应用中,有些情况下需要连续监控传感器数据,而最简单的方法是通过使用ESP8266 Web服务器来提供HTML网页服务。但是这种方法的问题在于,必须以特定的时间间隔刷新Web浏览器才能获取更新的传感器数据。这不仅效率低下,而且需要很多时钟周期才能执行其他任务。该问题的解决方案称为“Asynchronous JavaScript and XML ”或简称AJAX。使用AJAX技术,我们可以监视实时数据而无需刷新整个网页,这不仅节省了时间,而且还节省了宝贵的时钟周期。通过本文,您将学习如何在ESP8266上实现基于AJAX的网络服务器。
什么是AJAX?
如前所述,AJAX表示“Asynchronous JavaScript and XML”,可用于更新网页的一部分,而无需重新加载所需页面。它通过自发地请求和接收来自服务器的数据来实现。 AJAX的功能是异步更新网页内容。这意味着,仅需要更新页面上的一部分内容时,用户的网络浏览器就无需刷新整个网页。
AJAX的日常示例就是Google的建议功能,当我们在Google搜索栏中键入内容时,Google会开始建议相关的搜索字符串。在此过程中,网页不会重新加载,但是需要更改的信息会使用AJAX在后台更新。
AJAX是如何工作的?
AJAX使用两种方法的组合:XML(可扩展标记语言)和 JavaScript和HTML。
XML (Extensible Markup Language)
XML是一种标记语言。 XML主要用于接收具有特定格式的服务器数据。尽管它可以接收纯文本形式的数据。当用户访问网页并发生事件(在我们的例子中是“按下按钮”)时,JavaScript创建一个XMLHttpRequest对象,该对象随后以XML格式在网络浏览器和网络服务器之间传输信息。 XMLHttpRequest对象将对更新后的页面数据的请求发送到Web服务器,服务器处理该请求,在服务器端创建一个响应,然后将其发送回浏览器,然后浏览器使用JavaScript处理该响应并将其显示在网页上。
JavaScript和HTML
JavaScript在AJAX中执行更新过程。对更新内容的请求以XML进行格式化,以使其易于理解,然后JavaScript刷新了该内容,供用户查看更新的页面。
AJAX工作过程
如上图所示,对于AJAX请求,浏览器使用JavaScript将XMLHttpRequest发送到服务器。该对象包含告诉服务器正在请求什么的数据。服务器仅响应从客户端请求的数据。然后,浏览器接收数据,仅更新页面中需要更新的部分,而不是重新加载整个网页。
构建基于AJAX和ESP8266的Web服务器所需的组件
由于我们正在构建项目以演示esp8266处理AJAX的功能,因此组件要求非常少。
● NodeMCU开发板
● LM35温度传感器
● LED指示灯
● 面包板
● 跳线
Ajax和ESP8266 Web服务器的电路图
基于AJAX的Web服务器的电路图如下所示。
由于电路非常简单,因此无需多解释。我们通过150欧姆限流电阻的LED连接到ESP8266的D0引脚,如您所见,我们可以使用网络服务器对其进行闪烁。接下来,我们使用LM35温度传感器,通过它我们将读取温度值并将其更新到网页。温度传感器由3.3V电源供电,由于LM35是模拟传感器,因此我们使用ESP8266板的A0引脚测量数据。
基于AJAX的Web服务器代码
在继续进行之前,让我们直接深入了解该程序,以了解NodeMCU Web服务器将如何工作。但在此之前,请确保已为ESP8266设置了Arduino IDE,如果没有设置,则可以继续下一部分,否则可以跳过此部分。
设置NodeMCU上传代码
如果您是第一次将代码上传到nodeMCU,则必须首先使用以下步骤将电路板包括到Arduino IDE中。
要将代码上传到NodeMCU,请按照以下步骤操作:
- 打开Arduino IDE,然后转到File–>;Preferences–>Settings 。
- 在"Additional Board Manager URL "字段中输入
https://arduino.esp8266.com/stable/package_esp8266com_index.json
,然后单击“OK”。 - 现在,转到“Tool”>“ Board”>“ Boards Manager”,打开“Boards Manager”窗口。在搜索框中输入ESP8266,选择最新版本的开发板,然后单击安装。
- 安装完成后,转到Tools ->Board并选择NodeMCU 1.0(ESP-12E模块)。现在,您可以使用Arduino IDE编程NodeMCU。
完成上述对NodeMCU的编程设置后,需要将完整的代码上传到NodeMCU。首先,在代码中包含所有必需的库。
为HTML页面创建头文件
首先,用于显示传感器值和LED控制按钮的HTML页面需要转换为头文件(.h文件),该文件将包含在我们的主代码中。这纯粹是为了方便。整个网页的HTML代码如下所示:
const char webpage[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<style type="text/css">
.button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
</style>
<body style="background-color: #f9e79f ">
<center>
<div>
<h1>AJAX BASED ESP8266 WEBSERVER</h1>
<button class="button" onclick="send(1)">LED ON</button>
<button class="button" onclick="send(0)">LED OFF</button><BR>
</div>
<br>
<div><h2>
Temp(C): <span id="adc_val">0</span><br><br>
LED State: <span id="state">NA</span>
</h2>
</div>
<script>
function send(led_sts)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("state").innerHTML = this.responseText;
}
};
xhttp.open("GET", "led_set?state="+led_sts, true);
xhttp.send();
}
setInterval(function()
{
getData();
}, 2000);
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("adc_val").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "adcread", true);
xhttp.send();
}
</script>
</center>
</body>
</html>
)=====";
首先,使用记事本创建一个新文件,并将其另存为.h扩展名。将头文件命名为“ index.h”,然后复制以上代码,然后粘贴到创建的头文件中。
代码的上述部分负责设置网页的所有视觉部分。
将代码上传到NodeMCU模块
我们首先包含所有必需的头文件,这里我们包含了“ ESP8266WiFi.h”、“ WiFiClient.h”和“ ESP8266WebServer.h”头文件。
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
然后,我们包含先前编写的头文件。不要忘记将文件保存在ESP8266 Code文件夹中。
#include "index.h"
现在,声明网络凭据-即SSID和密码。需要将NodeMCU连接到互联网。
const char* ssid = "admin";
const char* password = "12345678";
然后我们用名称服务器和默认端口号80定义ESP8266WebServer对象。
ESP8266WebServer server(80);
定义了handleRoot() 函数来处理HTML网页,并在请求时将整个网页发送到客户端。
void handleRoot()
{
String s = webpage;
server.send(200, "text/html", s);
}
sensor_data() 函数读取温度传感器数据,并在进行必要的转换后将其发送到网页。
void sensor_data()
{
int a = analogRead(A0);
int temp= a/4.35;
String sensor_value = String(temp);
server.send(200, "text/plane", sensor_value);
}
在led_control函数中,接收来自网页的信息并进行比较,以控制LED状态,如下所示。
void led_control()
{
String state = "OFF";
String act_state = server.arg("state");
if(act_state == "1")
{
digitalWrite(LED,HIGH); //LED ON
state = "ON";
}
else
{
digitalWrite(LED,LOW); //LED OFF
state = "OFF";
}
server.send(200, "text/plane", state);
}
然后,为了将NodeMCU连接到互联网,我们调用WiFi.begin()函数并传递网络SSID和密码作为其参数。使用WiFi.status()检查网络连接是否成功,连接成功后,在串口监视器上打印一条消息,显示连接设备的IP地址。
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print("Connecting...");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
然后,当客户端请求索引为“ /”,“ / led_set”和“ / adcread”的URL时,为了调用诸如“ handleRoot”、“ led_control”和“ sensor_data”之类的已定义函数,定义了以下代码块。
server.on("/", handleRoot);
server.on("/led_set", led_control);
server.on("/adcread", sensor_data);
server.begin();
上传代码后,就该测试项目了。首先,请确保您的热点已打开。然后在接通电路之前检查连接。然后,接通电路电源。在本例中,我们使用USB为项目供电,但也可以为NodeMCU提供外部5v DC电源。
接通电源后,就该获取nodeMCU的IP地址了。这可以使用Arduino IDE的串口监视器找到。打开串口监视器,然后按一下NodeMCU的Reset按钮,NodeMCU的IP地址应打印在串口监视器上。记下IP地址并将其粘贴到Web浏览器的URL栏上。
请注意,您的设备必须连接到与Nodemcu连接的同一网络。 在地址栏中输入IP后,您会在浏览器中得到网页。获取网页后,现在可以在此处监视传感器值,还可以从浏览器控制LED灯的状态。