Hľadať kód

Výukový program ESP32 43/55 - IoT internetová meteorologická stanica | SunFounderova ESP32 IoT vzdelávacia súprava

Výukový program ESP32 43/55 - IoT internetová meteorologická stanica | SunFounderova ESP32 IoT vzdelávacia súprava

V tomto návode si postavíme internetovú meteorologickú stanicu pomocou ESP32 a jeho kamerovej rozširujúcej dosky od SunFounder. Tento projekt umožňuje ESP32 získavať údaje o počasí v reálnom čase, vrátane teploty a vlhkosti, a zobrazovať ich na LCD obrazovke. Táto aplikácia nielenže ukazuje možnosti ESP32, ale tiež demonštruje, ako získavať a spracovávať dáta z externého API.

Ako budeme postupovať v návode, zapojíme komponenty, nakonfigurujeme kód a zabezpečíme, aby všetko fungovalo bezproblémovo. Výsledkom bude plne funkčná meteorologická stanica, ktorá aktualizuje svoje údaje každých 10 sekúnd a poskytuje jasný a stručný prehľad aktuálnych poveternostných podmienok (vo videu o 00:30).

Vysvetlenie hardvéru

Hlavné komponenty použité v tomto projekte zahŕňajú mikrokontrolér ESP32, LCD displej a potrebné zapojenie. ESP32 je vybavený vstavaným Wi-Fi a Bluetooth, čo mu umožňuje pripojiť sa na internet a získavať dáta. LCD displej zobrazí aktuálne informácie o počasí vrátane teploty a vlhkosti.

Používaný LCD je 16x2 znakový displej, čo znamená, že môže zobraziť dva riadky po 16 znakoch. To bude postačujúce pre náš výstup informácií o počasí. ESP32 bude komunikovať s LCD cez I2C, čo zjednodušuje zapojenie použitím iba dvoch dátových liniek.

Podrobnosti z datasheetu

VýrobcaEspressif
Označenie dieluESP32-WROOM-32
Logické/IO napätie3,3 V
Napájacie napätie3,0–3,6 V
Výstupný prúd (na kanál)max. 12 mA
Špičkový prúd (na kanál)40 mA
Odporúčaná PWM frekvencia1 kHz
Logické prahové hodnoty vstupu0,3 V (nízka), 0,7 V (vysoká)
Pokles napätia / RDS(on) / saturácia0,5 V
Tepelné limity-40 až 85 °C
PuzdroQFN48
Poznámky / variantyZahŕňa viacero variantov pre rôzne aplikácie

  • Uistite sa, že ESP32 je napájaný stabilným napätím 3,3 V.
  • Použite spoločnú zem pre všetky komponenty, aby ste predišli problémom s komunikáciou.
  • Skontrolujte I2C adresu LCD pomocou I2C skenera.
  • Sledujte stav Wi-Fi pripojenia, aby ste predišli odpojeniam počas získavania dát.
  • Spracujte chyby pri parsovaní JSON pre robustnosť pri získavaní dát.

Pokyny na zapojenie

esp32-43-weather_station-wiring

Pri zapájaní komponentov začnite pripojením LCD k ESP32. LCD bude používať I2C rozhranie, takže pripojte pin SDA z LCD na GPIO21 na ESP32 a pin SCL na GPIO22. Uistite sa, že napájacie a uzemňovacie piny LCD pripojíte na piny 5V a GND na ESP32.

Ďalej sa uistite, že ESP32 je správne napájaný pomocou priloženej lítiovej batérie alebo USB pripojenia. Batéria poskytuje prenosnosť, zatiaľ čo USB pripojenie je užitočné na programovanie a ladenie. Nakoniec skontrolujte, či sú všetky spojenia pevné, aby ste predišli problémom s uvoľnenými vodičmi, ktoré by mohli narušiť funkčnosť.

Príklady kódu a vysvetlenie

Vo fáze nastavenia nášho programu inicializujeme sériovú komunikáciu a pripojíme sa k Wi-Fi sieti pomocou poskytnutého SSID a hesla. Nasledujúci úryvok kódu spracováva Wi-Fi pripojenie:

WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("Pripojené k Wi-Fi sieti s IP adresou: ");
Serial.println(WiFi.localIP());

Tento kód zabezpečuje, že sa ESP32 pripojí k zadanej Wi-Fi sieti pred pokračovaním v získavaní dát. Ak pripojenie zlyhá, bude sa neustále pokúšať o opätovné pripojenie.

Ďalej musíme odoslať HTTP GET požiadavku na získanie údajov o počasí. To sa dosiahne pomocou nasledujúceho úryvku kódu:

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

Tu zostavíme URL adresu pre API požiadavku, ktorá zahŕňa mesto, kód krajiny a náš API kľúč. Funkcia httpGETRequest sa potom zavolá na získanie údajov o počasí.

Nakoniec parsujeme JSON odpoveď a zobrazíme príslušné dáta 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("%");

Tento úryvok kódu aktualizuje LCD displej s aktuálnym časom, poveternostnými podmienkami, teplotou a vlhkosťou. Vymaže predchádzajúce zobrazenie a nastaví kurzor na príslušné pozície pre každý riadok.

Demonštrácia / Čo očakávať

Po úspešnom zapojení a naprogramovaní sa vaša meteorologická stanica pripojí k Wi-Fi a začne získavať údaje o počasí každých 10 sekúnd. Na LCD obrazovke uvidíte aktuálnu teplotu, vlhkosť a poveternostné podmienky. Ak sa ESP32 nepodarí pripojiť k Wi-Fi, vypíše chybové hlásenie do sériového monitora.

Dbte na limity API volaní, aby ste sa vyhli zablokovaniu služby OpenWeatherMap. Ak narazíte na problémy so získavaním údajov, skontrolujte svoj API kľúč a uistite sa, že vaše mesto a kód krajiny sú správne zadané (vo videu o 15:45).

Časové značky videa

  • 00:00 Začiatok
  • 2:00 Úvod do projektu
  • 5:04 OpenWeather účet
  • 6:11 Zapojenie
  • 8:05 Vysvetlenie kódu Arduino
  • 14:13 JASON prvky v kóde
  • 20:23 Výber dosky ESP32 a COM portu v Arduino IDE
  • 22:05 Ukážka meteorologickej stanice na LCD1602
  • 23:45 Ukážka meteorologickej stanice na LCD2004

Obrázky

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
Jazyk: 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;
}

Zdroje a referencie

Súbory📁

Žiadne súbory nie sú k dispozícii.