NodeMcu arduino ESP8266 网络服务器进行通讯请求(心知天气示例)

12 篇文章 9 订阅
6 篇文章 0 订阅

NodeMcu arduino ESP8266 网络服务器进行通讯请求[太极创客学习整理]

例如:使用ESP8266HTTPClient库实现网络通讯

点击进入官方太极创客



前言

因此,在我们使用ESP8266开发项目时,更多的时候是使用WiFiClient库来实现物联网通讯功能。换句话说,我个人认为WiFiClient库的重要性和实用性要高于ESP8266HTTPClient库。


提示:以下是本篇文章正文内容,下面案例可供参考

一、如何使用ESP8266库 实现网络通讯

方式1、使用ESP8266HTTPClient库实现网络通讯

/**********************************************************************
  项目名称/Project          : 零基础入门学用物联网
  程序名称/Program name     : HTTPClient_request_basic
  团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
  作者/Author              : Dapenson
  日期/Date(YYYYMMDD)     : 20200325
  程序目的/Purpose          :
  此程序用于演示如何使用ESP8266来向www.example.com网站服务器发送HTTP请求并通过串口
  监视器将网站服务器响应信息通过串口监视器显示出来。
  -----------------------------------------------------------------------
  修订历史/Revision History  
  日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
  20200411      CYNO朔           001        将请求服务器改为www.example.com
  -----------------------------------------------------------------------
  本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
  该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
  http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
 
// 测试HTTP请求用的URL。注意网址前面必须添加"http://"
#define URL "http://www.example.com"
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "taichimaker";
const char* password = "12345678";
 
void setup() {
  //初始化串口设置
  Serial.begin(9600);
 
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
 
  //开始连接wifi
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,连接成功打印IP
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi Connected!");
  
  httpClientRequest();  
}
 
void loop() {}
 
// 发送HTTP请求并且将服务器响应通过串口输出
void httpClientRequest(){
 
  //重点1 创建 HTTPClient 对象
  HTTPClient httpClient;
 
  //重点2 通过begin函数配置请求地址。此处也可以不使用端口号和PATH而单纯的
  httpClient.begin(URL); 
  Serial.print("URL: "); Serial.println(URL);
 
  //重点3 通过GET函数启动连接并发送HTTP请求
  int httpCode = httpClient.GET();
  Serial.print("Send GET request to URL: ");
  Serial.println(URL);
  
  //重点4. 如果服务器响应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);
  }
 
  //重点5. 关闭ESP8266与服务器连接
  httpClient.end();
}

程序重点讲解
重点1. 声明HTTPClient对象,对象名称httpClient。后续程序中,我们将使用对象httpClient控制ESP8266的网络通讯。
重点2. 通过ESP8266HTTPClient库的begin函数来设置ESP8266发送HTTP请求的目标URL。
重点3. 通过ESP8266HTTPClient库的GET函数向服务器发送HTTP请求。
重点4. 以上重点3中GET函数的返回值是网络服务器响应状态码。根据该状态码,我们可以判断服务器是否成功接收到了ESP8266客户端的请求。如果服务器成功接收到请求,我们就可以在接下来使用getString函数来获取服务器响应报文(服务器响应体)信息,并且将该信息传递给responsePayload变量以便我们在后面通过串口监视器显示服务器响应报文。(这一报文信息正是www.example.com网站的首页HTML源代码)。
重点5.执行完以上操作后,我们将关闭ESP8266与服务器连接。这里是通过ESP8266HTTPClient库的end函数来实现这一操作的。

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

代码如下(示例):

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : wifiClient_request_basic
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : Dapenson
日期/Date(YYYYMMDD)     : 20200325
程序目的/Purpose          : 
此程序用于演示如何使用esp8266作为互联网客户端向www.example.com网站服务器发送http请求,
并且将网站服务器响应的信息输出在屏幕中
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
#include <ESP8266WiFi.h>

const char* host = "www.example.com"; // 网络服务器地址
const int httpPort = 80;              // http端口80

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "taichimaker";
const char* password = "12345678";

void setup() {
  //初始化串口设置
  Serial.begin(9600);
  Serial.println("");
 
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
 
  //开始连接wifi
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,连接成功打印IP
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");
  
  wifiClientRequest();  
}

void loop(){}

// 向服务器发送HTTP请求
void wifiClientRequest(){
  // 建立WiFi客户端对象,对象名称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); 

  // 连接网络服务器,以下段落中的示例程序为本程序重点1
  // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
  // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
  if (client.connect(host, httpPort)){ 
    Serial.println(" Success!");        // 连接成功后串口输出“Success”信息
    
    client.print(httpRequest);          // 向服务器发送HTTP请求
    Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
    Serial.println(httpRequest);     
    
    // 通过串口输出网络服务器响应信息, 以下段落中的示例程序为本程序重点2
    // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
    // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
    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();
  }  
}

重点1:实现网络服务器连接
这部分逻辑判断语句中的判断条件是client.connect(host, httpPort)的返回值。ESP8266所实现的网络客户端是通过connect函数来实现与网络服务器的连接的。被连接的网络服务器网址为connect函数的第一个参数,即host。这里的第二个参数httpPort则是连接网络服务器的端口编号。关于host 和 httpPort的具体定义都在程序刚一开始的部分。
如果ESP8266所建立的网络客户端成功与网络服务器建立了连接,connect函数将会返回“真”,否则将会返回“假”。利用connect函数返回值,程序可以根据网络服务器的连接状况来决定具体执行哪一个操作。即:
– 连接成功则通过后续的while循环语句来获取网络服务器的HTTP响应信息,并且将信息通过串口输出。
– 连接不成功则通过串口输出“连接失败”信息。
<--------------------------------------------------------------------------------------------------------------------------------------------------------->重点2:获取网络服务器响应信息并且通过串口输出
这里的 while (client.connected() || client.available())循环语句判断条件由两个函数的返回值来决定。
第一个条件是 client.connected() 的返回值。connected()这个函数用于检查当前ESP8266与网络服务器的连接情况。如果连接状态为“真”,则返回真。否则返回“假”。
第二个条件是 client.available()的返回值。available()函数用于检查网络客户端是否有接收到服务器发来的信息。如果有信息则返回真,否则返回“假”。
利用以上两个条件进行“或”运算所得到的结果即是这里while循环语句的判断条件。换句话说,就是当ESP8266与服务器保持连接以及服务器有信息发送给ESP8266这两个条件满足一个,while循环语句体就会执行循环。当这两个条件都不满足了,则跳出循环。

二、Stream – ESP8266物联网应用

认识并了解 Stream

Stream这个概念可能很多朋友会感到陌生。其实在过去的学习和开发中,我们已经使用Stream很久了。Stream对于ESP8266-Arduino语言来说指的是数据序列。请留意:在C++编程中Stream常被翻译作“流”。我们认为将Stream称为数据序列更加直观。因为数据序列这一概念有两个很关键特点。

Stream特点

第一个特点是“序”,即数据序列不能是杂乱无章的数据罗列。
第二个特点是“列”,即数据序列是排成一列的。

综上所述,数据序列可以理解为一列有先后顺序的数据。为了让您对数据序列也就是Stream数据有更直观的认识,这里我们将通过几个实例来向您说明Stream数据是什么。

示例1 使用串口监视器演示Stream概念

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : stream_readString
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200308
程序目的/Purpose          : 
Stream类用于处理字符数据流或二进制数据流。Stream类是不能被直接调用的。
然而当我们使用基于Stream类的库时,都会调用Stream中的内容。
 
以下Arduino库及相应库中的类都是基于Stream类所实现的。
 库                  类
Serial              Serial
SoftwareSerial    SoftwareSerial
Ehternet          EthernetClient
ESP8266FS         File
SD                File
Wire              Wire
GSM               GSMClient
WifiClient        WiFiClient
WiFiServer        WiFiServer
WiFiUDP           WiFiUDP
WiFiClientSecure  WiFiClientSecure
 
此程序使用Serial库来演示Stream类中的available()以及
readString函数的使用方法。
available函数将会返回开发板所接收到的stream中等待读取的字节数。
readString函数将读取stream中的字符并存储到字符中。
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
 
void setup() {
  // 启动串口通讯
  Serial.begin(9600); 
  Serial.println();
}
 
void loop() {  
  if (Serial.available()){                    // 当串口接收到信息后
    String serialData = Serial.readString();  // 将接收到的信息使用readString()存储于serialData变量
    Serial.print(serialData);                 // 以便查看serialData变量的信息
  }
}

在本示例中,我们使用了Serial.available来判断ESP8266开发板是否接收到串口数据。这里的开发板通过串口所接收到的数据就是Stream数据。另外,程序通过Serial.println语句将接收到的Stream数据通过串口输出并显示在串口监视器中,这里ESP8266通过串口所输出的数据也是Stream数据。换句话说,ESP8266开发板通过串口收发的数据都是Stream数据。

示例2 使用HTTP请求和响应信息演示Stream概念

以下示例程序是上一节课“3-4-1 ESP8266网络客户端基本操作”中的第二个示例程序。该示例程序中,ESP8266开发板通过client.print向服务器发送HTTP请求。这里开发板所发出的HTTP请求信息就是Stream数据。另外,以下示例程序中,ESP8266开发板通过client.readStringUntil来读取服务器响应信息。这里服务器响应信息也是Stream数据。

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : wifiClient_request_basic
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : Dapenson
日期/Date(YYYYMMDD)     : 20200325
程序目的/Purpose          : 
此程序用于演示如何使用esp8266作为互联网客户端向www.example.com网站服务器发送http请求,
并且将网站服务器响应的信息输出在屏幕中
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
20200411      CYNO朔           001        将请求服务器改为www.example.com
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/
#include <ESP8266WiFi.h>
 
const char* host = "www.example.com"; // 网络服务器地址
const int httpPort = 80;              // http端口80
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "dajiating";
const char* password = "xxxx";
 
void setup() {
  //初始化串口设置
  Serial.begin(9600);
  Serial.println("");
 
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
 
  //开始连接wifi
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,连接成功打印IP
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");
  
  wifiClientRequest();  
}
 
void loop(){}
 
// 向服务器发送HTTP请求
void wifiClientRequest(){
  // 建立WiFi客户端对象,对象名称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); 
 
  // 连接网络服务器,以下段落中的示例程序为本程序重点1
  // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
  // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
  if (client.connect(host, httpPort)){ 
    Serial.println(" Success!");        // 连接成功后串口输出“Success”信息
    
    client.print(httpRequest);          // 向服务器发送合同谈判请求
    Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
    Serial.println(httpRequest);     
    
    // 通过串口输出网络服务器响应信息, 以下段落中的示例程序为本程序重点2
    // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
    // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
    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();
  }  
}

示例3 使用File对象演示Stream概念

该示例程序通过dataFile.println来向文件中写入信息。使用dataFile.find从闪存文件内容里查找指定信息。使用dataFile.readString来获取信息。这些操作都是针对Stream数据的操作。

/**********************************************************************
项目名称/Project           : 零基础入门学用物联网
程序名称/Program name      : file_stream_demo
团队/Team                 : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author               : CYNO 朔 
日期/Date(YYYYMMDD)      : 20200506
程序目的/Purpose           : 
通过File对象演示Stream操作
***********************************************************************/
#include <FS.h>  
 
String file_name = "/taichi-maker/notes.txt"; //被读取的文件位置和名称
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
 
  // 启动SPIFFS
  if(SPIFFS.begin()){ 
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息
  dataFile.println("Hello IOT World.");       // 向dataFile写入字符串信息
  dataFile.close();                           // 完成文件写入后关闭文件
  Serial.println("Finished Writing data to SPIFFS");
 
  // 使用find函数从dataFile中找到指定信息
  Serial.print("Try to find IOT in ");Serial.println(file_name); 
   
  dataFile = SPIFFS.open(file_name, "r");     // 以“r”模式再次打开闪存文件
  if (dataFile.find("IOT")){                  // 在闪存文件中查找文字"IOT"
    Serial.print("Found IOT in file: ");      // 如果找到则告知用户找到文字"IOT"
    Serial.println(file_name);         
  }
 
  // 使用readString读取执行完find函数后的dataFile内容并显示与串口监视器
  Serial.println("Use readString to get contents of dataFile after find");
  Serial.println(dataFile.readString());
    
  dataFile.close();                           // 完成操作后关闭文件  
}
 
void loop() {}

Stream是ESP8266-Arduino开发环境中的一种数据类型。Serial库,WiFiClient库,FS库所建立的对象都可以处理Stream数据。

以下列表中的库也可以处理Stream数据。

