#define MICROSECONDS_PER_TICK (portTICK_PERIOD_MS / 1000)

int threshold = 61;
int senseTime = 2;
int flushTime = 7;

//Flow Sensor Variables ========================================================================
const int flowsensor = 16;
const int ledPin = 17;
volatile int flowDetected = 0;
unsigned long lastFlowTime = 0;
const unsigned long flowTimeout = 1000; 

void flowChange() {
  flowDetected = 1;
  lastFlowTime = millis();
}

void flowSense(void *pvParameters) {
  for (;;) {
  unsigned long currentTime = millis();
    if (flowDetected && (currentTime - lastFlowTime < flowTimeout)) {
      digitalWrite(ledPin, HIGH); // Turn on the LED
    } else {
      digitalWrite(ledPin, LOW); // Turn off the LED
      flowDetected = 0; // Reset flow detection when there is no flow
    }
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

//Uri 1 ========================================================================
const int trig1 = 33;
const int echo1 = 32;
const int relay1 = 4;

long duration1;
int distance1;

int count1 = 0;
int wait1 = 0;
int tFlush1 = 0;

void uri1(void * parameters) {
  for(;;){
    // Clears the trigPin
    digitalWrite(trig1, LOW);
    vTaskDelay(pdMS_TO_TICKS(2));

    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trig1, HIGH);
    vTaskDelay(pdMS_TO_TICKS(10));
    digitalWrite(trig1, LOW);

    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration1 = pulseIn(echo1, HIGH);

    // Calculating the distance
    distance1 = duration1 * 0.034/2;

if (distance1 <= threshold && wait1 !=1){
  if (count1 <= senseTime){
    count1++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
  
  if (count1 > senseTime){
    count1 = 0;
    wait1 = 1;
  }
}

if (count1 <= senseTime && distance1 > threshold && wait1 != 1){
  count1 = 0;
}

if (wait1 == 1){
  if (distance1 > threshold){
    digitalWrite(relay1, LOW);
    tFlush1++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    if (tFlush1 > flushTime){
      tFlush1 = 0;
      wait1 = 0;
    }
  }

  if (distance1 <= threshold){ 
    tFlush1 = 0;
    digitalWrite(relay1, HIGH);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

    if (wait1 == 0){
      digitalWrite(relay1, HIGH);
    }
  }
}

//Uri 2 ========================================================================
const int trig2 = 26;
const int echo2 = 25;
const int relay2 = 0;

long duration2;
int distance2;
int count2 = 0;
int wait2 = 0;
int tFlush2 = 0;

void uri2(void * parameters) {
  for(;;){
    // Clears the trigPin
    digitalWrite(trig2, LOW);
    vTaskDelay(pdMS_TO_TICKS(2));

    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trig2, HIGH);
    vTaskDelay(pdMS_TO_TICKS(10));
    digitalWrite(trig2, LOW);

    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration2 = pulseIn(echo2, HIGH);

    // Calculating the distance
    distance2 = duration2 * 0.034/2;

if (distance2 <= threshold && wait2 !=1){
  if (count2 <= senseTime){
    count2++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
  
  if (count2 > senseTime){
    count2 = 0;
    wait2 = 1;
  }
}

if (count2 <= senseTime && distance2 > threshold && wait2 != 1){
  count2 = 0;
}

if (wait2 == 1){
  if (distance2 > threshold){
    digitalWrite(relay2, LOW);
    tFlush2++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    if (tFlush2 > flushTime){
      tFlush2 = 0;
      wait2 = 0;
    }
  }

  if (distance2 <= threshold){ 
    tFlush2 = 0;
    digitalWrite(relay2, HIGH);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

    if (wait2 == 0){
      digitalWrite(relay2, HIGH);
    }
  }
}

//Uri 3 ========================================================================
const int trig3 = 14;
const int echo3 = 27;
const int relay3 = 2;

long duration3;
int distance3;
int count3 = 0;
int wait3 = 0;
int tFlush3 = 0;


void uri3(void * parameters) {
  for(;;){
    // Clears the trigPin
    digitalWrite(trig3, LOW);
    vTaskDelay(pdMS_TO_TICKS(2));

    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trig3, HIGH);
    vTaskDelay(pdMS_TO_TICKS(10));
    digitalWrite(trig3, LOW);

    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration3 = pulseIn(echo3, HIGH);

    // Calculating the distance
    distance3 = duration3 * 0.034/2;

if (distance3 <= threshold && wait3 !=1){
  if (count3 <= senseTime){
    count3++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
  
  if (count3 > senseTime){
    count3 = 0;
    wait3 = 1;
  }
}

if (count3 <= senseTime && distance3 > threshold && wait3 != 1){
  count3 = 0;
}

if (wait3 == 1){
  if (distance3 > threshold){
    digitalWrite(relay3, LOW);
    tFlush3++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    if (tFlush3 > flushTime){
      tFlush3 = 0;
      wait3 = 0;
    }
  }

  if (distance3 <= threshold){ 
    tFlush3 = 0;
    digitalWrite(relay3, HIGH);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

    if (wait3 == 0){
      digitalWrite(relay3, HIGH);
    }
  }
}

//Uri 4 ========================================================================
const int trig4 = 13;
const int echo4 = 12;
const int relay4 = 15;

long duration4;
int distance4;
int count4 = 0;
int wait4 = 0;
int tFlush4 = 0;

void uri4(void * parameters) {
  for(;;){
    // Clears the trigPin
    digitalWrite(trig4, LOW);
    vTaskDelay(pdMS_TO_TICKS(2));

    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trig4, HIGH);
    vTaskDelay(pdMS_TO_TICKS(10));
    digitalWrite(trig4, LOW);

    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration4 = pulseIn(echo4, HIGH);

    // Calculating the distance
    distance4 = duration4 * 0.034/2;

if (distance4 <= threshold && wait4 !=1){
  if (count4 <= senseTime){
    count4++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
  
  if (count4 > senseTime){
    count4 = 0;
    wait4 = 1;
  }
}

if (count4 <= senseTime && distance4 > threshold && wait4 != 1){
  count4 = 0;
}

if (wait4 == 1){
  if (distance4 > threshold){
    digitalWrite(relay4, LOW);
    tFlush4++;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    if (tFlush4 > flushTime){
      tFlush4 = 0;
      wait4 = 0;
    }
  }

  if (distance4 <= threshold){ 
    tFlush4 = 0;
    digitalWrite(relay4, HIGH);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

    if (wait4 == 0){
      digitalWrite(relay4, HIGH);
    }
  }
}

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

//Uri 1 ========================================================================
  pinMode(trig1, OUTPUT); 
  pinMode(echo1, INPUT); 
  pinMode(relay1, OUTPUT);

  xTaskCreatePinnedToCore(uri1, "Urinal One", 5000, NULL, 1, NULL, 1);

//Uri 2 ========================================================================
  pinMode(trig2, OUTPUT); 
  pinMode(echo2, INPUT); 
  pinMode(relay2, OUTPUT);

  xTaskCreatePinnedToCore(uri2, "Urinal Two", 5000, NULL, 1, NULL, 1);

//Uri 3 ========================================================================
  pinMode(trig3, OUTPUT); 
  pinMode(echo3, INPUT); 
  pinMode(relay3, OUTPUT);

  xTaskCreatePinnedToCore(uri3, "Urinal Three",5000, NULL, 1, NULL, 0);

//Uri 4 ========================================================================
  pinMode(trig4, OUTPUT); 
  pinMode(echo4, INPUT); 
  pinMode(relay4, OUTPUT);

  xTaskCreatePinnedToCore(uri4, "Urinal Four", 5000, NULL, 1, NULL, 0);

//Flow Sensor ========================================================================
  pinMode(flowsensor, INPUT);
  digitalWrite(flowsensor, HIGH);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  attachInterrupt(digitalPinToInterrupt(flowsensor), flowChange, FALLING);

  xTaskCreatePinnedToCore(flowSense, "flowSense Core1", 5000, NULL, 1, NULL, 1);
}


void loop() {

}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module