#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <NewPing.h>
#include <Servo.h>

// LCD I2C connection
LiquidCrystal_I2C lcd(0x27, 20, 4); 
RTC_DS1307 rtc;

// DHT22 sensor setup
#define DHTPIN 10     
#define DHTTYPE DHT22  
DHT dht(DHTPIN, DHTTYPE);

// SR04 Ultrasonic sensor setup
#define TRIG_PIN 5 
#define ECHO_PIN 6
#define MAX_DISTANCE 200 // Maximum distance to measure (in cm)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

// Servo motor setup
Servo myServo;  
#define SERVO_PIN 9 

bool blinkColon = true;
int currentPage = 0; // Page state variable
unsigned long lastPageSwitch = 0; // Time tracker
const unsigned long pageSwitchInterval = 5000; // 5-second interval

void setup() {
  // Initialize LCD
  lcd.init();
  lcd.backlight();

  // Initialize RTC
  if (!rtc.begin()) {
    lcd.print("Couldn't find RTC");
    while (1);
  }
  if (!rtc.isrunning()) {
    lcd.print("RTC is NOT running!");
  }

  // Initialize DHT sensor
  dht.begin();

  // Initialize Servo
  myServo.attach(SERVO_PIN);
  myServo.write(90); // Start with servo at 90 degrees
}

void loop() {
  // Get current time
  DateTime now = rtc.now();
  
  // Read temperature and humidity from DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
  // Ultrasonic sensor measurement
  unsigned int distance = sonar.ping_cm();

  // Update page every 5 seconds
  if (millis() - lastPageSwitch >= pageSwitchInterval) {
    lastPageSwitch = millis();
    currentPage = (currentPage + 1) % 3; // Cycle through 3 pages
    lcd.clear(); // Clear the screen for the new page
  }

  // Display page based on the current page state
  switch (currentPage) {
    case 0:
      // Page 1: Display Date and Time
      lcd.setCursor(0, 0);
      lcd.print("Date: ");
      lcd.print(now.day(), DEC);
      lcd.print('/');
      lcd.print(now.month(), DEC);
      lcd.print('/');
      lcd.print(now.year(), DEC);

      lcd.setCursor(0, 1);
      lcd.print("Time: ");
      lcd.print(now.hour(), DEC);
      if (blinkColon) {
        lcd.print(':');
      } else {
        lcd.print(' ');
      }
      if (now.minute() < 10) {
        lcd.print('0'); 
      }
      lcd.print(now.minute(), DEC);
      blinkColon = !blinkColon;
      break;

    case 1:
      // Page 2: Display Temperature and Humidity
      if (isnan(h) || isnan(t)) {
        lcd.setCursor(0, 0);
        lcd.print("Error reading DHT");
      } else {
        lcd.setCursor(0, 0);
        lcd.print("Temp: ");
        lcd.print(t);
        lcd.print(" C");

        lcd.setCursor(0, 1);
        lcd.print("Humidity: ");
        lcd.print(h);
        lcd.print(" %");
      }
      break;

    case 2:
      // Page 3: Display Ultrasonic Distance and Servo
      lcd.setCursor(0, 0);
      lcd.print("Distance: ");
      if (distance > 0) {
        lcd.print(distance);
        lcd.print(" cm");
      } else {
        lcd.print("Out of range");
      }

      // Move servo based on distance: Less than 50 -> 0 degrees, 50 or more -> 90 degrees
      if (distance > 0 && distance < 50) {
        myServo.write(0); // Move servo to 0 degrees
      } else if (distance >= 50) {
        myServo.write(90); // Move servo to 90 degrees
      }
      break;
  }

  delay(100); // Short delay to allow blinking and smooth transitions
}
GND5VSDASCLSQWRTCDS1307+