Код для поиска

ESP32 Урок 43/55 - Интернет-метеостанция IoT | Обучающий набор SunFounder для ESP32 IoT

ESP32 Урок 43/55 - Интернет-метеостанция IoT | Обучающий набор SunFounder для ESP32 IoT

В этом руководстве мы создадим подключенную к Интернету метеостанцию с использованием ESP32 и его платы расширения с камерой от SunFounder. Этот проект позволяет ESP32 получать данные о погоде в реальном времени, включая температуру и влажность, и отображать их на ЖК-экране. Это приложение не только демонстрирует возможности ESP32, но и показывает, как получать и анализировать данные из внешнего API.

По мере продвижения по руководству мы подключим компоненты, настроим код и убедимся, что все работает слаженно. В результате мы получим полностью функциональную метеостанцию, которая обновляет свои показания каждые 10 секунд, обеспечивая четкое и лаконичное отображение текущих погодных условий (на видео в 00:30).

Объяснение аппаратного обеспечения

Основные компоненты, используемые в этом проекте, включают микроконтроллер ESP32, ЖК-дисплей и необходимые соединения. ESP32 оснащен встроенными Wi-Fi и Bluetooth, что позволяет ему подключаться к Интернету и получать данные. ЖК-дисплей будет показывать текущую информацию о погоде, включая температуру и влажность.

Используемый нами ЖК-дисплей — это символьный дисплей 16x2, что означает, что он может отображать две строки по 16 символов в каждой. Этого будет достаточно для вывода нашей информации о погоде. ESP32 будет общаться с ЖК-дисплеем через I2C, что упрощает подключение, используя только две линии данных.

Детали из технического описания

ПроизводительEspressif
Номер деталиESP32-WROOM-32
Логическое/IO напряжение3,3 В
Напряжение питания3,0–3,6 В
Выходной ток (на канал)макс. 12 мА
Пиковый ток (на канал)40 мА
Рекомендации по частоте ШИМ1 кГц
Пороговые значения входной логики0,3 В (низкий), 0,7 В (высокий)
Падение напряжения / RDS(on) / насыщение0,5 В
Тепловые пределыот -40 до 85 °C
КорпусQFN48
Примечания / вариантыВключает несколько вариантов для различных применений

  • Убедитесь, что ESP32 питается от стабильного источника 3,3 В.
  • Используйте общий заземляющий провод для всех компонентов, чтобы избежать проблем со связью.
  • Проверьте I2C-адрес ЖК-дисплея с помощью I2C-сканера.
  • Следите за статусом Wi-Fi-подключения, чтобы избежать разрывов во время получения данных.
  • Обрабатывайте ошибки парсинга JSON для надежности при получении данных.

Инструкции по подключению

esp32-43-weather_station-wiring

Чтобы подключить компоненты, начните с соединения ЖК-дисплея с ESP32. ЖК-дисплей будет использовать интерфейс I2C, поэтому подключите контакт SDA ЖК-дисплея к GPIO21 на ESP32, а контакт SCL — к GPIO22. Убедитесь, что контакты питания и заземления ЖК-дисплея подключены к контактам 5V и GND на ESP32 соответственно.

Затем убедитесь, что ESP32 правильно запитан с помощью прилагаемой литиевой батареи или USB-подключения. Батарея обеспечивает портативность, а USB-подключение полезно для программирования и отладки. Наконец, проверьте, что все соединения надежны, чтобы избежать проблем с ослабленными проводами, которые могут нарушить работу.

Примеры кода и пояснения

На этапе настройки нашей программы мы инициализируем последовательную связь и подключаемся к Wi-Fi-сети, используя предоставленные SSID и пароль. Следующий фрагмент кода обрабатывает Wi-Fi-подключение:

WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("Подключено к Wi-Fi сети с IP-адресом: ");
Serial.println(WiFi.localIP());

Этот код гарантирует, что ESP32 подключится к указанной Wi-Fi-сети перед продолжением получения данных. Если подключение не удается, он будет непрерывно пытаться переподключиться.

Далее нам нужно отправить HTTP GET-запрос для получения данных о погоде. Это выполняется с помощью следующего фрагмента кода:

String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric" + "&APPID=" + openWeatherMapApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());

Здесь мы формируем URL для API-запроса, который включает город, код страны и наш API-ключ. Затем вызывается функция httpGETRequest для получения данных о погоде.

Наконец, мы анализируем JSON-ответ и отображаем соответствующие данные на ЖК-дисплее:

lcd.clear(); 
lcd.setCursor(0, 0); 
lcd.print(time);
lcd.print(" ");        
lcd.print(myObject["weather"][0]["main"]);             
lcd.setCursor(0, 1);
lcd.print("T:");    
lcd.print(myObject["main"]["temp"]); 
lcd.print("\xDF");  // символ "°"
lcd.print("C ");    
lcd.print("H:");    
lcd.print(myObject["main"]["humidity"]);  
lcd.print("%");

Этот фрагмент кода обновляет ЖК-дисплей, отображая текущее время, погодные условия, температуру и влажность. Он очищает предыдущее отображение и устанавливает курсор в соответствующие позиции для каждой строки.

Демонстрация / Чего ожидать

После успешного подключения и программирования ваша метеостанция подключится к Wi-Fi и начнет получать данные о погоде каждые 10 секунд. Вы увидите текущую температуру, влажность и погодные условия на ЖК-экране. Если ESP32 не сможет подключиться к Wi-Fi, он выведет сообщение об ошибке в последовательный монитор.