在这里插入图片描述

三、 示例如下

使用ESP8266客户端向ESP8266服务器发送数据

首先我们来看第一个示例。在这个示例中,ESP8266客户端将会通过HTTP协议向ESP8266服务器发送信息。在运行过程中,客户端ESP8266将会实时检测板上的按键状态,并且把按键状态发送给服务器。服务器在接收到客户端按键状态后,可以根据客户端按键状态来控制服务器端板上的LED点亮和熄灭。最终实现的效果是,我们可以通过客户端ESP8266开发板上的按键来“遥控”服务器上的LED点亮和熄灭。

注意,下示例中的服务器端和客户端ESP8266必须连接同一WiFi网络,方可实现数据通讯。

服务器端程序:
– 接收客户端发来的http请求并且解析信息中的数据信息
– 将解析的数据信息通过串口监视器显示供用户查看
– 将解析的客户端按键状态信息用于控制服务器端板上LED的点亮和熄灭

代码如下(示例):

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : csd_server
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200228
程序目的/Purpose          : 
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。
 
此代码为客户端代码。此代码主要功能:
    - 接收客户端发来的http请求
    - 解析客户端请求中的数据信息
    - 将解析的数据信息通过串口监视器显示供用户查看
    - 将解析的客户端按键状态信息用于控制板上LED的点亮和熄灭
    
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
20200229      CYNO朔           0.01       加入IP设置
 
***********************************************************************/
 
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>   // 使用WiFiMulti库 
#include <ESP8266WebServer.h>   // 使用WebServer库
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
 
ESP8266WebServer server(80);    // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
 
IPAddress local_IP(192, 168, 0, 123); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 0, 1);    // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0);   // 设置子网掩码
IPAddress dns(192,168,0,1);           // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
 
void setup(void){
  Serial.begin(9600);          // 启动串口通讯
  Serial.println("");
 
  pinMode(LED_BUILTIN, OUTPUT);   
  digitalWrite(LED_BUILTIN, HIGH);
  
  // 设置开发板网络环境
  if (!WiFi.config(local_IP, gateway, subnet)) {
    Serial.println("Failed to Config ESP8266 IP"); 
  } 
  
  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 ...");                            // 则尝试使用此处存储的密码进行连接。
  
  // 尝试进行wifi连接。
  while (wifiMulti.run() != WL_CONNECTED) { 
    delay(250);
    Serial.print('.');
  }
 
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // 通过串口监视器输出连接的WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // 通过串口监视器输出ESP8266-NodeMCU的IP
 
  server.on("/update", handleUpdate);        // 处理服务器更新函数
  
  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("=================");    
}

客户端程序:
– 客户端通过HTTP协议向服务器发送信息
– 信息中包含客户端按键开关引脚状态用于控制服务器板上LED的点亮和熄灭
– 信息中还包含测试数据以便我们更好的了解如何使用ESP8266发送和接收物联网数据信息

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : csd_client
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200228
程序目的/Purpose          : 
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。
 
此代码为客户端代码。此代码主要功能:
    - 通过HTTP协议向服务器发送HTTP请求
    - HTTP请求中包含客户端按键开关引脚状态和程序测试数据
-----------------------------------------------------------------------
修订历史/Revision History  
日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
-----------------------------------------------------------------------
http信息发送说明
192.168.0.123/update?float=1.5&int=2&button=0
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>   // 使用WiFiMulti库 
 
#define buttonPin D3            // 按钮引脚D3
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
 
