Water filling system code has problems

Hello everybody, at the moment im working on a project to fill up a tank with water (600 litres), the goal is to let it fill up and let the water flow stop once its full. I am using a water flow sensor and a valve (I named it ‘‘Procesklep’’). for this system I made a control box with a switch to turn on the overall power of the system and a reset button with a LED.

This is what is supposed to happen:
when the tank is totally empty
-Turn power switch on
-Valve opens so water can flow through

  • once the water reaches 600 litres (what is meassured by the flow sensor) the valve gets shut and LED turns on
    then if you would want to reset everything you can press the reset button.

OR

Water level in tank is already on 300 litres for example

  • turn power switch on
    -valve opens and water fills up the tank
  • water level reaches 600 litres and water flow goes slower since the tank is full
    -flow sensor sees the flow is lower and once it goes under for example 1L/m for 10 seconds or longer the valve also gets shut and the LED turns on.

but for some reason this happens:

Option 1:
-turn switch on, valve opens and water flows through
-water level reaches 600 litres, valve closes and the LED turns on for a split second (doesnt stay on like its supposed to do) then after 10 seconds the valve opens again (its supposed to stay shut until the reset button is pressed)

or option 2
-Turn switch on, valve opens, dont let water through to test the low flow
-after 10 seconds of low flow the valve shuts and led turns on for a split second (doesnt stay on like its supposed to do) then after 10 seconds the valve opens again (its supposed to stay shut until the reset button is pressed)

What am I doing wrong in my code, and how can let my LED stay on after it reached the water level or if the flow is too low?

thanks in advance

//Rior Filling System

byte sensorInterrupt = 0;
byte sensorPin       = 2;

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

volatile byte pulseCount;

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long totalLitres;
int timer1 = 0;

int procesklep = 4;
int resetknop = 7;

unsigned long oldTime;

void setup() {

  Serial.begin(9600);

  pinMode(procesklep, OUTPUT);
  digitalWrite(procesklep, LOW);
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  totalLitres       = 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);
}

void loop() {

  if ((millis() - oldTime) > 1000) {  // Only process counters once per second
    // 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 = ((300.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.
    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;

    // 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("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");
    Serial.print(totalMilliLitres);
    Serial.println("mL");
    Serial.print("\t");       // Print tab space
    Serial.print(totalMilliLitres / 1000);
    Serial.println("L");


    // 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);

    totalLitres = totalMilliLitres / 1000; //Transform total millilitres to total litres

    if (totalLitres >= 600) { //If the total litres is higher than the value of 600,
      //then the "procesklep" must be closed.
      digitalWrite(procesklep, HIGH);
    }

    if (int(flowRate) <= 1 && timer1 >= 10) { //If the Flow is lower than 1 L/m,
      digitalWrite(procesklep, HIGH);         //then the procesklep must be closed.
    }
    //To be able to reset the Flowrate "error" you must reset the entire system.

    if (timer1 >= 10) { //If the timer value is higher than 10,
      timer1 = 0;       //than the timer reset to 0.
    }

    timer1 ++;  //+1 added to Timer 1 value
  }

  if (resetknop == 1) { //Reset = Set every variable to 0
    pulseCount        = 0;
    flowRate          = 0.0;
    flowMilliLitres   = 0;
    totalMilliLitres  = 0;
    totalLitres       = 0;
    oldTime           = 0;
    timer1            = 0;
    digitalWrite(procesklep, LOW); //Reset "procesklep" (closed -> open)
  }

  delay(10); //Delay to make the program run slower
}

/*
  Insterrupt Service Routine
*/
void pulseCounter()

{
  // Increment the pulse counter
  pulseCount++;
}

Hi,
Why aren't you using float switches to tell you when the tank is full or empty?

Your method relies on the fact that at turn on of the project, you know how much water is in the tank.

Tom.... :slight_smile:

the company I work for doesnt want to build anything in the tank unfortunately and really want to use this flow sensor so thats basically why lol,

Your method relies on the fact that at turn on of the project, you know how much water is in the tank.

this is not really true, I gave 300 litres as an example, if the tank is empty the system basically already automatically uses the 600 litre cap, if there is already some water in the tank the system will just read the flow coming through the sensor (what it does at all times anyways) so when the tank becomes full the flow will decrease and result in giving a signal to the valve after 10 seconds of low flow.

the problem what im dealing with is just the valve opening again after about 10 seconds of being closed... and the LED not staying on after the valve shuts..

Are you getting correct data through the serial monitor?

Could you post a diagram of your wiring?

