在許多物聯(lián)網(wǎng)應(yīng)用中,存在傳感器數(shù)據(jù)需要持續(xù)監(jiān)控的情況,最簡單的方法是啟用 為 HTML 網(wǎng)頁提供服務(wù)的ESP8266 網(wǎng)絡(luò)服務(wù)器;但是這種方法的問題是需要在特定的時間間隔刷新網(wǎng)絡(luò)瀏覽器才能獲取更新的傳感器數(shù)據(jù)。這不僅效率低下,而且需要很多時鐘周期才能執(zhí)行其他任務(wù)。這個問題的解決方案被稱為“異步 JavaScript 和 XML”或簡稱 AJAX。使用AJAX,我們可以在不刷新整個網(wǎng)頁的情況下監(jiān)控實時數(shù)據(jù),這不僅節(jié)省了時間,還節(jié)省了寶貴的時鐘周期。在本文中,您將學(xué)習(xí)如何在 ESP8266 上實現(xiàn)基于 AJAX 的網(wǎng)絡(luò)服務(wù)器。
什么是 AJAX?
正如我們之前所討論的, AJAX代表“異步 JavaScript 和 XML”,它可以用于更新網(wǎng)頁的一部分,而無需重新加載需要的頁面。它通過自發(fā)地從服務(wù)器請求和接收數(shù)據(jù)來做到這一點。AJAX 的功能是異步更新網(wǎng)頁內(nèi)容。這意味著當(dāng)只需要更新頁面上的一部分內(nèi)容時,用戶的 Web 瀏覽器不需要刷新整個網(wǎng)頁。
AJAX 的一個日常示例將是 Google 的建議功能,當(dāng)我們在 Google 搜索欄中鍵入時,Google 開始建議相關(guān)的搜索字符串。在此過程中,網(wǎng)頁不會重新加載,而是使用 AJAX 在后臺更新需要更改的信息。
AJAX 是如何工作的?
AJAX 只是使用以下組合 -
XML(可擴展標(biāo)記語言)
JavaScript 和 HTML
XML(可擴展標(biāo)記語言):
XML 是一種標(biāo)記語言。XML 主要用于接收具有特定格式的服務(wù)器數(shù)據(jù)。雖然它可以接收純文本形式的數(shù)據(jù)。當(dāng)用戶訪問網(wǎng)頁并發(fā)生事件時,在我們的例子中,它是一個“按鈕按下”,JavaScript 創(chuàng)建一個XMLHttpRequest對象,然后在 Web 瀏覽器和 Web 服務(wù)器之間以 XML 格式傳輸信息。XMLHttpRequest 對象向 Web 服務(wù)器發(fā)送更新頁面數(shù)據(jù)的請求,服務(wù)器處理請求,在服務(wù)器端創(chuàng)建響應(yīng)并發(fā)送回瀏覽器,然后使用 JavaScript 處理響應(yīng)并將其顯示在網(wǎng)頁上。
JavaScript 和 HTML:
JavaScript 在 AJAX 中執(zhí)行更新過程。更新內(nèi)容的請求采用 XML 格式以使其易于理解,并且 JavaScript 為查看更新頁面的用戶刷新內(nèi)容。
AJAX 工作:
如上圖所示,對于 AJAX 請求,瀏覽器使用 javascript 向服務(wù)器發(fā)送XMLHttpRequest 。該對象包括告訴服務(wù)器正在請求什么的數(shù)據(jù)。服務(wù)器僅響應(yīng)客戶端請求的數(shù)據(jù)。然后瀏覽器接收數(shù)據(jù),只更新頁面中需要更新的部分,而不是重新加載整個網(wǎng)頁。
構(gòu)建基于 AJAX 和 ESP8266 的 Web 服務(wù)器所需的組件
由于我們正在構(gòu)建項目以展示 esp8266 處理 AJAX 的能力,因此組件需求非常小,您可以在當(dāng)?shù)氐膼酆蒙痰曛姓业酱蟛糠纸M件。
節(jié)點單片機 X 1
LM35 溫度傳感器 X 1
LED X 1
面包板 X 1
跳線 X 4
編程電纜 X 1
Ajax 和 ESP8266 Web 服務(wù)器 - 電路圖
基于 AJAX 的網(wǎng)絡(luò)服務(wù)器的電路圖如下所示。
由于電路非常簡單,所以沒有什么好解釋的。我們已經(jīng)將一個帶 150 歐姆限流電阻的 LED 連接到 ESP8266 的引腳 D0,如您所見,我們可以使用網(wǎng)絡(luò)服務(wù)器對其進(jìn)行切換。接下來,我們有我們的 LM35 溫度傳感器,我們將通過它讀取溫度值并將其更新到網(wǎng)頁。溫度傳感器由 3.3V 電源軌供電,由于 LM35 是模擬傳感器,我們使用 ESP8266 板的 A0 引腳來測量數(shù)據(jù)。如果您是第一次接觸 LM35 溫度傳感器,或者您想了解更多關(guān)于這個非??岬男鞲衅鞯男畔ⅲ梢圆榭次覀冎瓣P(guān)于使用 NodeMCU 和 LM35 的數(shù)字溫度計的帖子,其中我們討論了該傳感器的工作原理細(xì)節(jié)。
ESP8266 的基于 AJAX 的 Web 服務(wù)器代碼
在我們繼續(xù)之前,讓我們直接進(jìn)入程序以了解我們的 NodeMCU Web 服務(wù)器將如何工作。但在此之前,請確保您有 ESP8266 的 Arduino IDE 設(shè)置,如果您沒有設(shè)置,您可以按照下一部分進(jìn)行操作,否則您可以跳過這一部分。如果您有興趣了解有關(guān)webserver和基于IoT的項目的更多信息,您可以查看我們之前的帖子,我們在其中討論了更多關(guān)于該主題的內(nèi)容。
設(shè)置 NodeMCU 以上傳代碼:
如果您是第一次將代碼上傳到 nodeMCU,那么您必須先包含板,使用以下步驟。
要將代碼上傳到 NodeMCU,請按照以下步驟操作:
1.打開 Arduino IDE,然后轉(zhuǎn)到File–》Preferences–》Settings。
2.在 “Additional Board Manager URL ”字段中輸入https://arduino.esp8266.com/stable/package_esp8266com_index.json并單擊“Ok”。
3.現(xiàn)在在 Boards Manager 窗口中轉(zhuǎn)到Tools 》 Board 》 Boards Manager 。在搜索框中輸入ESP 8266,選擇最新版本的開發(fā)板,然后點擊安裝。
4.安裝完成后,進(jìn)入Tools -》 Board -》 選擇NodeMCU 1.0(ESP-12E Module)?,F(xiàn)在您可以使用 Arduino IDE 對 NodeMCU 進(jìn)行編程。
完成上述 NodeMCU 編程設(shè)置后,需要將完整代碼上傳到 NodeMCU。首先,所有必需的庫文件都將包含在代碼中。
為 HTML 頁面創(chuàng)建頭文件:
首先,需要將用于顯示傳感器值和 LED 控制按鈕的 HTML 頁面轉(zhuǎn)換為頭文件(.h 文件),我們將在主代碼中包含該文件。這純粹是為了方便。整個網(wǎng)頁的 HTML 代碼如下所示:
const char pages[] PROGMEM = R"=====(?
?
)====="; 基于 AJAX 的 ESP8266 WEBSERVER
溫度(C):0
LED 狀態(tài):NA
?
首先,使用記事本創(chuàng)建一個新文件并將其保存為.h 擴展名,這是 C 頭文件的表示形式。將頭文件命名為“index.h”并將上述代碼復(fù)制并粘貼到創(chuàng)建的頭文件中。
上述代碼部分負(fù)責(zé)設(shè)置網(wǎng)頁的所有視覺和美學(xué)部分。
注意:不要忘記將上面的頭文件放在NodeMCU代碼的同一文件夾中,因為這需要在以后的編程中包含。
將代碼上傳到 NodeMCU 模塊:
我們首先包含所有必需的頭文件,聽說我們已經(jīng)包含了“ESP8266WiFi.h”、“WiFiClient.h”和“ESP8266WebServer.h”頭文件。
?
#include#include #include
?
然后,我們包含我們之前編寫的頭文件。不要忘記將文件保存在 ESP8266 代碼文件夾中。它被定義為,
?
#include "index.h"
?
現(xiàn)在,聲明網(wǎng)絡(luò)憑據(jù) - 即 SSID 和密碼。需要將 NodeMCU 連接到互聯(lián)網(wǎng)。
?
const char* ssid = "管理員"; const char* 密碼 = "12345678";
?
然后我們使用名稱服務(wù)器和默認(rèn)端口號 80 定義 ESP8266WebServer 對象。
?
ESP8266WebServer 服務(wù)器(80);
?
定義函數(shù)handleRoot處理HTML 網(wǎng)頁,并在請求時將整個網(wǎng)頁發(fā)送到客戶端。
?
void handleRoot() { String s = 網(wǎng)頁; server.send(200, "text/html", s); }
?
函數(shù)sensor_data被定義為讀取溫度傳感器數(shù)據(jù)并在必要的轉(zhuǎn)換后將其發(fā)送到網(wǎng)頁。
?
void sensor_data() { int a = analogRead(A0); 國際溫度=一/4.35; 字符串傳感器值 = 字符串(溫度); server.send(200, "文本/平面", sensor_value); }
?
在?led_control函數(shù)內(nèi)部,接收來自網(wǎng)頁的信息并進(jìn)行比較以控制 LED 狀態(tài),如下所示。
?
無效 led_control() { 字符串狀態(tài) = "OFF"; String act_state = server.arg("state"); if(act_state == "1") { digitalWrite(LED,HIGH); //LED 開啟 狀態(tài) = "ON"; } 其他 { 數(shù)字寫入(LED,LOW);//LED關(guān)閉 狀態(tài)=“關(guān)閉”; } server.send(200,“文本/平面”,狀態(tài)); }
?
然后,為了將 NodeMCU 連接到互聯(lián)網(wǎng),我們調(diào)用WiFi.begin() 函數(shù)并傳遞網(wǎng)絡(luò) SSID 和密碼作為其參數(shù)。使用WiFi.status()檢查網(wǎng)絡(luò)連接是否成功,連接成功后,在串行監(jiān)視器上打印一條消息,其中包含所連接設(shè)備的 IP 地址。
?
WiFi.begin(ssid, 密碼); 而(WiFi.status()!= WL_CONNECTED) { Serial.print(“正在連接......”); } Serial.println(""); Serial.print("連接到"); 序列號.println(ssid); Serial.print("IP地址:"); Serial.println(WiFi.localIP());
?
然后,為了在客戶端請求索引為“/”、“/led_set”和“/adcread”的URL時調(diào)用定義的函數(shù),如“handleRoot”、“l(fā)ed_control”和“sensor_data”,定義了以下代碼塊。
?
server.on("/", handleRoot); server.on("/led_set", led_control); server.on("/adcread", sensor_data); server.begin();
?
基于 AJAX 和 ESP8266 的 Web 服務(wù)器測試
上傳代碼后,就可以測試項目了。首先,確保您的熱點已打開。然后在打開電路之前檢查連接。然后,打開電路的電源。在我們的例子中,我們使用 USB 為項目供電,但也可以為 NodeMCU 提供外部 5v 直流電源。
打開電源后,就可以獲取nodeMCU的IP地址了。這可以使用 Arduino IDE 的串行監(jiān)視器找到。打開串口監(jiān)視器,按一下 NodeMCU 的 Reset 按鈕,串口監(jiān)視器上應(yīng)該會打印 NodeMCU 的 IP 地址。記下 IP 地址并將其粘貼到任何 Web 瀏覽器的 URL 欄上。
請注意,您的設(shè)備必須連接到與 Nodemcu 連接的同一網(wǎng)絡(luò)。在地址欄中輸入 IP 后,您應(yīng)該會在瀏覽器中獲取項目的網(wǎng)頁。如果你得到它,那么現(xiàn)在你可以在這里監(jiān)控傳感器值,你還可以從瀏覽器控制 LED 的狀態(tài)。
/*ESP8266 AJAX 網(wǎng)絡(luò)服務(wù)器的 Arduino 代碼
www.circuitdigest.com ;
*/
#include
#include
#include
#include "index.h"
#define LED D0
const char* ssid = "admin";
const char* 密碼 = "12345678";
ESP8266WebServer 服務(wù)器(80);
void handleRoot()
{
String s = 網(wǎng)頁;
server.send(200, "text/html", s);
}
void sensor_data()
{
int a = analogRead(A0);
國際溫度=一/4.35;
字符串傳感器值 = 字符串(溫度);
server.send(200, "文本/平面", sensor_value);
}
無效 led_control()
{
字符串狀態(tài) = "OFF";
String act_state = server.arg("state");
if(act_state == "1")
{
digitalWrite(LED,HIGH); //LED 開啟
狀態(tài) = "ON";
}
其他
{
數(shù)字寫入(LED,LOW);//LED關(guān)閉
狀態(tài)=“關(guān)閉”;
}
server.send(200,“文本/平面”,狀態(tài));
}
無效設(shè)置(無效)
{
Serial.begin(115200);
WiFi.begin(ssid, 密碼);
序列號.println("");
pinMode(LED,輸出);
而(WiFi.status()!= WL_CONNECTED)
{
Serial.print(“正在連接......”);
}
Serial.println("");
Serial.print("連接到");
序列號.println(ssid);
Serial.print("IP地址:");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/led_set", led_control);
server.on("/adcread", sensor_data);
server.begin();
}
無效循環(huán)(無效)
{
server.handleClient();
}
?
評論
查看更多