Search Code

ESP32 Eğitimi 43/55 - IoT İnternet Hava Durumu İstasyonu | SunFounder'ın ESP32 IoT Öğrenme Kiti

ESP32 Eğitimi 43/55 - IoT İnternet Hava Durumu İstasyonu | SunFounder'ın ESP32 IoT Öğrenme Kiti

Bu eğitimde, ESP32 ve SunFounder'dan kamera genişletme kartını kullanarak internete bağlı bir hava durumu istasyonu kuracağız. Bu proje, ESP32'nin sıcaklık ve nem dahil olmak üzere gerçek zamanlı hava durumu verilerini almasını ve bunları bir LCD ekranda görüntülemesini sağlar. Bu uygulama yalnızca ESP32'nin yeteneklerini sergilemekle kalmaz, aynı zamanda harici bir API'den veri almayı ve ayrıştırmayı da gösterir.

Eğitimde ilerledikçe bileşenleri bağlayacağız, kodu yapılandıracağız ve her şeyin sorunsuz bir şekilde birlikte çalışmasını sağlayacağız. Sonuç, okumalarını her 10 saniyede bir güncelleyen ve mevcut hava koşullarının net ve öz bir görüntüsünü sağlayan (videoda 00:30'da) tamamen işlevsel bir hava durumu istasyonu olacaktır.

Donanım Açıklaması

Bu projede kullanılan ana bileşenler ESP32 mikrodenetleyicisi, bir LCD ekran ve gerekli kablolamadır. ESP32, internete bağlanmasına ve veri almasına olanak tanıyan yerleşik Wi-Fi ve Bluetooth ile donatılmıştır. LCD ekran, sıcaklık ve nem dahil olmak üzere mevcut hava durumu bilgilerini gösterecektir.

Kullandığımız LCD, 16x2 karakterli bir ekrandır; bu, her biri 16 karakterden oluşan iki satır gösterebileceği anlamına gelir. Bu, hava durumu bilgisi çıktımız için yeterli olacaktır. ESP32, LCD ile yalnızca iki veri hattı kullanarak kablolamayı basitleştiren I2C üzerinden iletişim kuracaktır.

Veri Sayfası Ayrıntıları

ÜreticiEspressif
Parça numarasıESP32-WROOM-32
Mantık/G/Ç voltajı3,3 V
Besleme voltajı3,0–3,6 V
Çıkış akımı (kanal başına)maks. 12 mA
Tepe akımı (kanal başına)40 mA
PWM frekansı kılavuzu1 kHz
Giriş mantık eşikleri0,3 V (düşük), 0,7 V (yüksek)
Gerilim düşümü / RDS(on) / doyum0,5 V
Termal sınırlar-40 ila 85 °C
PaketQFN48
Notlar / varyantlarFarklı uygulamalar için birden fazla varyant içerir

  • ESP32'nin sabit bir 3,3 V kaynakla beslendiğinden emin olun.
  • İletişim sorunlarını önlemek için tüm bileşenler için ortak bir toprak kullanın.
  • Bir I2C tarayıcı kullanarak LCD'nin I2C adresini kontrol edin.
  • Veri alımı sırasında bağlantı kopmalarını önlemek için Wi-Fi bağlantı durumunu izleyin.
  • Veri alımında sağlamlık için JSON ayrıştırma hatalarını ele alın.

Bağlantı Talimatları

esp32-43-weather_station-wiring

Bileşenleri bağlamak için LCD'yi ESP32'ye bağlayarak başlayın. LCD, I2C arayüzünü kullanacaktır; bu nedenle LCD'nin SDA pinini ESP32'deki GPIO21'e ve SCL pinini GPIO22'ye bağlayın. LCD'nin güç ve toprak pinlerini sırasıyla ESP32'deki 5V ve GND pinlerine bağladığınızdan emin olun.

Ardından, ESP32'nin dahil edilen lityum pil veya bir USB bağlantısı kullanılarak doğru şekilde beslendiğinden emin olun. Pil taşınabilirlik sağlarken, USB bağlantısı programlama ve hata ayıklama için kullanışlıdır. Son olarak, işlevselliği bozabilecek gevşek kablo sorunlarını önlemek için tüm bağlantıların güvenli olduğunu kontrol edin.

Kod Örnekleri ve Açıklama

Programımızın kurulum aşamasında, seri iletişimi başlatır ve sağlanan SSID ve şifreyi kullanarak Wi-Fi ağına bağlanırız. Aşağıdaki kod parçası Wi-Fi bağlantısını yönetir:

WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("Wi-Fi ağına IP Adresi ile bağlanıldı: ");
Serial.println(WiFi.localIP());

Bu kod, ESP32'nin herhangi bir veri alma işlemine geçmeden önce belirtilen Wi-Fi ağına bağlanmasını sağlar. Bağlantı başarısız olursa, sürekli olarak yeniden bağlanmayı deneyecektir.

Ardından, hava durumu verilerini almak için bir HTTP GET isteği göndermemiz gerekir. Bu, aşağıdaki kod parçası kullanılarak gerçekleştirilir:

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

Burada, şehir, ülke kodu ve API anahtarımızı içeren API isteği için URL'yi oluşturuyoruz. Ardından hava durumu verilerini almak için httpGETRequest işlevi çağrılır.

Son olarak, JSON yanıtını ayrıştırır ve ilgili verileri LCD'de görüntüleriz:

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");  // "°" karakteri
lcd.print("C ");    
lcd.print("H:");    
lcd.print(myObject["main"]["humidity"]);  
lcd.print("%");

Bu kod parçası, LCD ekranı mevcut saat, hava durumu koşulu, sıcaklık ve nem ile günceller. Önceki görüntüyü temizler ve imleci her satır için uygun konumlara ayarlar.

Gösterim / Beklentiler

Başarılı bir bağlantı ve programlama sonrasında, hava durumu istasyonunuz Wi-Fi'ye bağlanacak ve her 10 saniyede bir hava durumu verilerini almaya başlayacaktır. LCD ekranda mevcut sıcaklık, nem ve hava koşullarını göreceksiniz. ESP32 Wi-Fi'ye bağlanamazsa, seri monitöre bir hata mesajı yazdıracaktır.

API çağrı limitlerine dikkat ederek OpenWeatherMap hizmetinden engellenmekten kaçının. Veri alımında herhangi bir sorunla karşılaşırsanız, API anahtarınızı kontrol edin ve şehir ile ülke kodunuzun doğru belirtildiğinden emin olun (videoda 15:45'te).

Video Zaman Damgaları

  • 00:00 Başlangıç
  • 2:00 Projeye giriş
  • 5:04 OpenWeather Hesabı
  • 6:11 Bağlantılar
  • 8:05 Arduino kodu açıklaması
  • 14:13 Kod içindeki JSON öğeleri
  • 20:23 Arduino IDE'de ESP32 kartı ve COM portu seçimi
  • 22:05 LCD1602 üzerinde Hava İstasyonu gösterimi
  • 23:45 LCD2004 üzerinde Hava İstasyonu gösterimi

Görseller

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

Kaynaklar ve referanslar

Dosyalar📁

Dosya mevcut değil.