bool buttonState;       //存储客户端按键控制数据
float clientFloatValue; //存储客户端发送的浮点型测试数据
int clientIntValue;     //存储客户端发送的整数型测试数据
 
const char* host = "192.168.0.123";    // 即将连接服务器网址/IP
const int httpPort = 80;               // 即将连接服务器端口
 
void setup(void){
  Serial.begin(9600);                  // 启动串口通讯
  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 ...");                            // 则尝试使用此处存储的密码进行连接。
  
  while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
    delay(250);
    Serial.print('.');
  }
 
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // 通过串口监视器输出连接的WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // 通过串口监视器输出ESP8266-NodeMCU的IP
}
 
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)) {  //如果连接失败则串口输出信息告知用户然后返回loop
    Serial.println(" Sucess");
    
    client.print(httpRequest);          // 向服务器发送HTTP请求
    Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
    Serial.println(httpRequest);        
  } else{
    Serial.println(" failed");
  }
  
  client.stop();                         
}

使用ESP8266客户端从ESP8266服务器获取数据

这一示例中,客户端会定时向服务器发送请求信息。服务器一旦接收到客户端请求后,会把服务器开发板上的按键引脚状态发送给客户端。客户端在接收到这一信息后,会利用该信息来控制客户端的LED点亮和熄灭。最终实现的效果是,通过控制服务器端的板上按键,我们可以控制客户端板上LED的点亮和熄灭。

注意,下示例中的服务器端和客户端ESP8266必须连接同一WiFi网络,方可实现数据通讯。

服务器端程序:
– 实时获取服务器端开发板上按钮引脚状态
– 当有客户端向ESP8266服务器的/update发送请求时,将服务器的按键引脚状态通过响应信息回复给客户端

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : cgd_server
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200228
程序目的/Purpose          : 
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。用户可通过服务器端开发板上按钮控制客户端的板上LED点亮和熄灭
 
此代码为服务器端代码。此代码主要功能:
  - 实时获取服务器端开发板上按钮引脚状态
  - 当有客户端向ESP8266服务器的/update发送请求时,将服务器的按键引脚状态
    通过响应信息回复给客户端
***********************************************************************/
#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)
 
IPAddress local_IP(192, 168, 0, 123); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 0, 1);    // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0);   // 设置子网掩码
IPAddress dns(192,168,0,1);           // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
 
bool pinState;                 // 存储引脚状态用变量
 
void setup(){
  Serial.begin(9600);          // 启动串口通讯
  Serial.println("");
 
  pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
 
  // 设置开发板网络环境
  if (!WiFi.config(local_IP, gateway, subnet)) {
    Serial.println("Failed to ESP8266 IP"); 
  } 
 
  //通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("taichi-maker1", "12345678"); // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 用户可自行增加、修改、删除此处网络连接信息。
  wifiMulti.addAP("taichi-maker3", "13572468"); 
 
  // 尝试网络连接                                            
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  
    delay(1000);                             
    Serial.print(i++); Serial.print(' ');   
  }                                          
                                             
  // WiFi连接成功后,通过串口监视器输出连接信息 
  Serial.println("");                     
  Serial.print("Connected to ");            
  Serial.println(WiFi.SSID());              
  Serial.print("IP address:\t");            
  Serial.println(WiFi.localIP());           
 
  // 设置网络服务器                  
  esp8266_server.on("/update", handleUpdate);  // 处理客户端HTTP请求LED状态  
  
  esp8266_server.begin(); 
  Serial.println("HTTP esp8266_server started");
}
 
void loop(){
  pinState = digitalRead(buttonPin); // 获取引脚状态
  esp8266_server.handleClient();     // 处理http服务器访问 
}          
 
// 处理客户端HTTP请求LED状态button: 1
void handleUpdate() {
  String pinStateStr;
  pinState == HIGH ? pinStateStr = "1" : pinStateStr = "0";
  esp8266_server.send(200, "text/html", "buttonState: " + pinStateStr); 
}