I don't really see how the valve could be opening after 10 seconds, since the only place that you set the output pin LOW is during setup, and during the final IF statement where you are comparing resetknop to 1, and since resetknop is initialized to 7 and never used anywhere else in the code that should never get executed.

You increment ‘timer1’ every second, and resets it when it goes beyond 10.

You have to change this

    if (int(flowRate) <= 1 && timer1 >= 10) { //If the Flow is lower than 1 L/m,
      digitalWrite(procesklep, HIGH);         //then the procesklep must be closed.
    }

to:

When ‘flowrate’ is below threshold…
Then, if ‘timer1’ is above 10, stop pump.
Increment ‘timer1’

if (resetknop == 1) { //Reset = Set every variable to 0

resetknop is set at 7 and never changes.

// 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.

You did not disable interrupts all together, although not relevant this is just not true.

how can let my LED stay on after it reached the water level or if the flow is too low?

what led ??

just tried to change it like you said but got an error, think I messed up the lines you wrote, how exactly do I need to type those lines if I may ask?

thanks in advance @leongjerland

sorry for the bad drawing lol, made this a few days ago just to remind myself how I connected the wires but now I need to use it here since I dont have other software available....

but this is how I got everything connected electricity wise, the flowsensor and valve are outside my controlbox

What are the specs on the relay? Impossible to tell from the drawing, but it seems unlikely it could be driven directly from an arduino output pin, since the built-in power supplies are both well above the voltage output of an arduino.

Are you certain it is taking exactly 10 seconds to turn the valve back on after it turns off? I'm thinking its more likely that the arduino is going into reset when you turn off the valve, and restarting the program because of that.

It is a Interface Relay - R600 Series

Coil Voltage 5V dc
Contact Configuration SPDT
Switching Current 6 A
Input Current 40mA
Turn Off Time 8ms
Turn On Time 5ms

and no im not certain about the 10 seconds time when it opens the valve again, that might be it?

Hi,

the 600 litre cap, if there is already some water in the tank the system will just read the flow coming through the sensor (what it does at all times anyways) so when the tank becomes full the flow will decrease and result in giving a signal to the valve after 10 seconds of low flow.

How are you putting water into the tank, a pump or gravity.
Why will the flow decrease as it becomes full?

Can you post a diagram of how your tank and the source of the water are connected?

Tom… :slight_smile:

its a big tank with a small hole in the top, once it reaches max it will leak out of the hole but water cant flow with the same speed into the tank anymore once its full, thats why it can be measured with the flowsensor. it will get filled by using a pump/tap

Imgur: The magic of the Internet

OMG that looks like something my niece drew. You don't have a simple drawing program like paint available ? I am with the 'Arduino is resetting' theory btw, you could use a transistor to drive the relay, but how about for now you just connect a led instead, just to exclude that as a possible cause.

Erik968:
[…] it will leak out of the hole [and that can be detected indirectly by the flow sensor]

This doesn’t seem like the best design choice to me, if you want to detect whether the tank is full or not.

if (int(flowRate) <= 1 && timer1 >= 10) { //If the Flow is lower than 1 L/m,
    digitalWrite(procesklep, HIGH);         //then the procesklep must be closed.
}
//To be able to reset the Flowrate "error" you must reset the entire system.

if (timer1 >= 10) { //If the timer value is higher than 10,
	timer1 = 0;       //than the timer reset to 0.
}
		
timer1 ++;  //+1 added to Timer 1 value

When you close the valve the flow is zero. After 10 seconds the first condition becomes true again (flow is lower than 1 and timer1 is greater or equals 10).

hahaha well no im on the go atm, thats why I used that ''drawing'' that I already had.. im sorry about that :cold_sweat:

and yes, I also do think its the Arduino that is resetting itself.. will look at it later and let you guys know what I found out. @Deva_Rishi

So, you determine that the tank is full when it overflows on the floor? What material is the tank made of? There ARE sensors that can sense water level through the wall of certain tank materials.

outsider:
So, you determine that the tank is full when it overflows on the floor? What material is the tank made of? There ARE sensors that can sense water level through the wall of certain tank materials.

Yeah actually why don't you put the flow meter at the other end ?

Hi,
What the???
N7xQgwU.png

How are you controlling the relay with the UNO and 24V and 12V?
Can you post a picture of your project please?

https://docs-apac.rs-online.com/webdocs/0d66/0900766b80d66759.pdf

Can you please post a copy of your circuit as a picture of a hand drawn circuit in jpg, png?

The 12V and 24V supplies do not have their gnds connected so controlling the relay looks very puzzling.
How does the valve get its current from the 24V supply?

Tom… :slight_smile: