/*
https://forum.arduino.cc/t/void-loop-stalls/1324710

*/



//ultrasound
int trigPin                      = 8;              //sets pin 8 to be 'int & trigPin'
int echoPin                      = 9;              //sets pin 8 to be 'int & echoPin'
int remaining                    = 0;              //sets variable for the remaining water
unsigned long usMillis           = 0;              //us - store for curent usMillis
unsigned long usPrevMillis       = 0;              //us - store for prior usMillis value
const unsigned long usPeriod     = 3000;           //us - period between TOF readings
int duration                     = 0;              //us - TOF
int distance                     = 0;              //distance calculated from TOF


//Hall effect flow sensor
int flowPin                      = 2;              //Sets pin 2 to be 'int & flowPin'  (which is an intrrupt pin)
double flowRate                  = 0;              //flow - calculated flow value
volatile int count               = 0;              //flow - counts number of hall effect occurences (needs to be volatile as it is used in the intrrupt)
int flowDelay                    = 10000;          //flow - period of intrupt and count

//non contact level sensor
int levelPin                     = 3;              //Sets pin 3 to be 'int & levelPin'
int fullLevel                    = 0;              //level status 1 = full / 0 = not full sets fullLevel to 0
unsigned long levelMillis        = 0;              //level - store for curent levelMillis
unsigned long levelPrevMillis    = 0;              //level - store for prior levelMillis value
const unsigned long levelPeriod  = 3000;           //level - period between FullLevel readings


//LED
int ledhi                        = 4;              //sets pin 4 to be 'int & ledhi' the green LED
int ledmed                       = 5;              //sets pin 5 to be 'int & ledmed' the yellow LDE
int ledlow                       = 6;              //sets pin 6 to be 'int & ledlow' red LDE
//unsigned long LEDMillis         = 0;     //LED - store for curent LDEMillis
//unsigned long LEDPrevMillis     = 0;     //LED - store for prior LDEMillis value
//const unsigned long             = 3000;  //LED - period between LED update
const unsigned long flashPeriod  = 1000;//LED - period between the red (ledlow) will flash when flow <= 10 l/h

//added these..
byte stateLeds = 0;
unsigned long lastLed = 0;
unsigned long ledInterval;
unsigned long now = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("ready..");


  //LEDs
  pinMode(ledhi,  OUTPUT);  //sets ledhi  (pin 4) to output
  pinMode(ledmed, OUTPUT);  //sets ledmed (pin 5) to output
  pinMode(ledlow, OUTPUT);  //sets ledlow (pin 6) to output

}

void loop() {
  // put your main code here, to run repeatedly:
  now = millis();
  floCal();
  LEDs();

}


void LEDs() {

  switch (stateLeds) {
    case 0: Serial.println(fullLevel, DEC);
      //check LEDs
      digitalWrite(ledhi, HIGH);
      digitalWrite(ledmed, HIGH);
      digitalWrite(ledlow, HIGH);
      lastLed = now;
      ledInterval = 10000;
      stateLeds++; //advance to next state
      break;
    case 1: if (now - lastLed >= ledInterval) {
        digitalWrite(ledhi, LOW);
        digitalWrite(ledmed, LOW);
        digitalWrite(ledlow, LOW);
        Serial.print("This is the flowRate value used to set the LEDs flashing, or not = ");
        Serial.println(flowRate);
        stateLeds++;
      }
      break;
    case 2: if (flowRate < 10) {
        if (now - lastLed >= flashPeriod) {
          lastLed = now;
          digitalWrite(ledlow, !digitalRead(ledlow));
        }
      } else {
        digitalWrite(ledlow, LOW);
        stateLeds++;
      }
      break;
    case 3:  //set the RAG level status LEDs
      if (fullLevel == 1) {
        remaining = 100;
      } else {  //this else will need amending to read the US sensor reading in
        remaining = 0;
      }
      Serial.print("This is the value for fullLevel used to set the RAG = ");
      Serial.println(fullLevel);
      Serial.print("This is the value for remaining used to set the RAG = ");
      Serial.println(remaining);
      stateLeds++;
      break;
    case 4:  if (remaining == 100) {
        digitalWrite(ledhi, HIGH);
        digitalWrite(ledmed, LOW);
        digitalWrite(ledlow, LOW);
      }
      if (remaining < 100) {
        digitalWrite(ledhi, LOW);
        digitalWrite(ledmed, HIGH);
        digitalWrite(ledlow, LOW);
      }
      if (remaining < 50) {
        digitalWrite(ledhi, LOW);
        digitalWrite(ledmed, LOW);
        digitalWrite(ledlow, HIGH);
      }
      stateLeds = 0;
      break;

  }

}

//the flowCal function
unsigned long lastFlow;
unsigned long flowInterval = 10000;
void flowCal() {
  if (now - lastFlow >= flowInterval){
  int localCount = 0;         //local counter
  noInterrupts();      //disable interrupts on the arduino
  localCount = count;
  count = 0;
  interrupts();    //enable the inturrupts on arduino

  //calculation
  flowRate = (23 * localCount / flowDelay);  //l/min (23  the conversion factor on the sensor) I don't know if this is the correct formular for this sensor
  flowRate = (flowRate * 60);           //l/h

  Serial.print("Water flow rate = ");
  Serial.print(flowRate);
  Serial.println(" l/h");
  }
}