位置导航: 首页 / 物联网教程 / 第3章 – 用C/C++开发物联网 / 3-2 – ESP8266网络服务器 /本页
我们在项目制作中可能会需要实时掌握NodeMCU开发板的引脚状态。在本节课程中 ,我们来一起学习如何通过NodeMCU建立基本网站。该网站的页面会实时显示NodeMCU的引脚状态。
为了便于学习,本节课中我们将使用D3引脚作为演示。选择D3引脚是因为它已经与开发板上的FLASH按键开关连接好了。
我们可以通过NodeMCU开发板上的FLASH按键控制D3引脚的电平。当我们没有按下该按键时,D3引脚将会保持高电平状态。当按下该按键后,D3引脚会变为低电平。
以下是本教程的第一段示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : 3_2_3_Pin_State_Display 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20191107 程序目的/Purpose : 使用NodeMCU建立基本服务器。该页面将会自动刷新并且显示NodeMCU 的D3引脚状态。NodeMCU开发板上的FLASH按键可以控制D3引脚的电平。 没有按下该按键时D3引脚将会保持高电平状态。当按下该按键后, D3引脚会变为低电平。 ----------------------------------------------------------------------- 修订历史/Revision History 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description ***********************************************************************/ #include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库 #include <ESP8266WiFiMulti.h> // ESP8266WiFiMulti库 #include <ESP8266WebServer.h> // ESP8266WebServer库 #define buttonPin D3 // 按钮引脚D3 ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti' ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80) bool pinState; // 存储引脚状态用变量 void setup(){ Serial.begin(9600); // 启动串口通讯 pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式 wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列WiFi ID和密码输入这里 wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络 wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有 Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。 int i = 0; while (wifiMulti.run() != WL_CONNECTED) { // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前 delay(1000); // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU Serial.print(i++); Serial.print(' '); // 将会连接信号最强的那一个WiFi信号。 } // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是 // 此处while循环判断是否跳出循环的条件。 // WiFi连接成功后将通过串口监视器输出连接成功信息 Serial.println('\n'); // WiFi连接成功后 Serial.print("Connected to "); // NodeMCU将通过串口监视器输出。 Serial.println(WiFi.SSID()); // 连接的WiFI名称 Serial.print("IP address:\t"); // 以及 Serial.println(WiFi.localIP()); // NodeMCU的IP地址 esp8266_server.begin(); // 启动网站服务 esp8266_server.on("/", handleRoot); // 设置服务器根目录即'/'的函数'handleRoot' esp8266_server.onNotFound(handleNotFound);// 设置处理404情况的函数'handleNotFound' Serial.println("HTTP esp8266_server started");// 告知用户ESP8266网络服务功能已经启动 } void loop(){ esp8266_server.handleClient(); // 处理http服务器访问 pinState = digitalRead(buttonPin); // 获取引脚状态 } /* 以下函数处理网站首页的访问请求。此函数为本示例程序重点1 详细讲解请参见太极创客网站《零基础入门学用物联网》 第3章-第2节“通过网络服务将开发板引脚状态显示在网页中”的说明讲解。*/ void handleRoot() { String displayPinState; // 存储按键状态的字符串变量 if(pinState == HIGH){ // 当按键引脚D3为高电平 displayPinState = "Button State: HIGH"; // 字符串赋值高电平信息 } else { // 当按键引脚D3为低电平 displayPinState = "Button State: LOW"; // 字符串赋值低电平信息 } esp8266_server.send(200, "text/plain", displayPinState); // 向浏览器发送按键状态信息 } // 设置处理404情况的函数'handleNotFound' void handleNotFound(){ // 当浏览器请求的网络资源无法在服务器找到时, esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。 } |
在以上程序的loop函数中,pinState = digitalRead(buttonPin);
语句将不断检查NodeMCU开发板D3引脚状态,也就是检查该引脚所连接的按键是否被按下。该状态将会存储与布尔变量pinState中。
变量pinState将会用于本程序的重点1,也就是handleRoot() 函数里。在handleRoot函数里,我们利用逻辑判断语句来对displayPinState 进行赋值。如果按键没有被按下,pinState为HIGH,这时候程序将会执行displayPinState = "Button State: HIGH";
也就是为displayPinState的赋值为“Button State: HIGH”。这句话的意思是“按键引脚状态为高电平”。反之,当我们按下按键后,程序将会执行displayPinState = "Button State: LOW";
也就是为displayPinState的赋值为“Button State: LOW”。
在handleRoot函数的结尾处,
esp8266_server.send(200, "text/plain", displayPinState);
这条语句将会把displayPinState所存储的信息发送给浏览器。于是我们在没有按下按键时,将会得到以下页面信息。
而当我们按下NodeMCU的Flash按键后,并且刷新页面后
,会得到以下信息
以上示例中,我们需要刷新网页页面才能将按键的最新状态显示在网页中。为了实现页面的自动刷新,请您参考以下示例程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : 3_2_4_Pin_State_Display_Auto_Refresh 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200128 程序目的/Purpose : 使用NodeMCU建立基本服务器。该网页将显示引脚D3状态。同时状态会 每隔5秒钟更新一次。 ----------------------------------------------------------------------- 修订历史/Revision History 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description ***********************************************************************/ #include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库 #include <ESP8266WiFiMulti.h> // ESP8266WiFiMulti库 #include <ESP8266WebServer.h> // ESP8266WebServer库 #define buttonPin D3 // 按钮引脚D3 ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti' ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80) bool pinState; // 存储引脚状态用变量 void setup(){ Serial.begin(9600); // 启动串口通讯 delay(10); Serial.println(""); pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式 wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列WiFi ID和密码输入这里 wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU在启动后会扫描当前网络 wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有 Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。 // 另外这里只存储了3个WiFi信息,您可以存储更多 // 的WiFi信息在此处。 int i = 0; while (wifiMulti.run() != WL_CONNECTED) { // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前 delay(1000); // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU Serial.print(i++); Serial.print(' '); // 将会连接信号最强的那一个WiFi信号。 } // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是 // 此处while循环判断是否跳出循环的条件。 // WiFi连接成功后将通过串口监视器输出连接成功信息 Serial.println('\n'); // WiFi连接成功后 Serial.print("Connected to "); // NodeMCU将通过串口监视器输出。 Serial.println(WiFi.SSID()); // 连接的WiFI名称 Serial.print("IP address:\t"); // 以及 Serial.println(WiFi.localIP()); // NodeMCU的IP地址 esp8266_server.begin(); esp8266_server.on("/", handleRoot); esp8266_server.onNotFound(handleNotFound); Serial.println("HTTP esp8266_server started");// 告知用户ESP8266网络服务功能已经启动 } void loop(){ esp8266_server.handleClient(); // 处理http服务器访问 pinState = digitalRead(buttonPin); // 获取引脚状态 } /* 以下函数处理网站首页的访问请求。此函数为本示例程序重点1 详细讲解请参见太极创客网站《零基础入门学用物联网》 第3章-第2节“通过网络服务将开发板引脚状态显示在网页中”的说明讲解。*/ void handleRoot() { //处理网站目录“/”的访问请求 esp8266_server.send(200, "text/html", sendHTML(pinState)); } /* 建立用于发送给客户端浏览器的HTML代码。此代码将会每隔5秒刷新页面。 通过页面刷新,引脚的最新状态也会显示于页面中 */ String sendHTML(bool buttonState){ String htmlCode = "<!DOCTYPE html> <html>\n"; htmlCode +="<head><meta http-equiv='refresh' content='5'/>\n"; htmlCode +="<title>ESP8266 Butoon State</title>\n"; htmlCode +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; htmlCode +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n"; htmlCode +="</style>\n"; htmlCode +="</head>\n"; htmlCode +="<body>\n"; htmlCode +="<h1>ESP8266 BUTTON STATE</h1>\n"; if(buttonState) {htmlCode +="<p>Button Status: HIGH</p>\n";} else {htmlCode +="<p>Button Status: LOW</p>\n";} htmlCode +="</body>\n"; htmlCode +="</html>\n"; return htmlCode; } // 设置处理404情况的函数'handleNotFound' void handleNotFound(){ // 当浏览器请求的网络资源无法在服务器找到时, esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。 } |
在以上示例程序中的handleRoot
函数中,esp8266_server.send(200, "text/html", sendHTML(pinState))
语句的的3个参数 sendHTML(pinState)
调用了sendHTML
函数。该函数的作用是建立一个可以定时刷新的HTML网页代码。通过定时刷新网页,开发板的引脚状态将会不断地在页面中进行更新。
此HTML网页代码是由sendHTML
函数产生的。该函数建立了一个字符串变量,该字符串变量所存储的信息正是网页HTML代码。值得注意的是,该HTML代码会不断地检查变量pinState状态,并且根据pinState的状态改变HTML代码的信息,从而实现在网页上显示引脚状态。
此HTML代码中真正实现定时刷新网页功能的语句是代码中的第79行语句。这条语句是告诉网页需要定时刷新,刷新频率5秒钟,即每5秒钟刷新一次页面。您可以通过改变此行语句中的数值5来调整页面刷新频率。
每一次页面刷新,浏览器都会向NodeMCU发送HTTP请求。NodeMCU在收到浏览器请求后,将会把最新的HTML代码信息返回给浏览器。浏览器收到最新的HTML代码后将会在页面中显示引脚的状态。
以下是没有按下按键时的页面显示信息。
以下是按下按键时的页面显示信息。