客户端程序:
– 定时向服务器发送请求,从而获取服务器开发板上按钮状态
– 将服务器端发来的按钮引脚电平状态解析为数字量,并且用该数字量控制板上LED点亮和熄灭

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : cgd_client
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200228
程序目的/Purpose          : 
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。
 
此代码为客户端代码。此代码主要功能:
    - 定时向服务器发送请求信息,从而获取服务器开发板上按钮状态
    - 将服务器端发来的按钮引脚电平状态解析为数字量,并且用该数字量控制板上LED点亮和熄灭
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
 
ESP8266WiFiMulti wifiMulti;           // 建立ESP8266WiFiMulti对象
 
const char* host = "192.168.0.123";   // 网络服务器IP
const int httpPort = 80;              // http端口80
 
void setup(){
  Serial.begin(9600);          
  Serial.println("");
 
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  
  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) { // 尝试进行wifi连接。
    delay(1000);
    Serial.print(i++); Serial.print(' ');
  }
  
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // IP
}
 
void loop(){
  wifiClientRequest();  
  delay(3000);
}
 
void wifiClientRequest(){
  WiFiClient client;          // 建立WiFiClient对象
 
  bool buttonState;     // 储存服务器按钮状态变量  
         
  Serial.print("Connecting to "); Serial.print(host);
 
  // 连接服务器
  if (client.connect(host, httpPort)){
    Serial.println(" Success!");
    
    // 建立客户端请求信息
    String httpRequest =  String("GET /update") + " HTTP/1.1\r\n" +
                          "Host: " + host + "\r\n" +
                          "Connection: close\r\n" +
                          "\r\n";
                          
    // 发送客户端请求
    Serial.println("Sending request: ");Serial.print(httpRequest);  
    client.print(httpRequest);
 
    // 获取服务器响应信息中的按钮状态信息
    while (client.connected() || client.available()){
      if(client.find("buttonState:")){      
        buttonState = client.parseInt(); 
        Serial.print("buttonState: " ); 
        Serial.println(buttonState); 
      }
    }
  } else{
    Serial.println(" failed!");
  } 
  
  Serial.println("===============");
  client.stop();    // 停止客户端  
   
  // 根据服务器按键状态点亮或熄灭LED
  buttonState == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH);
}

JSON基础

json 概念

JSON(JavaScript Object Notation) 是一种通用的轻量级数据交换文本格式。它很容易让人阅读和编写,也便于机器进行解析和生成。它使用JavaScript语法来存储和描述数据对象,但是JSON完全独立于JavaScript。JSON可适用于多种流行编程语言。这些特性使JSON成为理想的数据交换格式。

1. JSON重点概念

数据 对象 数组

2. JSON语法规则要点

数据以“名”“值”对呈现
数据“名”和“值”之间由冒号分隔
大括号{}用于标注对象内容
中括号[]用于标注数组内容
逗号用于分隔数据、对象、数组

3. JSON数据

JSON数据以“名”“值”对呈现。数据“名”“值”由冒号分隔。JSON数据的书写格式是:

“JSON数据名”:JSON数据值

JSON数据举例:

“Year”: 2016
“URL”:”www.taichi-maker.com”

JSON数据名称
JSON数据名称需要放在双引号中。以下示例都是合法的JSON数据名:
“Value”、”信息1”

JSON数据值
JSON数据值可以是以下内容:

数字(整数或浮点数)
字符串
逻辑值(true 或 false)
数组(在中括号中)
对象(在大括号中)
null

4. JSON数组数据示例

"info": [
    {
        "name" : "taichi-maker",
        "website" : "www.taichi-maker.com"
    },
    {
        "year": 2020,
        "month": 12,
        "day": 30
    }
]

json 在线工具

https://www.json.cn/

https://oktools.net/json

arduino IDE 下载库
在这里插入图片描述

示例ESP8266 JSON解析

