Some hints.
Pressing the button latches the relay, presumably energised, to the ON state. It stays ON when you release the button. Look at states and toggling push-buttons. Statechange in Arduino examples always works well.
You need to look at de-bouncing as well.
In your code, you read the flow rate by counting pulses and convert that to flow - you start off talking about flow, then talk about volume. 500ml is a volume not a flow - 500ml per second is a flow.
So get that straight first. If you are measuring a volume, you don't need a flow-meter.
So are you monitoring the flow and turning the relay off when it goes over 500ml per ?? or do you want to turn it off when you get 500ml volume?
Either way, you use an IF statement to compare what you are measuring against a fixed value and make a decision based on the two values. So, if flow or volume is greater or equal to 500, turn off, if not, don't turn off.
If this is your first project, you are going to have to get familiar with some basics.
Having said that, what you want to do, flow or volume, is reasonably straightforward and ideally suited to an MCU.
Another hint, have a look at thermostat examples.
I don't think anyone is going to write the code for you, though. If you try a few things and they don't work, put your efforts here then you might get some more detailed help
here is my program, but it is not, done. but it is a start
Build on basis of Liquid flow rate sensor -DIYhacking.com Arvind Sanjeev
Measure the liquid/water flow rate using this code.
Connect Vcc and Gnd of sensor to arduino, and the
signal line to arduino digital pin 2 with a 10kOhm Resistor to 5V to get RS-Comp flow sensor to function
byte statusLed = 5;
const int relayPin = 7;
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 60;// This has to be changed when in final operation to adjust to correct flow of liquid.
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres = 0;
int relayState = 0;
unsigned long oldTime;
void setup()
{
// Initialize a serial connection for reporting values to the host. The measured flow will be displayed in the arduino Serial Monitor ( /Tools/Serial monitor )
Serial.begin(38400);
// 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);
pinMode(relayState, INPUT);
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, pulseCounter, FALLING);
}
//Main program loop
void loop()
{
// Detect input pulse from external to start flow measurement
// if(digitalRead(InputPin) == HIGH)
// {
// EnableFlow = 1;
// }
// Make flow measurement until triggered
// if (EnableFLow)
// {
// digitalWrite(statusLed, HIGH);
// ValveOpen();
// flow = MeasureFlow();
// if(flow > TriggerFlow)
// {
// ValveClose();
// Set Pin High ?
// digitalWrite(statusLed, LOW);
// EnableFlow = 0;
// Reset Flow Measurement
// flow = 0;
// }
// }
relayState = digitalRead(relayPin); // read state of PIN4
if (relayState == HIGH) // if button is not pressed run - This must be changed to HIGH in final operation
{
if ((totalMilliLitres < 50))// define amout on liquid to flow before switch off relay
{
if((millis() - oldTime) > 500) // Only process counters once per second //measureflow
{
// Disable the interrupt while calculating flow rate and sending the value to
// the host
detachInterrupt(sensorInterrupt);
// Because this loop may not complete in exactly 1 second intervals we calculate
// the number of milliseconds that have passed since the last execution and use
// that to scale the output. We also apply the calibrationFactor to scale the output
// based on the number of pulses per second per units of measure (litres/minute in
// this case) coming from the sensor.
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away. A fixed number amy be added to offset the missing flow data here.
oldTime = millis();
// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
flowMilliLitres = (flowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
unsigned int frac;
// All Print functions may be removed from final itteration to speed up operations, Just added for debugging purposes.
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(flowRate)); // Print the integer part of the variable
Serial.print("."); // Print the decimal point
// Determine the fractional part. The 10 multiplier gives us 1 decimal place.
frac = (flowRate - int(flowRate)) * 10;
Serial.print(frac, DEC) ; // Print the fractional part of the variable
Serial.print("L/min");
// Print the number of litres flowed in this second
Serial.print(" Current Liquid Flowing: "); // Output separator
Serial.print(flowMilliLitres);
Serial.print("mL/Sec");
// Print the cumulative total of litres flowed since starting
Serial.print(" Output Liquid Quantity: "); // Output separator
Serial.print(totalMilliLitres);
Serial.println("mL");
// 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);
}
}
else
{
digitalWrite(statusLed, LOW); //Power off to relay
totalMilliLitres = 0;
delay(3000);//wait 3 sec;
digitalWrite(statusLed, HIGH);//reset relay switch to run again
relayState = LOW; // setting the relay state low and resetting the code. This will have to be removed in final implementation
}
}
}
Interrupt Service Routine
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
Here is a very simple routine I use. If your information is accurate your meter is working the same way pulses/volume. Do a dimensional analysis. This bit of code is just edge detection with a time measurement between pulses. Please see "State Change Detection" in the Examples for further information. If you need faster you can use micros(), and/or interrupts as needed. As the previous reply noted you really don't need to.
/*
Flow meter for well monitoring. Meter is pulse per unit volume type.
Created 2019
A. J. Lindfors
*/
//set the pins
const byte inFlow = 2; // pin for the flow signal input
//integer variables for controls
int stateNew = LOW; //initialize
int stateOld = LOW; //initialize
int pulseTime;
//timing and calculation variables
unsigned long startTime, stopTime, pulseFlow;
float totalFlow, flowRate, timeInterval;
void setup() {
//set the pins
pinMode(inFlow, INPUT);
//serial set-up
Serial.begin(9600);
}
void loop() {
stateNew = digitalRead(inFlow);
if (stateNew != stateOld) {
if (stateNew == HIGH) {
pulseFlow++; //increment a counter for back checking
startTime = millis();
totalFlow = 0.10 + totalFlow; //varies by meter
timeInterval = startTime - stopTime;
flowRate = 1.667 / timeInterval; //varies by meter
// do any checks here
//output in CSV form
Serial.print(pulseFlow);
Serial.print(",");
Serial.print(totalFlow);
Serial.print(",");
Serial.print(flowRate);
Serial.print(",");
Serial.println(timeInterval);
}
stateOld = stateNew;
stopTime = startTime;
}
}