Cari Kode

Tutorial ESP32 43/55 - Stasiun Cuaca Internet IoT | Kit Pembelajaran IoT ESP32 SunFounder

Tutorial ESP32 43/55 - Stasiun Cuaca Internet IoT | Kit Pembelajaran IoT ESP32 SunFounder

Dalam tutorial ini, kita akan membangun stasiun cuaca yang terhubung ke internet menggunakan ESP32 dan papan ekstensi kameranya dari SunFounder. Proyek ini memungkinkan ESP32 untuk mengambil data cuaca real-time, termasuk suhu dan kelembapan, dan menampilkannya di layar LCD. Aplikasi ini tidak hanya menunjukkan kemampuan ESP32 tetapi juga mendemonstrasikan cara mengambil dan mengurai data dari API eksternal.

Seiring kita melanjutkan tutorial ini, kita akan merangkai komponen, mengonfigurasi kode, dan memastikan semuanya bekerja dengan lancar bersama-sama. Hasil akhirnya akan menjadi stasiun cuaca yang berfungsi penuh yang memperbarui pembacaannya setiap 10 detik, memberikan tampilan yang jelas dan ringkas tentang kondisi cuaca saat ini (dalam video pada 00:30).

Penjelasan Perangkat Keras

Komponen utama yang digunakan dalam proyek ini termasuk mikrokontroler ESP32, layar LCD, dan kabel yang diperlukan. ESP32 dilengkapi dengan Wi-Fi dan Bluetooth bawaan, memungkinkannya untuk terhubung ke Internet dan mengambil data. Layar LCD akan menampilkan informasi cuaca saat ini, termasuk suhu dan kelembapan.

LCD yang kita gunakan adalah layar karakter 16x2, yang berarti dapat menampilkan dua baris masing-masing 16 karakter. Ini akan cukup untuk keluaran informasi cuaca kita. ESP32 akan berkomunikasi dengan LCD melalui I2C, yang menyederhanakan pengkabelan dengan hanya menggunakan dua jalur data.

Detail Datasheet

ProdusenEspressif
Nomor bagianESP32-WROOM-32
Tegangan logika/IO3,3 V
Tegangan suplai3,0–3,6 V
Arus keluaran (per saluran)Maks 12 mA
Arus puncak (per saluran)40 mA
Panduan frekuensi PWM1 kHz
Ambang logika masukan0,3 V (rendah), 0,7 V (tinggi)
Penurunan tegangan / RDS(on) / saturasi0,5 V
Batas termal-40 hingga 85 °C
KemasanQFN48
Catatan / varianTermasuk beberapa varian untuk aplikasi yang berbeda

  • Pastikan ESP32 diberi daya dengan suplai 3,3 V yang stabil.
  • Gunakan ground yang sama untuk semua komponen untuk menghindari masalah komunikasi.
  • Periksa alamat I2C LCD menggunakan pemindai I2C.
  • Pantau status koneksi Wi-Fi untuk menghindari pemutusan selama pengambilan data.
  • Tangani kesalahan penguraian JSON untuk ketahanan dalam pengambilan data.

Instruksi Pengkabelan

esp32-43-weather_station-wiring

Untuk merangkai komponen, mulailah dengan menghubungkan LCD ke ESP32. LCD akan menggunakan antarmuka I2C, jadi hubungkan pin SDA LCD ke GPIO21 pada ESP32 dan pin SCL ke GPIO22. Pastikan untuk menghubungkan pin daya dan ground LCD ke pin 5V dan GND pada ESP32, masing-masing.

Selanjutnya, pastikan ESP32 diberi daya dengan benar menggunakan baterai lithium yang disertakan atau koneksi USB. Baterai memberikan portabilitas, sementara koneksi USB berguna untuk pemrograman dan debugging. Terakhir, periksa semua koneksi aman untuk menghindari masalah kabel longgar yang dapat mengganggu fungsionalitas.

Contoh Kode & Penjelasan

Dalam fase pengaturan program kita, kita menginisialisasi komunikasi serial dan terhubung ke jaringan Wi-Fi menggunakan SSID dan kata sandi yang disediakan. Cuplikan kode berikut menangani koneksi Wi-Fi:

WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("Terhubung ke jaringan Wi-Fi dengan Alamat IP: ");
Serial.println(WiFi.localIP());

Kode ini memastikan bahwa ESP32 terhubung ke jaringan Wi-Fi yang ditentukan sebelum melanjutkan dengan pengambilan data apa pun. Jika koneksi gagal, ia akan terus mencoba menyambung kembali.

Selanjutnya, kita perlu mengirim permintaan HTTP GET untuk mengambil data cuaca. Ini dilakukan menggunakan cuplikan kode berikut:

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

Di sini, kita menyusun URL untuk permintaan API, yang mencakup kota, kode negara, dan kunci API kita. Fungsi httpGETRequest kemudian dipanggil untuk mengambil data cuaca.

Terakhir, kita mengurai respons JSON dan menampilkan data yang relevan di 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");  // karakter "°"
lcd.print("C ");    
lcd.print("H:");    
lcd.print(myObject["main"]["humidity"]);  
lcd.print("%");

Cuplikan kode ini memperbarui tampilan LCD dengan waktu saat ini, kondisi cuaca, suhu, dan kelembapan. Ini membersihkan tampilan sebelumnya dan mengatur kursor ke posisi yang sesuai untuk setiap baris.

Demonstrasi / Apa yang Diharapkan

Setelah pengkabelan dan pemrograman berhasil, stasiun cuaca Anda akan terhubung ke Wi-Fi dan mulai mengambil data cuaca setiap 10 detik. Anda akan melihat suhu saat ini, kelembapan, dan kondisi cuaca ditampilkan di layar LCD. Jika ESP32 gagal terhubung ke Wi-Fi, ia akan mencetak pesan kesalahan ke monitor serial.

Perhatikan batas panggilan API agar tidak diblokir dari layanan OpenWeatherMap. Jika Anda mengalami masalah dalam pengambilan data, periksa kunci API Anda dan pastikan kode kota serta negara Anda ditentukan dengan benar (di video pada menit 15:45).

Stempel Waktu Video

  • 00:00 Mulai
  • 2:00 Pengenalan proyek
  • 5:04 Akun OpenWeather
  • 6:11 Perangkaian kabel
  • 8:05 Penjelasan kode Arduino
  • 14:13 Elemen JASON dalam kode
  • 20:23 Memilih papan ESP32 dan port COM di Arduino IDE
  • 22:05 Demonstrasi Stasiun Cuaca pada LCD1602
  • 23:45 Demonstrasi Stasiun Cuaca pada LCD2004

Gambar

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

Sumber daya & referensi

Berkas📁

Tidak ada file tersedia.