ESP32 HTTP GET с Arduino IDE (OpenWeatherMap.org и ThingSpeak)

В этом руководстве вы узнаете, как выполнять HTTP GET запросы с помощью платы ESP32 и Arduino IDE. Мы покажем, как декодировать JSON-данные с OpenWeatherMap.org и отображать значения на графиках с помощью ThingSpeak.

ESP32 HTTP GET с Arduino IDE OpenWeatherMap ThingSpeak

Рекомендуем: ESP32 HTTP POST с Arduino IDE (ThingSpeak и IFTTT.com)

Метод HTTP GET запроса

Протокол передачи гипертекста (HTTP) работает как протокол запрос-ответ между клиентом и сервером. Вот пример:

  • ESP32 (клиент) отправляет HTTP-запрос серверу (например: OpenWeatherMap.org или ThingSpeak);

  • Сервер возвращает ответ ESP32 (клиенту);

  • Наконец, ответ содержит информацию о статусе запроса и может также содержать запрошенные данные.

HTTP GET

GET используется для запроса данных из указанного ресурса. Он часто используется для получения значений из API.

Например, вы можете использовать простой запрос для получения значения или JSON-объекта:

GET /weather?countryCode=PT

Кроме того, вы также можете выполнить GET-запрос для обновления значения (как в ThingSpeak). Например, вы можете использовать:

GET /update?field1=value1

Обратите внимание, что строка запроса (name = field1 и value = value1) отправляется в URL HTTP GET запроса.

(При HTTP GET данные видны всем в URL запроса.)

Предварительные требования

Прежде чем приступить к этому руководству, убедитесь, что выполнены следующие предварительные требования.

Arduino IDE

Мы будем программировать ESP32 с помощью Arduino IDE, поэтому убедитесь, что у вас установлено дополнение ESP32.

Библиотека Arduino_JSON

Вам также необходимо установить библиотеку Arduino_JSON. Вы можете установить эту библиотеку в менеджере библиотек Arduino IDE. Просто перейдите в Sketch > Include Library > Manage Libraries и найдите название библиотеки следующим образом:

Установка библиотеки Arduino JSON в Arduino IDE

Другие веб-сервисы или API

В этом руководстве вы узнаете, как настроить плату ESP32 для выполнения HTTP-запросов к OpenWeatherMap.org и ThingSpeak. Если вы предпочитаете работать с локальным решением, вы можете использовать HTTP с Node-RED. Все примеры, представленные в этом руководстве, также работают с другими API.

В общем, чтобы сделать это руководство совместимым с любым сервисом, вам нужно найти документацию по API сервиса. Затем вам понадобится имя сервера (URL или IP-адрес) и параметры для отправки в запросе (путь URL или тело запроса). Наконец, измените наши примеры для интеграции с любым API, который вы хотите использовать.

1. ESP32 HTTP GET: JSON-данные (OpenWeatherMap.org)

В этом примере вы узнаете, как выполнять API-запросы для доступа к данным. В качестве примера мы будем использовать API OpenWeatherMap. Этот API имеет бесплатный план и предоставляет много полезной информации о погоде практически в любом месте мира.

HTTP GET Open Weather Map ESP32

Использование API OpenWeatherMap

Интерфейс программирования приложений (API) — это набор функций, написанных разработчиками программного обеспечения, чтобы любой мог использовать их данные или сервисы. Проект OpenWeatherMap имеет API, который позволяет пользователям запрашивать данные о погоде.

Логотип OpenWeatherMap API

В этом проекте вы будете использовать этот API для запроса прогноза погоды на день для выбранного вами местоположения. Изучение работы с API — отличный навык, потому что он открывает доступ к широкому разнообразию постоянно меняющейся информации, такой как текущие цены на акции, курсы валют, последние новости, обновления трафика, твиты и многое другое.

Примечание: API-ключи уникальны для каждого пользователя и не должны передаваться другим лицам.

Бесплатный план OpenWeatherMap предоставляет всё необходимое для завершения этого проекта. Для использования API вам нужен API-ключ, известный как APIID. Чтобы получить APIID:

  1. Откройте браузер и перейдите по адресу https://openweathermap.org/appid/

  2. Нажмите кнопку Sign up и создайте бесплатный аккаунт.

  3. Перейдите по ссылке: https://home.openweathermap.org/api_keys и получите свой API-ключ.

Копирование API-ключа OpenWeatherMap
  1. На вкладке API keys вы увидите ключ по умолчанию (выделен красным прямоугольником на рисунке выше); это уникальный ключ, который вам понадобится для получения информации с сайта. Скопируйте и вставьте этот ключ куда-нибудь; он скоро вам понадобится.

  2. Для получения информации о погоде в выбранном вами месте введите следующий URL:

http://api.openweathermap.org/data/2.5/weather?q=yourCityName,yourCountryCode&APPID=yourUniqueAPIkey

Замените yourCityName на город, для которого вам нужны данные, yourCountryCode на код страны для этого города, а yourUniqueAPIkey на уникальный API-ключ из шага 4. Например, обновлённый URL API для города Порту, Португалия, будет:

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
}

Далее вы узнаете, как использовать эту информацию для получения конкретных данных, таких как температура, влажность, давление, скорость ветра и т.д.

Код ESP32 HTTP GET OpenWeatherMap.org

После установки необходимых дополнений и библиотек скопируйте следующий код в Arduino IDE, но пока не загружайте его. Вам нужно внести некоторые изменения, чтобы он работал.

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp32-http-get-open-weather-map-thingspeak-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <WiFi.h>
#include <HTTPClient.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 = "bd939aa3d23ff33d3c8f5dd1dd435";

// 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 Domain name with URL path or IP address with 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";

Настройка API-ключа OpenWeatherMap.org

Вставьте ваш API-ключ в следующую строку:

String openWeatherMapApiKey = "REPLACE_WITH_YOUR_OPEN_WEATHER_MAP_API_KEY";

Настройка города и страны

Введите город, для которого вы хотите получить данные, а также код страны в следующие переменные:

// 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) {
  HTTPClient http;

  // Your IP address with path or Domain name with URL path
  http.begin(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

После загрузки кода откройте Serial Monitor, и вы увидите, что он получает следующие 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}

Затем он выводит декодированный JSON-объект в Serial Monitor Arduino IDE, чтобы получить значения температуры (в Кельвинах), давления, влажности и скорости ветра.

ESP32 HTTP GET Arduino IDE OpenWeatherMap ответ Serial Monitor

Для демонстрационных целей мы запрашиваем новые данные каждые 10 секунд. Однако для долгосрочного проекта вам следует увеличить таймер или проверить ограничения API-вызовов в час/минуту, чтобы избежать блокировки/бана.

2. ESP32 HTTP GET: Обновление значения (ThingSpeak)

В этом примере ESP32 выполняет HTTP GET запрос для обновления показания в ThingSpeak.

HTTP GET ThingSpeak ESP32

Использование API ThingSpeak

ThingSpeak имеет бесплатный API, который позволяет хранить и извлекать данные с помощью HTTP. В этом руководстве вы будете использовать API ThingSpeak для публикации и визуализации данных на графиках из любого места. В качестве примера мы будем публиковать случайные значения, но в реальном приложении вы бы использовали реальные показания датчиков.

Для использования ThingSpeak с вашим ESP вам нужен API-ключ. Выполните следующие шаги:

  1. Перейдите на ThingSpeak.com и создайте бесплатный аккаунт.

  2. Затем откройте вкладку Channels.

  3. Создайте New Channel.

ThingSpeak создание нового канала
  1. Откройте ваш вновь созданный канал и выберите вкладку API Keys, чтобы скопировать ваш Write API Key.

ThingSpeak просмотр и копирование API Key

Код ESP32 HTTP GET ThingSpeak

Скопируйте следующий скетч в Arduino IDE (введите ваш SSID, пароль и API Key):

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/esp32-http-get-open-weather-map-thingspeak-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <WiFi.h>
#include <HTTPClient.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(33));
}

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 Key)

Измените переменную serverName, включив ваш API-ключ.

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

Теперь загрузите код на свою плату, и он должен сразу заработать. Прочитайте следующий раздел, если хотите узнать, как выполняется HTTP GET запрос.

HTTP GET запрос

В loop() выполняется HTTP GET запрос каждые 10 секунд со случайными значениями:

String serverPath = serverName + "&field1=" + String(random(40));

// Your Domain name with URL path or IP address with path
http.begin(serverPath.c_str());

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

ESP32 выполняет новый запрос по следующему URL для обновления поля sensor field1 новым значением (30).

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);
}

В Serial Monitor Arduino IDE вы должны увидеть HTTP-код ответа 200 (это означает, что запрос выполнен успешно).

ESP32 HTTP GET Arduino IDE Serial Monitor ответ

Ваша панель управления ThingSpeak (на вкладке Private View) должна получать новые показания каждые 10 секунд.

ESP32 HTTP GET ThingSpeak график

Для финального приложения вам может потребоваться увеличить таймер или проверить ограничения API-вызовов в час/минуту, чтобы избежать блокировки/бана.

Заключение

В этом руководстве вы узнали, как интегрировать ESP32 с веб-сервисами, используя HTTP GET запросы. Вы также можете выполнять HTTP POST запросы с ESP32.

Если вы используете плату ESP8266, прочитайте:

Вам также может быть интересно: