#define LOOP_UPDATE 500
#define BUZZER_BEEP 150

// Pin definitions
const int trigPin = 2;
const int echoPin = 3;
const int buzzerPin = 4;

uint32_t lastLoopMillis = 0;

// Buzzer params
uint32_t buzzerLastMillis = 0;
bool buzzerActive = false;
int32_t buzzerInterval = -1;

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
}

void buzzer(int32_t interval) {
  if (interval < 0 || (buzzerActive && millis() - buzzerLastMillis > BUZZER_BEEP)) {
	  buzzerActive = false;  
	  digitalWrite(buzzerPin, LOW);
	  return;
  }
  
  if (millis() - buzzerLastMillis > interval) {
	  digitalWrite(buzzerPin, HIGH);  
	  buzzerActive = true;  
    buzzerLastMillis = millis();
  }
}

void loop() {
  if (millis() - lastLoopMillis > LOOP_UPDATE) {
	  digitalWrite(trigPin, LOW);
	  delayMicroseconds(2);
	  digitalWrite(trigPin, HIGH);
	  delayMicroseconds(10);
	  digitalWrite(trigPin, LOW);
	  float duration = pulseIn(echoPin, HIGH);
	  float distance = (duration / 2) * 0.0343;

	  // Print water level to serial monitor
	  Serial.print("Water level: ");
	  Serial.print(distance);
	  Serial.println(" cm");
  
  if (distance < 50) {
		buzzerInterval = 200;  // Buzzer beep 0.2s
	} else if (distance < 100) {
		buzzerInterval = 400; // Buzzer beep 0.4s
	} else if (distance < 200) {
		buzzerInterval = 750; // Buzzer beep 0.75s
	} else if (distance < 300) {
		buzzerInterval = 1000; // Buzzer beep 1s
	} else if (distance < 400) {
		buzzerInterval = 1500; // Buzzer beep 1.5s
	} else {
		buzzerInterval = -1; // Buzzer OFF
	}
	
	lastLoopMillis = millis();
  }

  buzzer(buzzerInterval);
}