/**********************************************************************
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/
***********************************************************************/
#include <ArduinoJson.h>
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
 
  // 重点1:DynamicJsonDocument对象
  const size_t capacity = JSON_OBJECT_SIZE(2) + 30;
  DynamicJsonDocument doc(capacity);
 
  // 重点2:即将解析的json文件
  String json = "{\"name\":\"taichi-maker\",\"number\":1}";
  
  // 重点3:反序列化数据
  deserializeJson(doc, json);
 
  // 重点4:获取解析后的数据信息
  String nameStr = doc["name"].as<String>();
  int numberInt = doc["number"].as<int>();
 
  // 通过串口监视器输出解析后的数据信息
  Serial.print("nameStr = ");Serial.println(nameStr);
  Serial.print("numberInt = ");Serial.println(numberInt);
}
 
void loop() {}

上传 中 、、、 ---- ok 来活了 找bug 吧
在这里插入图片描述

ESP8266客户端HTTP API应用实例

ESP8266心知天气使用教程。通过心知天气(www.seniverse.com)免费服务获取实时天气信息。

注册账号,

心知天气首页地址:www.seniverse.com

在这里插入图片描述
申请接口
在这里插入图片描述

示例如下

/**********************************************************************
通过心知天气(www.seniverse.com)免费服务获取实时天气信息。
-----------------------------------------------------------------------
其它说明 / Other Description
心知天气API文档说明: https://www.seniverse.com/docs
 
本程序为太极创客团队制作的免费视频教程《零基础入门学用物联网 》中一部分。该教程系统的
向您讲述ESP8266的物联网应用相关的软件和硬件知识。以下是该教程目录页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/                                
***********************************************************************/
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
 
const char* ssid     = "dajiating";       // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "xxx";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
 
const char* host = "api.seniverse.com";     // 将要连接的服务器地址  
const int httpPort = 80;                    // 将要连接的服务器端口      
 
// 心知天气HTTP请求所需信息
String reqUserKey = "SgPyzsfk1cq-xxx";   // 私钥
String reqLocation = "Beijing";            // 城市
String reqUnit = "c";                      // 摄氏/华氏
 
void setup(){
  Serial.begin(9600);          
  Serial.println("");
  
  // 连接WiFi
  connectWiFi();
}
 
void loop(){
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit;
 
  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes);
  delay(3000);
}
 
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
  WiFiClient client;
 
  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
  Serial.println(""); 
  Serial.print("Connecting to "); Serial.print(host);
 
  // 尝试连接服务器
  if (client.connect(host, 80)){
    Serial.println(" Success!");
 
    // 向服务器发送http请求信息
    client.print(httpRequest);
    Serial.println("Sending request: ");
    Serial.println(httpRequest);  
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);
 
    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
      Serial.println("Found Header End. Start Parsing.");
    }
    
    // 利用ArduinoJson库解析心知天气响应信息
    parseInfo(client); 
  } else {
    Serial.println(" connection failed!");
  }   
  //断开客户端与服务器连接工作
  client.stop(); 
}
 
// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。                                              
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。  
}
 
// 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);
  
  deserializeJson(doc, client);
  
  JsonObject results_0 = doc["results"][0];
  
  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  const char* results_0_now_code = results_0_now["code"]; // "0"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "32"
  
  const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00" 
 
  // 通过串口监视器显示以上信息
  String results_0_now_text_str = results_0_now["text"].as<String>(); 
  int results_0_now_code_int = results_0_now["code"].as<int>(); 
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>(); 
  
  String results_0_last_update_str = results_0["last_update"].as<String>();   
 
  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.print(results_0_now_text_str);
  Serial.print(F(" "));
  Serial.println(results_0_now_code_int);
  Serial.print(F("Temperature: "));
  Serial.println(results_0_now_temperature_int);
  Serial.print(F("Last Update: "));
  Serial.println(results_0_last_update_str);
  Serial.println(F("========================"));
}

解决办法如下

「一键安装8266_package_2.7.4 .exe」https://www.aliyundrive.com/s/j1aK1oBZe24
安装完了重启一下就可以了。神奇的度娘,哈哈

该处使用的url网络请求的数据。


总结

1、Stream是ESP8266-Arduino开发环境中的一种数据类型。Serial库,WiFiClient库,FS库所建立的对象都可以处理Stream数据。
2、

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闰土小蒋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值