Water Hose Dispenser

Hi

I’m trying to build an appliance where you enter a number in gallons on a keypad and using a hall effect sensor, monitor water flow and when the water flow quantity equals the amount entered it click off a power switch tail to turn the pump off.

Below is my code. The problem is the value I enter in the keypad doesn’t transfer over to a variable that I can use to compare with water flow and the value I type keeps getting erased and I can’t get my head around how to debug it. Please Help.

Thanks In Advance

#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


unsigned long currentTime = 0;
byte data_count=0;
char Data[2];
int iGallons;

byte statusLed    = 13;

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;

const byte pumpPin=3;

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;

volatile byte pulseCount;

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

unsigned long oldTime;

//keypad setup stuff
const byte ROWS = 4; 
const byte COLS = 4; 

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {11, 10, 9, 8}; 
byte colPins[COLS] = {7, 6, 5, 4}; 

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
LiquidCrystal_I2C lcd(0x3F,20,4); 

void setup()
{

  // Initialize a serial connection for reporting values to the host
  Serial.begin(9600);
  
  pinMode(pumpPin, INPUT_PULLUP);
  pinMode(pumpPin, OUTPUT);
  digitalWrite(pumpPin, HIGH);
          
  //if 15 seconds go by and Data[0] is still 0 
  //and not a # the system will auto set to 0 and be on constantly
  Data[0]='0';
  iGallons=0;

  // Set up the status LED line as an output
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached

  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;

  // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
  // Configured to trigger on a FALLING state change (transition from HIGH
  // state to LOW state)
  attachInterrupt(sensorInterrupt, pulseCount, FALLING);
  lcd.init();
  lcd.backlight();
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Gallons: ");

  
  char key = customKeypad.getKey();
  


  detachInterrupt(sensorInterrupt);


  flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;

  oldTime = millis();


  flowMilliLitres = (flowRate / 60) * 1000;

  totalMilliLitres += flowMilliLitres;

  unsigned int frac;


  if(Data[0]=='0' && currentTime>10)
  {
    lcd.clear();
    lcd.setCursor(2,0);
    // Print the cumulative total of litres flowed since starting
    lcd.print("Quart: ");
    lcd.print((totalMilliLitres * 0.00105669));
    lcd.setCursor(2,1);
    lcd.print( "Liters: ");
    lcd.print((flowRate / 60));
    lcd.setCursor(2,2);
    lcd.print("Gallons: ");
    lcd.print(totalMilliLitres / 3785.41);
  }
  else 
  {
    if(key=='#')
    {
      lcd.clear();
      
      unsigned long curGallons=totalMilliLitres / 3785.41;
      iGallons=atoi(Data);
      lcd.print(curGallons);
      lcd.print(" of ");
      lcd.print(iGallons);

      if(curGallons>=iGallons)
      {
          digitalWrite(pumpPin, LOW);
      }
    }
    else
    {
      
       int c = (int)key - 48;
      inNum *= 10;
      inNum += c;
    
      Data[data_count] = inNum;
      lcd.print(atoi(Data)); 
      lcd.print(inNum);
      data_count++;
    }
  }
  
  // Reset the pulse counter so we can start incrementing again
  pulseCount = 0;

    // Enable the interrupt again now that we've finished sending output
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  currentTime++;
  delay(1000); 
}

/*
  Insterrupt Service Routine
*/
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

I see several issues in the code.

Not sure why you are configuring pumpPin as an input and then reconfiguring it:

  pinMode(pumpPin, INPUT_PULLUP);
  pinMode(pumpPin, OUTPUT);

The following line in setup is incorrect:

  attachInterrupt(sensorInterrupt, pulseCount, FALLING);

It should be:

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

Instead of delay(1000) you should use millis() to time 1 second because the lcd.print statements will throw the timing off. There is really no need to detach and attach the interrupt. You can just reset pulseCount.

With regard to keypad entry, getKey() is non-blocking so you need to check for NO_KEY.