零基础入门学用物联网(ESP8266) 第一部分 基础知识篇(四)

参考教程:https://www.bilibili.com/video/BV1L7411c7jw/?spm_id_from=333.1387.favlist.content.click

七、ESP8266作为网络客户端

1、ESP8266作为网络客户端的行为

(1)网络客户端有很多种类型,像日常生活中使用的手机、电脑,以及ESP866-NodeMCU开发板,都可以作为网络客户端,向服务器发出请求。

(2)如果ESP866-NodeMCU作为客户端,接入一个与互联网连接的Wi-Fi网络中,那么ESP866-NodeMCU想要访问其它服务器的网站首页,大致流程如下所示。

2、使用ESP8266HTTPClient库实现网络通讯

(1)HTTPClient类是使用HTTP协议的网络客户端的抽象,该类的成员函数有如下几个(包括但不限于):

①begin函数:初始化HTTP请求并设置目标地址(URL,请求路径),并返回设置结果,True表示准备就绪,False表示URL格式错误或内存不足。

该函数有多种重载形式,最常用的是只有一个参数的重载形式,参数为指定URL的字符串类型数据

②GET函数:使用GET方法发送HTTP请求,并返回服务器响应的状态码,该函数无参数。

③POST函数:使用POST方法发送HTTP请求,并返回服务器响应的状态码,该函数无参数。

④getString函数:获取服务器HTTP响应报文中响应体的内容,以字符串的形式返回,该函数无参数。

⑤end函数:关闭ESP8266与服务器的连接,该函数无参数。

(2)使用ESP8266连接外部服务器,请求网址"http://www.example.com"的信息,其程序流程如下图所示。

(3)将以下示例程序粘贴到代码区中,然后将其编译并上传NodeMCU开发板,这样即可请求网址"http://www.example.com"的信息,并将返回的内容打印在串口监视器中。

cpp 复制代码
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#define URL "http://www.example.com"  //测试HTTP请求用的URL,注意网址前面必须添加"http://"

void setup() {
  Serial.begin(9600);
 
  WiFi.mode(WIFI_STA);  //设置ESP8266工作模式为无线终端模式
  WiFi.begin("Zevalin_Computer", "00114514");  //连接Wi-Fi
 
  //等待Wi-Fi连接
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi Connected!");
  
  httpClientRequest();   //发送HTTP请求
}
 
void loop(){

}
 
//发送HTTP请求并且将服务器响应通过串口输出
void httpClientRequest(){
 
  //创建 HTTPClient 对象
  HTTPClient httpClient;
 
  //通过begin函数配置请求地址
  httpClient.begin(URL); 
  Serial.print("URL: "); Serial.println(URL);
 
  //通过GET函数启动连接并发送HTTP请求
  int httpCode = httpClient.GET();
  Serial.print("Send GET request to URL: ");
  Serial.println(URL);
  
  //如果服务器响应HTTP_CODE_OK(200),则从服务器获取响应体信息并通过串口输出
  //如果服务器不响应HTTP_CODE_OK(200),则将服务器响应状态码通过串口输出
  if (httpCode == HTTP_CODE_OK) {
    // 使用getString函数获取服务器响应体内容
    String responsePayload = httpClient.getString();
    Serial.println("Server Response Payload: ");
    Serial.println(responsePayload);
  }
  else {
    Serial.println("Server Respose Code:");
    Serial.println(httpCode);
  }
 
  //关闭ESP8266与服务器连接
  httpClient.end();
}

①WiFi.mode(val):配置ESP8266以val参数指定的模式工作,val的可选项有WIFI_OFF(关闭Wi-Fi)、WIFI_STA(无线终端模式)、WIFI_AP(接入点模式)、WIFI_AP_STA(接入点-无线终端双模式)。

②WiFi.begin(ssid, password):控制ESP8266接入Wi-Fi网络,其中ssid参数为Wi-Fi网络名,password为Wi-Fi网络密码。

3、使用WiFiClient库实现网络通讯

(1)WiFiClient类是使用Wi-Fi接入互联网的网络客户端的抽象,它比HTTPClient类的局限性更小(也就是不局限于使用HTTP协议),该类的成员函数有如下几个(包括但不限于):

①print函数:向服务器发送HTTP请求报文,函数参数为字符串类型的报文内容,报文内容需要程序员按照通信协议的格式自行构建(下图所示的是HTTP请求报文格式,CLRF为换行符)。

②connect函数:与服务器建立连接,第一个参数为被连接网络服务器的网址,第二个参数为被连接网络服务器的端口编号(HTTP协议的熟知端口号为80)。

③connected函数:如果ESP8266已与服务器建立连接,则返回True,否则返回False,该函数无参数。

④available函数:如果ESP8266接收到服务器返回的响应信息,则返回True,否则返回False,该函数无参数。

⑤readStringUntil函数:获取服务器返回的响应信息,直到遇到指定字符,返回字符串类型数据,该指定字符即为函数参数。

