Szukaj kodu

Samouczek ESP32 43/55 - Internetowa stacja pogodowa IoT | Zestaw edukacyjny IoT ESP32 od SunFounder

Samouczek ESP32 43/55 - Internetowa stacja pogodowa IoT | Zestaw edukacyjny IoT ESP32 od SunFounder

W tym samouczku zbudujemy stację pogodową podłączoną do Internetu, wykorzystując ESP32 oraz jego płytkę rozszerzającą z kamerą od SunFounder. Projekt ten umożliwia ESP32 pobieranie danych pogodowych w czasie rzeczywistym, w tym temperatury i wilgotności, oraz wyświetlanie ich na ekranie LCD. Aplikacja ta nie tylko pokazuje możliwości ESP32, ale także demonstruje, jak pobierać i analizować dane z zewnętrznego API.

W trakcie samouczka połączymy komponenty, skonfigurujemy kod i upewnimy się, że wszystko działa ze sobą bezproblemowo. Efektem końcowym będzie w pełni funkcjonalna stacja pogodowa, która aktualizuje odczyty co 10 sekund, zapewniając czytelny i zwięzły wyświetlacz aktualnych warunków pogodowych (na wideo w 00:30).

Omówienie sprzętu

Główne komponenty użyte w tym projekcie to mikrokontroler ESP32, wyświetlacz LCD oraz niezbędne okablowanie. ESP32 jest wyposażony we wbudowany Wi-Fi i Bluetooth, co pozwala mu na połączenie z Internetem i pobieranie danych. Wyświetlacz LCD będzie pokazywał aktualne informacje pogodowe, w tym temperaturę i wilgotność.

Używany wyświetlacz LCD to wyświetlacz znakowy 16x2, co oznacza, że może pokazywać dwie linie po 16 znaków każda. To będzie wystarczające dla naszego wyjścia informacji pogodowych. ESP32 będzie komunikować się z LCD przez I2C, co upraszcza okablowanie, używając tylko dwóch linii danych.

Szczegóły z karty katalogowej

ProducentEspressif
Numer częściESP32-WROOM-32
Napięcie logiczne/IO3,3 V
Napięcie zasilania3,0–3,6 V
Prąd wyjściowy (na kanał)maks. 12 mA
Prąd szczytowy (na kanał)40 mA
Zalecana częstotliwość PWM1 kHz
Progi logiczne wejścia0,3 V (niski), 0,7 V (wysoki)
Spadek napięcia / RDS(on) / nasycenie0,5 V
Limity termiczne-40 do 85 °C
ObudowaQFN48
Uwagi / wariantyObejmuje wiele wariantów dla różnych zastosowań

  • Upewnij się, że ESP32 jest zasilany stabilnym napięciem 3,3 V.
  • Użyj wspólnej masy dla wszystkich komponentów, aby uniknąć problemów z komunikacją.
  • Sprawdź adres I2C wyświetlacza LCD za pomocą skanera I2C.
  • Monitoruj status połączenia Wi-Fi, aby uniknąć rozłączeń podczas pobierania danych.
  • Obsługuj błędy parsowania JSON dla niezawodności w pobieraniu danych.

Instrukcje okablowania

esp32-43-weather_station-wiring

Aby połączyć komponenty, zacznij od podłączenia LCD do ESP32. LCD będzie używać interfejsu I2C, więc podłącz pin SDA LCD do GPIO21 na ESP32, a pin SCL do GPIO22. Upewnij się, że podłączasz piny zasilania i masy LCD odpowiednio do pinów 5V i GND na ESP32.

Następnie upewnij się, że ESP32 jest prawidłowo zasilany za pomocą dołączonej baterii litowej lub połączenia USB. Bateria zapewnia przenośność, podczas gdy połączenie USB jest przydatne do programowania i debugowania. Na koniec sprawdź, czy wszystkie połączenia są pewne, aby uniknąć problemów z luźnym okablowaniem, które mogłoby zakłócić działanie.

Przykłady kodu i omówienie

