int DT = 4;   // GPIO #4-DT on encoder (Output B)
int CLK = 5;  // GPIO #5-CLK on encoder (Output A)

float distanceTraveled = 0; // Variable to store the accumulated distance
float deltaFlow = 0; // Variable to store the delta flow rate
float bentFlow = 0; // Variable to store the bent flow rate
float D_machine = 4.041; // Machine diameter in meters
float A_machine = PI * D_machine * D_machine / 4.0; // A_machine: Machine area
float D_pipe = 3.996; // Pipe diameter in meters
float AOC = PI * (D_machine * D_machine - D_pipe * D_pipe) / 4.0; // AOC: Overcut area
int aState;
int aLastState;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // Adjust the debounce delay as needed

unsigned long previousMillis = 0; // Variable to store the last time the counter changed

void setup() {
  Serial.begin(9600);
  pinMode(CLK, INPUT_PULLUP);
  pinMode(DT, INPUT_PULLUP);
  aLastState = digitalRead(CLK);
}

void loop() {
  aState = digitalRead(CLK);

  // Encoder rotation tracking with debounce
  if (aState != aLastState) {
    if (millis() - lastDebounceTime > debounceDelay) {
      if (digitalRead(DT) != aState) {
        distanceTraveled += 0.5; // Increment the accumulated distance by 0.5mm
      } else {
        distanceTraveled -= 0.5; // Decrement the accumulated distance by 0.5mm
      }

      unsigned long currentMillis = millis();  // Get the current time
      unsigned long timeDiff = currentMillis - previousMillis;  // Calculate the time difference since the last counter change

      // Calculate distance moved per pulse (0.5mm per pulse)
      float distancePerPulse = 0.5; // in mm
      float speed_mm_min = (distancePerPulse / timeDiff) * 60000; // Calculate speed in mm/min

      // Convert speed to meters per hour (m/hr)
      float speed_m_hr = speed_mm_min * 60 / 1000.0; // Convert mm/min to m/hr

      // Calculate delta flow rate in m³/hr
      deltaFlow = speed_m_hr * A_machine; // m³/hr

      // Calculate bent flow rate in m³/hr
      bentFlow = speed_m_hr * AOC; // m³/hr

      Serial.print("Linear Speed (mm/min): ");
      Serial.println(speed_mm_min);

      Serial.print("Distance Traveled (m): ");
      Serial.println(distanceTraveled / 1000);

      Serial.print("Delta Flow Rate (m³/hr): ");
      Serial.println(deltaFlow);

      // Convert bentFlow to liters per minute (L/min)
      float bentFlow_L_min = bentFlow * 1000 / 60; // Convert m³/hr to L/min

      Serial.print("Bent Flow Rate (L/min): ");
      Serial.println(bentFlow_L_min);

      lastDebounceTime = millis(); // Reset the debounce timer
      previousMillis = currentMillis;  // Update the previous time
    }
  }

  aLastState = aState;
}