Следите за лимитами вызовов API, чтобы не быть заблокированным сервисом OpenWeatherMap. Если у вас возникнут проблемы с получением данных, проверьте ваш API-ключ и убедитесь, что ваш город и код страны указаны правильно (в видео на 15:45).

Таймкоды видео

  • 00:00 Начало
  • 2:00 Введение в проект
  • 5:04 Аккаунт OpenWeather
  • 6:11 Подключение
  • 8:05 Объяснение кода Arduino
  • 14:13 Элементы JSON в коде
  • 20:23 Выбор платы ESP32 и COM-порта в Arduino IDE
  • 22:05 Демонстрация метеостанции на LCD1602
  • 23:45 Демонстрация метеостанции на LCD2004

Изображения

esp32-43-weather_station-main
esp32-43-weather_station-main
esp32-43-weather_station-wiring
esp32-43-weather_station-wiring
844-ESP32 Tutorial 43/55- Arduino code for IoT Internet Weather Station
Язык: C++
/*
 * Руи Сантос
 * Полные детали проекта на https://RandomNerdTutorials.com/esp32-http-get-open-weather-map-thingspeak-arduino/
 * 
 * Настоящим разрешение предоставляется бесплатно любому лицу, получающему копию
 * этого программного обеспечения и сопутствующих документов.
 * 
 * Вышеуказанное уведомление об авторских правах и данное уведомление о разрешении должны быть включены во все
 * копии или значительные части Программного обеспечения.
 */
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>


 // Замените следующие переменные на вашу комбинацию SSID/Пароль.
const char* ssid = "SSID";
const char* password = "PASSWORD";

 // Ваше доменное имя с URL-адресом или IP-адресом с путем
String openWeatherMapApiKey = "openWeatherMapApiKey";

 // Замените на код вашей страны и город.
 // Найдите код страны на https://openweathermap.org/find
String city = "CITY";
String countryCode = "COUNTRY CODE";

 // ТОЧКА ПО УМОЛЧАНИЮ УСТАНОВЛЕНА НА 10 СЕКУНД ДЛЯ ЦЕЛЕЙ ТЕСТИРОВАНИЯ
 // Для окончательного применения проверьте ограничения на вызовы API в час/минуту, чтобы избежать блокировки/запрета.
unsigned long lastTime = 0;
 // Таймер установлен на 10 минут (600000)
 // беззнаковое длинное целое timerDelay = 600000;
 // Установите таймер на 10 секунд (10000)
unsigned long timerDelay = 10000;

String jsonBuffer;

 // установите количество колонок и строк ЖК-дисплея
int lcdColumns = 16;
int lcdRows = 2;

 // установите адрес ЖК-дисплея, количество столбцов и строк
 // SDA -> GPIO21, SCL -> GPIO22
 // адрес lcd – 0x27, запустите скетч I2C-сканера
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);

 // Время сервера NTP
const char* ntpServer = "pool.ntp.org";
long  gmtOffset_sec = 0;
int   daylightOffset_sec = 0; // 3600;

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

 // Wi-Fi
  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.");

 // инициализировать ЖК-дисплей
  lcd.init();
 // включить подсветку ЖК-дисплея
  lcd.backlight();

}

void loop() {
 // Отправить HTTP GET запрос
  if ((millis() - lastTime) > timerDelay) {
 // Проверьте состояние соединения Wi-Fi
    if(WiFi.status()== WL_CONNECTED){
      String serverPath = "http: // api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric" + "&APPID=" + openWeatherMapApiKey;

      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer);
      JSONVar myObject = JSON.parse(jsonBuffer);

 // JSON.typeof(jsonVar) может быть использован для получения типа переменной.
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }

 // Serial.print("JSON объект = ");
 // Serial.println(myObject);
 // Серия.print("Температура: ");
 // Serial.println(myObject["main"]["temp"]);
 // Давление: 
 // Serial.println(myObject["main"]["pressure"]);
 // Serial.print("Влажность: ");
 // Serial.println(myObject["main"]["влажность"]);
 // Серийный.печать("Скорость ветра: ");
 // Serial.println(myObject["ветер"]["скорость"]);

 // Получите время
      gmtOffset_sec =  myObject["timezone"];
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
 // время =
      String time = printLocalTime();

 // LCD Печать
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(time);
      lcd.print(" ");
      lcd.print(myObject["weather"][0]["main"]);
      lcd.setCursor(0, 1);
      lcd.print("T:");
      lcd.print(myObject["main"]["temp"]);
      lcd.print("\xDF"); // "°" знак
      lcd.print("C ");
      lcd.print("H:");
      lcd.print(myObject["main"]["humidity"]);
      lcd.print("%");

    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

String printLocalTime(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return "null";
  }
 // Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

 // получить формат времени ЧЧ:ММ
  char timeHour[3];
  strftime(timeHour,3, "%H", &timeinfo);
  char timeMinute[3];
  strftime(timeMinute,3, "%M", &timeinfo);
  String time = String(timeHour) + ":" + String(timeMinute);
  Serial.println(time)
;  return time;
}


String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;

 // Ваше доменное имя с URL-адресом или IP-адресом с путем
  http.begin(client, serverName);

 // Отправить HTTP POST запрос
  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);
  }
 // Бесплатные ресурсы
  http.end();

  return payload;
}

Файлы📁

Нет доступных файлов.