介绍

超文本传输协议(HTTP)是标准的应用层协议,用作服务器和客户端之间的请求响应协议。

它被广泛应用于物联网(IoT)嵌入式应用,每个传感器都连接到一个服务器,我们可以通过互联网进行控制。

NodeMCU具有可用的Wi-Fi功能。通过这种Wi-Fi功能,NodeMCU可以作为客户端连接到任何Wi-Fi网络,也可以创建其他支持Wi-Fi的设备连接的网络。

NodeMCU作为Wi-Fi使用AP模式的HTTP Server

NodeMCU wi-fi具有接入点(AP)模式,通过它可以创建无线LAN,任何支持Wi-Fi的设备都可以连接,如下图所示。

esp8266作为自己的博客服务器 esp8266 服务器_HTTP

NodeMCU作为使用Wi-Fi AP模式的HTTP Server

我们可以设置AP模式下的SSID和密码,这个模式用来连接到其他设备。

NodeMCU作为Wi-Fi使用STA模式的HTTP Server

NodeMCU具有Station(STA)模式,可以使用该模式连接到现有的Wi-Fi网络,并可以充当该网络分配的IP地址的HTTP服务器。

esp8266作为自己的博客服务器 esp8266 服务器_html_02

NodeMCU作为使用Wi-Fi STA模式的HTTP Server

NodeMCU从连接的Wi-Fi路由器获取IP。使用此IP地址,它可以充当任何Wi-Fi设备可以连接的HTTP服务器。

让我们编写Arduino Sketch,使NodeMCU成为具有Wi-Fi STA / AP模式的HTTP服务器,并控制从客户端连接到服务器端的LED。

在这里,我们已经连接LED到引脚号。2即NodeMCU板上的D2引脚,如下图所示。

esp8266作为自己的博客服务器 esp8266 服务器_esp8266作为自己的博客服务器_03

客户端的HTML页面

由于我们正在开发用于LED开/关功能的HTTP服务器,因此我们将制作一个简单的HTML页面,这个页面将在客户端可见,并且能够接通/断开LED的用户输入。这是用户友好的按钮输入代表,从用户点击输入。

我们需要为LED ON和LED OFF状态编写两个HTML页面,即当客户点击LED ON按钮时,下一步我们需要提供LED OFF的选项。以下是LED ON和LED OFF状态显示的两个HTML代码片段。

用于LED的HTML代码片段

<!DOCTYPE html>
<html>
<head><title>LED Control</title></head>
<body>
<h1>LED</h1>
<p>Click to switch LED on and off.</p>
<form method="get">
<input type="button" value="LED ON" onclick="window.location.href='/ledon'">
</form>
</body>
</html>

关闭LED的HTML代码片段

<!DOCTYPE html>
<html>
<head><title>LED Control</title></head>
<body>
<h1>LED</h1>
<p>Click to switch LED on and off.</p>
<form method="get">
<input type="button" value="LED OFF" onclick="window.location.href='/ledoff'">
</form>
</body>
</html>

从上面的两个HTML代码片断中,我们可以看到只有LED ON和LED OFF状态的形式不同。

我们来看看HTML行

<!DOCTYPE html>:该声明将该文档定义为HTML,并帮助浏览器正确显示网页。它只能出现一次,在页面的顶部。

<html>:这个元素是HTML页面的根元素

<head>:这个元素包含关于文档的元信息

<title>:这个元素指定文档的标题

<body>:这个元素包含可见的页面内容,即文档的主体

<h1>:这个元素定义了标题的最大字体大小。同样的,我们可以使用<h2> / <h3>等来标题的较小的字体大小。

<p>:这个元素定义了一个段落。

<form>:这个元素定义了一个用来收集用户输入的表单

window.location.href:这是一个属性,会告诉我们当前的URL位置。更改属性的值将重定向页面。

比如window.location.href='/ledon'将当前页面重定向到URL current_url/ledon 页面。如果当前位置是http://192.168.0.1那么它将重定向到http://192.168.0.1/ledon 页面。页面重定向动作是在点击事件(例如点击按钮)上进行的。  

这里我们使用上面提到的概念(页面重定向)将客户端从LED ON页面重定向到LED OFF页面,反之亦然。

要了解有关HTML的更多信息,请参阅https://www.w3schools.com/html/default.asp

