#include <LiquidCrystal.h>

// Initialize the LCD with the appropriate pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

// Define pins for the ultrasonic sensor
const int trigPin = 5;
const int echoPin = 6;

// Define variables for distance calculation
float duration;
float distance;

// Define pins for the LEDs
const int greenLedPin = 2;
const int yellowLedPin = 3;
const int redLedPin = 4;

// Define pin for the buzzer
const int buzzerPin = 13;

// Function to show the startup message on the LCD
void showStartupMessage() {
  lcd.setCursor(0, 0);
  lcd.print("Distance Sensor");
  delay(1000);

  lcd.setCursor(0, 1);
  String message = "Starting Up";
  for (byte i = 0; i < message.length(); i++) {
    lcd.print(message[i]);
    delay(100);
  }
  delay(500);
}

void setup() {
  // Initialize the LCD
  lcd.begin(16, 2);
  showStartupMessage();

  // Set up the ultrasonic sensor pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Set up the LED and buzzer pins
  pinMode(greenLedPin, OUTPUT);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);

  // Start serial communication
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Trigger the ultrasonic sensor
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); // Adjusted to the standard 10us
  digitalWrite(trigPin, LOW);

  // Measure the duration of the echo
  duration = pulseIn(echoPin, HIGH);

  // Calculate the distance in cm
  distance = duration * 0.034 / 2;

  // Print the distance to the Serial Monitor
  Serial.print("Distance:");
  Serial.print(distance);
  Serial.println("cm");

  // Calculate the delay for the buzzer rhythm based on distance
  int delayTime;
  if (distance < 25) {
    delayTime = 100; // Fast rhythm for close distance
  } else if (distance >= 25 && distance < 75) {
    delayTime = 300; // Medium rhythm for medium distance
  } else {
    delayTime = 600; // Slow rhythm for far distance
  }

  // Update the LCD and LEDs based on the distance
  if (distance < 25) {
    digitalWrite(greenLedPin, LOW);
    digitalWrite(yellowLedPin, LOW);
    digitalWrite(redLedPin, HIGH);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Stop");
  } else if (distance >= 25 && distance < 75) {
    digitalWrite(greenLedPin, LOW);
    digitalWrite(yellowLedPin, HIGH);
    digitalWrite(redLedPin, LOW);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Close");
  } else {
    digitalWrite(greenLedPin, HIGH);
    digitalWrite(yellowLedPin, LOW);
    digitalWrite(redLedPin, LOW);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Safe Distance");
  }

  // Print the distance on the LCD
  lcd.setCursor(0, 1);
  lcd.print("Distance:");
  lcd.print(distance);
  lcd.print("cm");
  
  //lcd.setCursor(0, 1);
  //lcd.print(distance);
  //lcd.print(" cm");

  // Control the buzzer rhythm based on the distance
  tone(buzzerPin, 1000); // Use a fixed frequency for simplicity
  delay(delayTime);
  noTone(buzzerPin);
  delay(delayTime);

  // Small delay before the next measurement
  delay(100);
}