W fazie konfiguracji naszego programu inicjalizujemy komunikację szeregową i łączymy się z siecią Wi-Fi przy użyciu podanego SSID i hasła. Poniższy fragment kodu obsługuje połączenie Wi-Fi:

WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("Połączono z siecią Wi-Fi o adresie IP: ");
Serial.println(WiFi.localIP());

Ten kod zapewnia, że ESP32 łączy się z określoną siecią Wi-Fi przed przejściem do pobierania danych. Jeśli połączenie nie powiedzie się, będzie ciągle próbować się ponownie połączyć.

Następnie musimy wysłać żądanie HTTP GET, aby pobrać dane pogodowe. Odbywa się to za pomocą następującego fragmentu kodu:

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

Tutaj konstruujemy adres URL dla żądania API, który zawiera miasto, kod kraju i nasz klucz API. Funkcja httpGETRequest jest następnie wywoływana w celu pobrania danych pogodowych.

Na koniec analizujemy odpowiedź JSON i wyświetlamy odpowiednie dane na 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");  // znak "°"
lcd.print("C ");    
lcd.print("H:");    
lcd.print(myObject["main"]["humidity"]);  
lcd.print("%");

Ten fragment kodu aktualizuje wyświetlacz LCD o aktualny czas, warunki pogodowe, temperaturę i wilgotność. Czyści poprzedni wyświetlacz i ustawia kursor w odpowiednich pozycjach dla każdej linii.

Demonstracja / Czego się spodziewać

Po pomyślnym okablowaniu i zaprogramowaniu Twoja stacja pogodowa połączy się z Wi-Fi i zacznie pobierać dane pogodowe co 10 sekund. Zobaczysz aktualną temperaturę, wilgotność i warunki pogodowe wyświetlane na ekranie LCD. Jeśli ESP32 nie połączy się z Wi-Fi, wyświetli komunikat o błędzie w monitorze szeregowym.

Pamiętaj o limitach wywołań API, aby uniknąć zablokowania usługi OpenWeatherMap. Jeśli napotkasz jakiekolwiek problemy z pobieraniem danych, sprawdź swój klucz API i upewnij się, że miasto oraz kod kraju są poprawnie określone (na filmie o 15:45).

Znaczniki czasowe wideo

  • 00:00 Start
  • 2:00 Wprowadzenie do projektu
  • 5:04 Konto OpenWeather
  • 6:11 Podłączenia
  • 8:05 Wyjaśnienie kodu Arduino
  • 14:13 Elementy JSON w kodzie
  • 20:23 Wybór płytki ESP32 i portu COM w Arduino IDE
  • 22:05 Prezentacja stacji pogodowej na LCD1602
  • 23:45 Prezentacja stacji pogodowej na LCD2004

Obrazy

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
Język: C++
/*
  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 <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>


// Replace the next variables with your SSID/Password combination
const char* ssid = "SSID";
const char* password = "PASSWORD";

// Your Domain name with URL path or IP address with path
String openWeatherMapApiKey = "openWeatherMapApiKey";

// Replace with your country code and city
// Fine the country code by https://openweathermap.org/find
String city = "CITY";
String countryCode = "COUNTRY CODE";

// 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;

// set the LCD number of columns and rows
int lcdColumns = 16;
int lcdRows = 2;

// set LCD address, number of columns and rows
// SDA -> GPIO21, SCL -> GPIO22
// lcd address is 0x27, run an I2C scanner sketch
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);  

// NTP Server time
const char* ntpServer = "pool.ntp.org";
long  gmtOffset_sec = 0;
int   daylightOffset_sec = 0; //3600;

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

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

  // initialize LCD
  lcd.init();
  // turn on LCD backlight                      
  lcd.backlight();

}

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 + "&units=metric" + "&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"]);

      // Get time
      gmtOffset_sec =  myObject["timezone"]; 
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
      // time =  
      String time = printLocalTime();                     
  
      // LCD Print
      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");  // "°" char
      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");

  // get time format HH:MM
  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;
    
  // 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;
}

Zasoby i odniesienia

Pliki📁

Brak dostępnych plików.