现在,我们可以发送上面的HTML片段,当客户端连接到服务器,也当客户端点击按钮。

 

程序

在Wi-Fi接入点(AP)模式下,NodeMCU创建服务器,因此我们可以设置其IP地址,IP子网掩码和IP网关。

 

我们来看下SSID,密码加入网络和AP模式的地址

  • SSID =“NodeMCU”
  • 密码=“12345678”
  • IP =“192.168.2.1”
  • Sub netmask =“255.255.255.0”
  • 网关=“192.168.2.1”

带有Wi-Fi AP模式的HTTP服务器的Arduino Sketch

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,2,1);
IPAddress gateway(192,168,2,1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

uint8_t LEDpin = D2;
bool LEDstatus = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(LEDpin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  
  server.on("/", handle_OnConnect);
  server.on("/ledon", handle_ledon);
  server.on("/ledoff", handle_ledoff);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LEDstatus)
  digitalWrite(LEDpin, HIGH);
  else
  digitalWrite(LEDpin, LOW);
}

void handle_OnConnect() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(false)); 
}

void handle_ledon() {
  LEDstatus = HIGH;
  server.send(200, "text/html", SendHTML(true)); 
}

void handle_ledoff() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led){
  String ptr = "<!DOCTYPE html>\n";
  ptr +="<html>\n";
  ptr +="<head>\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>LED</h1>\n";
  ptr +="<p>Click to switch LED on and off.</p>\n";
  ptr +="<form method=\"get\">\n";
  if(led)
  ptr +="<input type=\"button\" value=\"LED OFF\" onclick=\"window.location.href='/ledoff'\">\n";
  else
  ptr +="<input type=\"button\" value=\"LED ON\" onclick=\"window.location.href='/ledon'\">\n";
  ptr +="</form>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

注意:成功上传以上草图客户端需要先连接到NodeMCU创建的网络。

从wifi连接到NodeMCU网络后,在浏览器中输入服务器地址,http://server_ip_address例如在我们的情况下http://192.168.2.1按Enter键后,我们可以看到服务器的HTML页面响应,如下图所示。现在只需点击按钮来改变LED的状态。

esp8266作为自己的博客服务器 esp8266 服务器_html_04

现在,让我们使用Wi-Fi站模式对NodeMCU执行HTTP服务器。

在Wi-Fi Station(STA)模式下,NodeMCU从Wi-Fi路由器(接入点)获取IP地址。如果我们也在同一个网络中,那么我们可以直接使用IP地址连接到NodeMCU HTTP Server。

带有Wi-Fi STA模式的HTTP服务器的Arduino Sketch

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

/*Put your SSID & Password*/
const char* ssid = "ssid";  // Enter SSID here
const char* password = "password";  //Enter Password here

ESP8266WebServer server(80);

uint8_t LEDpin = D2;
bool LEDstatus = LOW;

void setup() {
  Serial.begin(9600);
  delay(100);
  pinMode(LEDpin, OUTPUT);

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

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.on("/ledon", handle_ledon);
  server.on("/ledoff", handle_ledoff);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LEDstatus)
  digitalWrite(LEDpin, HIGH);
  else
  digitalWrite(LEDpin, LOW);
}

void handle_OnConnect() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(false)); 
}

void handle_ledon() {
  LEDstatus = HIGH;
  server.send(200, "text/html", SendHTML(true)); 
}

void handle_ledoff() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led){
  String ptr = "<!DOCTYPE html>\n";
  ptr +="<html>\n";
  ptr +="<head>\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>LED</h1>\n";
  ptr +="<p>Click to switch LED on and off.</p>\n";
  ptr +="<form method=\"get\">\n";
  if(led)
  ptr +="<input type=\"button\" value=\"LED OFF\" onclick=\"window.location.href='/ledoff'\">\n";
  else
  ptr +="<input type=\"button\" value=\"LED ON\" onclick=\"window.location.href='/ledon'\">\n";
  ptr +="</form>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

注意:在Wi-Fi站模式下,我们需要输入现有网络的ssid和密码。连接到WiFi网络后,在浏览器中输入服务器地址即http://assigned_ip_address按下回车键后,我们可以在浏览器中看到服务器的HTML页面响应,如上图所示