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. ЖК-дисплей будет использовать интерфейс 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
/*
* Руи Сантос
* Полные детали проекта на 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;
}
Common Course Links
Common Course Files
Ресурсы и ссылки
-
Документация
Файлы📁
Нет доступных файлов.