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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int flowSensorPin = 2; // The pin number to which the flow sensor output is connected
const int relayPin = 3; // The pin number to which the relay is connected
volatile int flowCount; // Variable to store the number of pulses from the flow sensor
unsigned long startTime; // Variable to store the start time
float flowRate; // Variable to store the flow rate
bool pumpStatus = false; // Variable to store the status of the pump

void setup() {
  pinMode(flowSensorPin, INPUT_PULLUP); // Set flow sensor pin as input with pull-up resistor
  attachInterrupt(digitalPinToInterrupt(flowSensorPin), flowCounter, RISING); // Attach interrupt to flow sensor pin
  pinMode(relayPin, OUTPUT); // Set relay pin as output
  digitalWrite(relayPin, LOW); // Ensure relay is initially off
  Serial.begin(9600); // Initialize serial communication
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize OLED display
  display.display();
  delay(2000); // Delay to allow time for display to initialize
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.println("Flow Rate:");
  display.println("Pump Status: OFF");
  display.display();
}

void loop() {
  unsigned long currentTime = millis(); // Get the current time
  if (currentTime - startTime >= 1000) { // Calculate flow rate every second
    detachInterrupt(digitalPinToInterrupt(flowSensorPin)); // Detach interrupt to prevent interference during calculation
    flowRate = (flowCount / 7.5); // Calculate flow rate in liters per minute (assuming 7.5 pulses per liter)
   // Serial.print("Flow Rate: ");
  //  Serial.print(flowRate);
  //  Serial.println(" L/min");
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0,0);
    display.print("Flow Rate: ");
    display.print(flowRate);
     display.setCursor(0,0);
    display.println(" L/min");
     display.setCursor(0,0);
    display.print("Pump Status: ");
    if (pumpStatus) {
      display.println("ON");
    } else {
      display.println("OFF");
    }
    display.display();
    if (flowRate > 2) {
      digitalWrite(relayPin, HIGH); // Energize relay if flow rate exceeds 2 L/min
      pumpStatus = true;
    } else {
      digitalWrite(relayPin, LOW); // De-energize relay if flow rate is below 2 L/min
      pumpStatus = false;
    }
    flowCount = 0; // Reset flow count
    startTime = currentTime; // Update start time
    attachInterrupt(digitalPinToInterrupt(flowSensorPin), flowCounter, RISING); // Attach interrupt again
  }
}

void flowCounter() {
  flowCount++; // Increment flow count when interrupt is triggered by flow sensor pulse
}