#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#include <DHT.h>

// Definisikan ukuran layar OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Alamat I2C OLED (umumnya 0x3C)
#define OLED_I2C_ADDRESS 0x3C

// Pin untuk DHT22
#define DHTPIN 4
#define DHTTYPE DHT22

// Buat objek untuk OLED, RTC, dan DHT22
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);

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

  // Inisialisasi OLED
  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);  // Hentikan eksekusi jika OLED gagal diinisialisasi
  }

  // Inisialisasi RTC
  if (!rtc.begin()) {
    Serial.println(F("Couldn't find RTC"));
    for (;;);  // Hentikan eksekusi jika RTC gagal ditemukan
  }

  // Set waktu RTC jika belum diatur (gunakan waktu dari komputer)
  if (!rtc.isrunning()) {
    Serial.println(F("RTC is NOT running, setting the time!"));
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Mengatur waktu RTC berdasarkan waktu kompilasi
  }

  // Inisialisasi DHT22
  dht.begin();

  // Bersihkan layar OLED
  display.clearDisplay();

  // Tampilkan teks awal
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 10);
  display.println(F("RTC & DHT22 with OLED"));
  display.display();
  delay(2000);  // Tunggu sebentar sebelum melanjutkan ke loop
}  

void loop() {
  // Ambil waktu saat ini dari RTC
  DateTime now = rtc.now();

  // Ambil suhu dan kelembapan dari DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // Debugging: Cek apakah pembacaan berhasil
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F(" %\tTemperature: "));
  Serial.print(t);
  Serial.println(F(" C"));

  // Jika pembacaan DHT gagal, tampilkan pesan error
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0, 10);
    display.println(F("Error reading DHT data"));
    display.display();
    delay(2000);
    return;
  }

  // Bersihkan layar sebelum menampilkan data baru
  display.clearDisplay();

  // Tampilkan jam, menit, detik pada OLED
  display.setTextSize(2); // Ukuran teks besar untuk jam
  display.setCursor(0, 10);
  display.print(now.hour(), DEC);
  display.print(":");
  display.print(now.minute(), DEC);
  display.print(":");
  display.print(now.second(), DEC);

  // Tampilkan tanggal pada OLED
  display.setTextSize(1); // Ukuran teks kecil untuk tanggal
  display.setCursor(0, 40);
  display.print(now.day(), DEC);
  display.print("/");
  display.print(now.month(), DEC);
  display.print("/");
  display.print(now.year(), DEC);

  // Tampilkan suhu dan kelembapan pada OLED
  display.setCursor(0, 55);
  display.print(F("Temp: "));
  display.print(t);
  display.print(F(" C "));
  display.print(F("Humidity: "));
  display.print(h);
  display.print(F(" %"));

  // Perbarui layar OLED
  display.display();

  // Tunggu 2 detik sebelum memperbarui data
  delay(2000);
}
GND5VSDASCLSQWRTCDS1307+