通过HTTP GET 请求互联网接口数据:ESP8266/NodeMCU

释放双眼,带上耳机,听听看~!

在本教程中,您将学习如何使用带有 Arduino IDE 的 ESP8266 NodeMCU 板发出 HTTP GET 请求。我们将演示如何使用 ThingSpeak 解码 OpenWeatherMap.org 中的 JSON 数据并在连接图中绘制值。

ESP8266-NodeMCU-HTTP-GET-with-Arduino-IDE-OpenWeatherMap-ThingSpeak

HTTP GET 请求方式

超文本传输协议 (HTTP) 用作客户端和服务器之间的请求-响应协议。下面是一个示例:

  • ESP8266(客户端)向服务器(例如:OpenWeatherMap.org 或 ThingSpeak)提交 HTTP 请求;
  • 服务器向ESP8266(客户端)返回响应;
  • 最后,响应包含有关请求的状态信息,也可能包含请求的内容。

 HTTP 获取

请注意,查询字符串(name = field1 和 value = value1)在 HTTP GET 请求的 URL 中发送。

(使用 HTTP GET,数据对 URL 请求中的每个人都可见。

 先决条件

在继续学习本教程之前,请确保完成以下先决条件。

 Arduino集成开发环境

我们将使用 Arduino IDE 对 ESP8266 NodeMCU 进行编程,因此请确保您已安装 ESP8266 附加组件。

 Arduino_JSON库

您还需要安装 Arduino_JSON 库。您可以在 Arduino IDE 库管理器中安装此库。只需转到“程序”>“包含库”>“管理库”,然后搜索库名称,如下所示:

Install-Arduino-JSON-library-Arduino-IDE

其他 Web 服务或 API

在本教程中,您将学习如何设置 ESP8266 NodeMCU 开发板,以执行对 OpenWeatherMap.org 和 ThingSpeak 的 HTTP 请求。如果您更喜欢使用本地解决方案进行学习,则可以将 HTTP 与 Node-RED 一起使用。本教程中介绍的所有示例也适用于其他 API。

总之,要使本教程与任何服务兼容,您需要搜索服务 API 文档。然后,您需要服务器名称(URL 或 IP 地址)和要在请求中发送的参数(URL 路径或请求正文)。最后,修改我们的示例以与您要使用的任何 API 集成。

1. ESP8266 HTTP GET:JSON 数据(OpenWeatherMap.org)

在此示例中,你将了解如何发出 API 请求来访问数据。例如,我们将使用 OpenWeatherMap API。此 API 有一个免费计划,并提供了许多有关世界上几乎任何地方天气的有用信息。

HTTP-GET-Open-Weather-Map-ESP8266-NodeMCU

使用 OpenWeatherMap API

应用程序编程接口 (API) 是由软件开发人员编写的一组函数,使任何人都可以使用他们的数据或服务。OpenWeatherMap 项目有一个 API,使用户能够请求天气数据。

logo

在此项目中,您将使用该 API 请求所选位置的当天天气预报。学习使用 API 是一项很棒的技能,因为它允许您访问各种不断变化的信息,例如当前股价、货币汇率、最新新闻、流量更新、推文等等。

注意:API 密钥对用户是唯一的,不应与任何人共享。

OpenWeatherMap 的免费计划提供了完成此项目所需的一切。要使用 API,您需要一个 API 密钥,称为 APIID。若要获取 APIID,请执行以下操作:

  1. 打开浏览器并转到 https://openweathermap.org/appid/
  2. 按“注册”按钮并创建一个免费帐户。
  3. 转到此链接:https://home.openweathermap.org/api_keys 并获取您的 API 密钥。
OpenWeatherMap-API-key
  1. 在“API 密钥”选项卡上,你将看到一个默认密钥(在上图中以红色矩形突出显示);这是从站点中提取信息所需的唯一密钥。将此密钥复制并粘贴到某处;你一会儿就会用到它。
  2. 要提取所选位置的天气信息,请输入以下 URL:
http://api.openweathermap.org/data/2.5/weather?q=yourCityName,yourCountryCode&APPID=yourUniqueAPIkey

将 yourCityName 替换为要为其提供数据的城市,将 yourCountryCode 替换为该城市的国家/地区代码,将 yourUniqueAPIkey 替换为步骤 4 中的唯一 API 密钥。例如,葡萄牙波尔图市更新后的 API URL 为:

http://api.openweathermap.org/data/2.5/weather?q=Porto,
PT&APPID=801d2603e9f2e1c70e042e4f5f6e0---
  1. 将您的 URL 复制到浏览器中,API 将返回一堆与您当地天气相对应的信息。在编写本教程的当天,我们得到了有关葡萄牙波尔图天气的以下信息。
{"coord":{"lon":-8.611,"lat":41.1496},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":294.58,"feels_like":294.95,"temp_min":293.82,"temp_max":295.65,"pressure":1016,"humidity":83},"visibility":10000,"wind":{"speed":8.94,"deg":180,"gust":8.94},"clouds":{"all":75},"dt":1666877635,"sys":{"type":2,"id":2009460,"country":"PT","sunrise":1666853957,"sunset":1666892227},"timezone":3600,"id":2735943,"name":"Porto","cod":200}

这是缩进时的样子,以提高可读性。

{
  "coord": {
    "lon": -8.611,
    "lat": 41.1496
  },
  "weather": [
    {
      "id": 803,
      "main": "Clouds",
      "description": "broken clouds",
      "icon": "04d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 294.58,
    "feels_like": 294.95,
    "temp_min": 293.82,
    "temp_max": 295.65,
    "pressure": 1016,
    "humidity": 83
  },
  "visibility": 10000,
  "wind": {
    "speed": 8.94,
    "deg": 180,
    "gust": 8.94
  },
  "clouds": {
    "all": 75
  },
  "dt": 1666877635,
  "sys": {
    "type": 2,
    "id": 2009460,
    "country": "PT",
    "sunrise": 1666853957,
    "sunset": 1666892227
  },
  "timezone": 3600,
  "id": 2735943,
  "name": "Porto",
  "cod": 200
}

接下来,您将了解如何使用此信息来获取特定数据,例如温度、湿度、压力、风速等。

代码ESP8266 HTTP GET OpenWeatherMap.org

安装必要的板附加组件和库后,将以下代码复制到 Arduino IDE,但不要上传。您需要进行一些更改才能使其适合您。

/*
  
  更多Arduino/ESP8266/ESP32等教程请访问: https://www.qutaojiao.com
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Your Domain name with URL path or IP address with path
String openWeatherMapApiKey = "REPLACE_WITH_YOUR_OPEN_WEATHER_MAP_API_KEY";
// Example:
//String openWeatherMapApiKey = "bd939aa3d23ff33d3c8f5dd1dd4";

// Replace with your country code and city
String city = "Porto";
String countryCode = "PT";

// THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES
// For a final application, check the API call limits per hour/minute to avoid getting blocked/banned
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 10 seconds (10000)
unsigned long timerDelay = 10000;

String jsonBuffer;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
}

void loop() {
  // Send an HTTP GET request
  if ((millis() - lastTime) > timerDelay) {
    // Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey;
      
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer);
      JSONVar myObject = JSON.parse(jsonBuffer);
  
      // JSON.typeof(jsonVar) can be used to get the type of the var
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(myObject);
      Serial.print("Temperature: ");
      Serial.println(myObject["main"]["temp"]);
      Serial.print("Pressure: ");
      Serial.println(myObject["main"]["pressure"]);
      Serial.print("Humidity: ");
      Serial.println(myObject["main"]["humidity"]);
      Serial.print("Wind Speed: ");
      Serial.println(myObject["wind"]["speed"]);
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(client, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

 

设置网络凭据

使用您的网络凭据修改下一行:SSID 和密码。该代码对您应该在何处进行更改进行了很好的注释。

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

设置 OpenWeatherMap.org API 密钥

在以下行中插入 API 密钥:

String openWeatherMapApiKey = "REPLACE_WITH_YOUR_OPEN_WEATHER_MAP_API_KEY";

设置您的城市和国家/地区

在以下变量中输入要获取其数据的城市以及国家/地区代码(中国地区码是CN):

// Replace with your country code and city
String city = "Porto";
String countryCode = "PT";

进行这些更改后,您可以将代码上传到您的开发板。继续阅读以了解代码的工作原理。

HTTP GET 请求(JSON 对象)

在 loop() 中,调用 httpGETRequest() 函数以发出 HTTP GET 请求:

String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey;

jsonBuffer = httpGETRequest(serverPath.c_str());

httpGETRequest() 函数向 OpenWeatherMap 发出请求,并检索一个带有 JSON 对象的字符串,该对象包含有关您所在城市天气的所有信息。

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(client, serverName);

  // Send HTTP POST request
  int httpResponseCode = http.GET();

  String payload = "{}"; 

  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

 解码 JSON 对象

若要访问这些值,请解码 JSON 对象并将所有值存储在 jsonBuffer 数组中。

JSONVar myObject = JSON.parse(jsonBuffer);
// JSON.typeof(jsonVar) can be used to get the type of the var

if (JSON.typeof(myObject) == "undefined") {
  Serial.println("Parsing input failed!");
  return;
}

Serial.print("JSON object = ");
Serial.println(myObject);
Serial.print("Temperature: ");
Serial.println(myObject["main"]["temp"]);
Serial.print("Pressure: ");
Serial.println(myObject["main"]["pressure"]);
Serial.print("Humidity: ");
Serial.println(myObject["main"]["humidity"]);
Serial.print("Wind Speed: ");
Serial.println(myObject["wind"]["speed"]);

 HTTP GET 演示

上传代码后,打开串行监视器,你将看到它正在接收以下 JSON 数据:

{"coord":{"lon":-8.61,"lat":41.15},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":294.44,"feels_like":292.82,"temp_min":292.15,"temp_max":297.04,"pressure":1008,"humidity":63},"visibility":10000,"wind":{"speed":4.1,"deg":240},"clouds":{"all":20},"dt":1589288330,"sys":{"type":1,"id":6900,"country":"PT","sunrise":1589260737,"sunset":1589312564},"timezone":3600,"id":2735943,"name":"Porto","cod":200}

然后,它在 Arduino IDE 串行监视器中打印解码的 JSON 对象,以获取温度(以开尔文为单位)、压力、湿度和风速值。

ESP32-ESP8266-NodeMCU-HTTP-GET-with-Arduino-IDE-OpenWeatherMap-Response

出于演示目的,我们每 10 秒请求一次新数据。但是,对于长期项目,您应该增加计时器或检查每小时/分钟的 API 调用限制,以避免被阻止/禁止。

2. ESP8266 HTTP GET:更新值 (ThingSpeak)

在此示例中,ESP8266发出 HTTP GET 请求以更新 ThingSpeak 中的读数。

HTTP-GET-Thingspeak-ESP8266-NodeMCU

 使用 ThingSpeak API

ThingSpeak 有一个免费的 API,允许您使用 HTTP 存储和检索数据。在本教程中,您将使用 ThingSpeak API 从任何位置在连接图中发布和可视化数据。例如,我们将发布随机值,但在实际应用中,您将使用真实的传感器读数。

要将 ThingSpeak 与 ESP 配合使用,您需要一个 API 密钥。请按照以下步骤操作:

  1. 转到 ThingSpeak.com 并创建一个免费帐户。
  2. 然后,打开“频道”选项卡。
  3.  创建一个新频道。
ESP32-ESP8266-NodeMCU-ThingSpeak-New-Channel
  1. 打开新创建的频道,然后选择“API 密钥”选项卡以复制 API 密钥。
ESP32-ESP8266-NodeMCU-ThingSpeak-View-API-Key-Write-Copy

HTTP GET ThingSpeak ESP8266代码

将下一个程序复制到Arduino IDE(键入SSID,密码和API密钥):

/*
  
  更多Arduino/ESP8266/ESP32等教程请访问: https://www.qutaojiao.com
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE WITH THINGSPEAK.COM API KEY
String serverName = "http://api.thingspeak.com/update?api_key=REPLACE_WITH_YOUR_API_KEY";
// EXAMPLE:
//String serverName = "http://api.thingspeak.com/update?api_key=7HQJM49R8JAPR";

// THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES
// For a final application, check the API call limits per hour/minute to avoid getting blocked/banned
unsigned long lastTime = 0;
// Timer set to 10 minutes (600000)
//unsigned long timerDelay = 600000;
// Set timer to 10 seconds (10000)
unsigned long timerDelay = 10000;

void setup() {
  Serial.begin(115200); 

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
  
  // Random seed is a number used to initialize a pseudorandom number generator
  randomSeed(analogRead(0));
}

void loop() {
  // Send an HTTP GET request
  if ((millis() - lastTime) > timerDelay) {
    // Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      WiFiClient client;
      HTTPClient http;
    
      String serverPath = serverName + "&field1=" + String(random(40));
      
      // Your Domain name with URL path or IP address with path
      http.begin(client, serverPath.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();
        Serial.println(payload);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

 

设置网络凭据

使用您的网络凭据修改下一行:SSID 和密码。该代码对您应该在何处进行更改进行了很好的注释。

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

设置 serverName(API 密钥)

修改 serverName 变量以包含您的 API 密钥。

String serverName = "http://api.thingspeak.com/update?api_key=REPLACE_WITH_YOUR_API_KEY";

现在,将代码上传到您的开发板,它应该可以立即工作。如果您想了解如何发出 HTTP GET 请求,请阅读下一节。

 HTTP GET 请求

在 loop() 中,您每 10 秒使用随机值发出一次 HTTP GET 请求:

if(WiFi.status()== WL_CONNECTED){
  WiFiClient client;
  HTTPClient http;
    
  String serverPath = serverName + "&field1=" + String(random(40));
      
  // Your Domain name with URL path or IP address with path
  http.begin(client, serverPath.c_str());

  // Send HTTP GET request
  int httpResponseCode = http.GET();

ESP8266在以下 URL 中发出新请求,以使用新值 (30) 更新传感器 field1。

http://api.thingspeak.com/update?api_key=REPLACE_WITH_YOUR_API_KEY&field1=30

然后,以下代码行保存来自服务器的 HTTP 响应。

if (httpResponseCode>0) {
  Serial.print("HTTP Response code: ");
  Serial.println(httpResponseCode);
  String payload = http.getString();
  Serial.println(payload);
}
else {
  Serial.print("Error code: ");
  Serial.println(httpResponseCode);
}

在Arduino IDE串行监视器中,您应该看到HTTP响应代码200(这意味着请求已成功)。

ESP32-ESP8266-NodeMCU-HTTP-POST-Arduino-IDE-Serial-Monitor-Response

您的 ThingSpeak 仪表板应该每 10 秒接收一次新读数。

ESP32-ESP8266-NodeMCU-HTTP-GET-POST-ThingSpeak-chart

对于最终应用程序,您可能需要增加计时器或检查每小时/分钟的 API 调用限制,以避免被阻止/禁止。

注意:为了更轻松地使用ESP8266将传感器读数发送到 ThingSpeak,我们推荐以下教程:

  • ESP8266 NodeMCU 将传感器读数发布到 ThingSpeak(最简单的方法)

 总结

在本教程中,您学习了如何使用 HTTP GET 请求将 ESP8266 与 Web 服务集成。您还可以使用 ESP8266发出 HTTP POST 请求。

给TA打赏
共{{data.count}}人
人已打赏
Nodemcu/ESP8266Nodemcu/ESP8266-进阶动态

HTTP GET 和 HTTP POST 请求教程:使用 ESP8266/NodeMCU

2023-12-11 22:22:35

ESP32ESP32-进阶Nodemcu/ESP8266Nodemcu/ESP8266-进阶免费项目

利用ESP32/ESP8266与OpenAI的ChatGPT实现对话的原理与步骤详解

2024-2-28 10:00:36

7 条回复 A文章作者 M管理员
  1. Lumilio

    666

  2. sonia2025

    ho

  3. sonia2025

    在OpenWeatherMap.org中,温度是292? 甚么单位?

  4. That tiered VIP system sounds genuinely interesting – smart way to boost retention! I’ve seen similar approaches really work. Checking out jljl13 com to see how their localized payments & mobile app integrate – crucial for the PH market! 🤔

  5. Interesting read! Seeing platforms like Swerte optimize for local payment options (GCash, PayMaya) is smart. Security is key, though – always verify sites! Check out the swerte app download apk for options, but proceed with caution & responsible gaming.

  6. Excellent tutorial on ESP8266 HTTP requests! As someone working with AI-powered creative platforms, I’m impressed by how IoT devices can fetch real-time data. Just as APIs enable weather data access, tools like 지브리 AI demonstrate how APIs can power creative applications. The JSON parsing techniques shown here apply beautifully to any API integration project. Great primer for developers expanding into connected devices!

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索