Search Code

ESP32 Упатство 43/55 - IoT Интернет Временска Станица | SunFounder's ESP32 IoT Комплет за учење

ESP32 Упатство 43/55 - IoT Интернет Временска Станица | SunFounder's ESP32 IoT Комплет за учење

Во ова упатство, ќе изградиме интернет-поврзана временска станица користејќи го ESP32 и неговата камера продолжна плоча од SunFounder. Овој проект му овозможува на ESP32 да презема податоци за времето во реално време, вклучувајќи температура и влажност, и да ги прикаже на LCD екран. Оваа апликација не само што ги покажува можностите на ESP32, туку и демонстрира како да се преземат и парсираат податоци од надворешен API.

Како што напредуваме низ упатството, ќе ги поврземе компонентите, ќе го конфигурираме кодот и ќе се осигураме дека сè работи беспрекорно заедно. Крајниот резултат ќе биде целосно функционална временска станица која ги ажурира своите читања на секои 10 секунди, обезбедувајќи јасен и концизен приказ на моменталните временски услови (во видео на 00:30).

Објаснување на хардверот

Главните компоненти користени во овој проект вклучуваат ESP32 микроконтролер, LCD екран и потребното поврзување. ESP32 е опремен со вграден Wi-Fi и Bluetooth, што му овозможува да се поврзе на интернет и да презема податоци. LCD екранот ќе ги прикажува моменталните временски информации, вклучувајќи температура и влажност.

LCD екранот што го користиме е 16x2 карактерен дисплеј, што значи дека може да прикаже две линии од по 16 карактери. Ова ќе биде доволно за нашиот излез на временски информации. ESP32 ќе комуницира со LCD преку I2C, што го поедноставува поврзувањето со користење само на две линии за податоци.

Детали од техничката документација

ПроизводителEspressif
Број на делESP32-WROOM-32
Логички/IO напон3.3 V
Напон на напојување3.0–3.6 V
Излезна струја (по канал)12 mA макс
Врвна струја (по канал)40 mA
Насоки за PWM фреквенција1 kHz
Прагови на влезна логика0.3 V (ниско), 0.7 V (високо)
Пад на напон / RDS(on) / заситување0.5 V
Термички граници-40 до 85 °C
ПакетQFN48
Белешки / варијантиВклучува повеќе варијанти за различни апликации

  • Осигурајте се дека ESP32 е напојуван со стабилен 3.3 V напон.
  • Користете заедничка земја за сите компоненти за да избегнете проблеми со комуникацијата.
  • Проверете ја I2C адресата на LCD екранот користејќи I2C скенер.
  • Следете го статусот на Wi-Fi конекцијата за да избегнете прекини при преземање податоци.
  • Ракувајте со грешки при JSON парсирање за робусност при преземање податоци.

Инструкции за поврзување

esp32-43-weather_station-wiring

За да ги поврзете компонентите, започнете со поврзување на LCD екранот со ESP32. LCD екранот ќе го користи I2C интерфејсот, па поврзете ја SDA пината на LCD екранот со GPIO21 на ESP32 и SCL пината со GPIO22. Осигурајте се да ги поврзете пините за напојување и земја на LCD екранот со 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 екранот:

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("%");

Овој фрагмент од код го ажурира LCD екранот со моменталното време, временската состојба, температурата и влажноста. Тој го чисти претходниот приказ и го поставува курсорот на соодветните позиции за секоја линија.

Демонстрација / Што да очекувате

По успешното поврзување и програмирање, вашата временска станица ќе се поврзе на Wi-Fi и ќе започне да презема временски податоци на секои 10 секунди. Ќе ги видите моменталната температура, влажност и временските услови прикажани на LCD екранот. Ако ESP32 не успее да се поврзе на Wi-Fi, ќе испечати порака за грешка на серискиот монитор.

Внимавајте на ограничувањата на API повиците за да не бидете блокирани од услугата OpenWeatherMap. Ако наидете на проблеми со преземањето податоци, проверете го вашиот API клуч и осигурете се дека вашиот град и кодот на државата се правилно наведени (во видеото на 15:45).

Временски ознаки на видеото

  • 00:00 Почеток
  • 2:00 Вовед во проектот
  • 5:04 OpenWeather сметка
  • 6:11 Поврзување (Wiring)
  • 8:05 Објаснување на Arduino кодот
  • 14:13 JASON елементи во кодот
  • 20:23 Избор на ESP32 плоча и COM порта во Arduino IDE
  • 22:05 Демонстрација на временска станица на LCD1602
  • 23:45 Демонстрација на временска станица на LCD2004

Images

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

Resources & references

Files📁

No files available.