⑥find函数:获取服务器返回的响应信息,判断响应信息中有没有指定字符串,该指定字符串即为函数参数,有指定字符串则返回True,否则返回False。

(2)使用ESP8266连接外部服务器,请求网址"http://www.example.com"的信息,其程序流程如下图所示。

(3)将以下示例程序粘贴到代码区中,然后将其编译并上传NodeMCU开发板,这样即可请求网址"http://www.example.com"的信息,并将返回的内容打印在串口监视器中。

cpp 复制代码
#include <ESP8266WiFi.h>
 
const char* host = "www.example.com"; // 目标网络服务器地址
const int httpPort = 80;              // http熟知端口号
 
void setup(){
  Serial.begin(9600);
  Serial.println("");
 
  WiFi.mode(WIFI_STA);   //设置ESP8266工作模式为无线终端模式
  WiFi.begin("Zevalin_Computer", "00114514");  //连接Wi-Fi
 
  //等待Wi-Fi连接
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");
  
  wifiClientRequest();  
}
 
void loop(){

}
 
// 向服务器发送HTTP请求
void wifiClientRequest(){
  // 建立Wi-Fi客户端对象,对象名称client
  WiFiClient client;    
 
  // 建立字符串,用于HTTP请求(注意请求行和请求头的格式)
  String httpRequest =  String("GET /") + " HTTP/1.1\r\n" +
                        "Host: " + host + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
  
  // 通过串口输出连接服务器名称,以便查阅连接服务器的网址                      
  Serial.print("Connecting to "); 
  Serial.print(host); 
 
  // 连接网络服务器
  if(client.connect(host, httpPort)){ 
    Serial.println(" Success!");        // 连接成功后串口输出"Success"信息
    
    client.print(httpRequest);          // 向服务器发送HTTP请求
    Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容
    Serial.println(httpRequest);     
    
    // 通过串口输出网络服务器响应信息
    Serial.println("Web Server Response:");        
    while (client.connected() || client.available()){ 
      if (client.available()){
        String line = client.readStringUntil('\n');
        Serial.println(line);
      }
    }
    
    client.stop();                      // 断开与服务器的连接
    Serial.print("Disconnected from "); // 通过串口输出断开连接信息
    Serial.print(host);
    
  }
  else{ 
    Serial.println(" connection failed!");   // 如果连接不成功,则通过串口输出"连接失败"信息
    client.stop();
  }  
}

八、ESP8266 HTTP协议数据通讯

1、客户端向服务器发送数据信息

(1)在这个示例中,两块ESP8266连接同一个Wi-Fi网络,一块作为服务器,另一块作为客户端,ESP8266客户端将会通过HTTP协议向ESP8266服务器发送信息,最终实现的效果是,通过客户端ESP8266开发板上的按键来"遥控"服务器上的LED点亮和熄灭。

①在运行过程中,客户端ESP8266将会实时检测板上的按键状态,并且把按键状态发送给服务器。

②服务器在接收到客户端按键状态后,可以根据客户端按键状态来控制服务器端板上的LED点亮和熄灭。

(2)服务器端程序:

①程序任务:

1\]接收客户端发来的HTTP请求并且解析信息中的数据信息。 \[2\]将解析的数据信息通过串口监视器显示供用户查看。 \[3\]将解析的客户端按键状态信息用于控制服务器端板上LED的点亮和熄灭。 ②程序框图: ![](https://i-blog.csdnimg.cn/direct/9f2cea16fa7b43a7afec95f9081bfdce.png) ③程序代码: ```cpp #include #include // 使用WiFiMulti库 #include // 使用WebServer库 ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti' ESP8266WebServer server(80); // 建立网络服务器对象,该对象用于响应HTTP请求 IPAddress local_IP(192, 168, 10, 135); // ESP8266-NodeMCU联网后的IP IPAddress gateway(192, 168, 10, 1); // 网关IP(通常网关IP是WiFI路由IP) IPAddress subnet(255, 255, 255, 0); // 子网掩码 IPAddress dns(192, 168, 10, 1); // 局域网DNS的IP(通常局域网DNS的IP是Wi-FI路由的IP) void setup(void){ Serial.begin(9600); // 启动串口通讯 Serial.println(""); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // 设置开发板网络环境(配置开发板、网关的IP地址及子网掩码,局域网DNS的IP可选,非必须配置) if(!WiFi.config(local_IP, gateway, subnet)) { Serial.println("Failed to Config ESP8266 IP"); } wifiMulti.addAP("Zevalin_Computer", "00114514"); wifiMulti.addAP("Zevalin_esp8266", "00114514"); Serial.println("Connecting ..."); while (wifiMulti.run() != WL_CONNECTED) { delay(250); Serial.print('.'); } Serial.println('\n'); Serial.print("Connected to "); Serial.println(WiFi.SSID()); Serial.print("IP address:\t"); Serial.println(WiFi.localIP()); server.on("/update", handleUpdate); // 配置处理"/update"请求的函数 server.begin(); // 启动网站服务 Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); // 检查http服务器访问 } void handleUpdate(){ float floatValue = server.arg("float").toFloat(); // 获取客户端发送HTTP信息中的浮点数值 int intValue = server.arg("int").toInt(); // 获取客户端发送HTTP信息中的整数数值 int buttonValue = server.arg("button").toInt(); // 获取客户端发送HTTP信息中的按键控制量 server.send(200, "text/plain", "Received"); // 发送http响应 buttonValue == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH); // 通过串口监视器输出获取到的变量数值 Serial.print("floatValue = "); Serial.println(floatValue); Serial.print("intValue = "); Serial.println(intValue); Serial.print("buttonValue = "); Serial.println(buttonValue); Serial.println("================="); } ``` \[1\]IPAddress是类对IP地址的抽象,创建IPAddress类时,构造函数的参数为IP地址各组的数值,其中每8位为一组(IPv4)。 \[2\]WiFi.config函数用于配置开发板、网关的IP地址及子网掩码,局域网DNS的IP地址是可选参数,非必须配置。 (3)客户端程序: ①程序任务: \[1\]客户端通过HTTP协议向服务器发送信息。 \[2\]信息中包含客户端按键开关引脚状态,用于控制服务器板上LED的点亮和熄灭。 \[3\]信息中包含测试数据。 ②程序框图: ![](https://i-blog.csdnimg.cn/direct/b226ca377ce54095868a63da3b08260c.png) ③程序代码: ```cpp #include #include // 使用WiFiMulti库 #define buttonPin D3 // 按钮引脚D3 ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti' bool buttonState; // 存储客户端按键控制数据 float clientFloatValue; // 存储客户端发送的浮点型测试数据 int clientIntValue; // 存储客户端发送的整数型测试数据 const char* host = "192.168.10.135"; // 即将连接服务器的网址/IP地址 const int httpPort = 80; // 即将连接服务器的端口 void setup(void){ Serial.begin(9600); Serial.println(""); pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式 wifiMulti.addAP("Zevalin_Computer", "00114514"); wifiMulti.addAP("Zevalin_esp8266", "00114514"); Serial.println("Connecting ..."); while(wifiMulti.run() != WL_CONNECTED){ delay(250); Serial.print('.'); } Serial.println('\n'); Serial.print("Connected to "); Serial.println(WiFi.SSID()); Serial.print("IP address:\t"); Serial.println(WiFi.localIP()); } void loop(void){ // 获取按键引脚状态 buttonState = digitalRead(buttonPin); // 改变测试用变量数值用于服务器端接收数据检测 clientFloatValue += 1.5; clientIntValue += 2; // 向服务器发送请求 wifiClientRequest(); delay(1000); } void wifiClientRequest(){ WiFiClient client; // 将需要发送的数据信息放入客户端请求 String url = "/update?float=" + String(clientFloatValue) + "&int=" + String(clientIntValue) + "&button=" + String(buttonState); // 建立字符串,用于HTTP请求 String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n" + "\r\n"; Serial.print("Connecting to "); Serial.print(host); if (client.connect(host, httpPort)){ Serial.println(" Sucess"); client.print(httpRequest); // 向服务器发送HTTP请求 Serial.println("Sending request: "); // 通过串口输出HTTP请求信息内容 Serial.println(httpRequest); } else{ Serial.println(" failed"); //如果连接失败则串口输出信息告知用户 } client.stop(); } ``` ### 2、客户端向服务器请求数据信息

相关推荐
智链RFID15 小时前
从需求到落地:企业RFID系统选择的智慧之道
物联网·rfid·数字化转型·企业信息化·仓储管理
RFID科技的魅力16 小时前
零门槛上手!CP300R触屏RFID打印机操作体验与打印效果实测
大数据·物联网·rfid
FreakStudio17 小时前
MicroPython+PycoClaw,3 分钟搞定 ESP32 跑上 OpenClaw!
python·单片机·嵌入式·电子diy
三佛科技-1873661339720 小时前
FT838NB1-RT原边反馈5级能效电源控制器5V1A芯片电路图及管脚定义
单片机·嵌入式硬件·物联网
逆小舟20 小时前
【SWM320】FreeRTOS搭建工程——1、框架学习
嵌入式·c·rtos
小杨同学4921 小时前
STM32 进阶封神之路(二十二):DMA 实战全攻略 ——ADC 采集 + 串口收发 + 内存复制(库函数 + 代码落地)
后端·单片机·嵌入式
隔壁大炮1 天前
速度环实现行进&角度环实现转弯
嵌入式·pid·江协科技·平衡小车
busideyang1 天前
STM32中__weak(弱定义)函数核心总结
c语言·stm32·单片机·嵌入式硬件·嵌入式
421!1 天前
ESP32学习笔记之UART
笔记·学习·嵌入式·esp32·通信