why can't the relay stays on and not turn OFF!!!

hi yall,

So this is my first time doing an arduino project and i'm still a newbie...
So my project is to control the usage of water.

the flow of my project:

WATER SENSOR>>WATER VALVE WITH RELAY -ON->>WATER FLOW SENSOR>>LCD( SHOW A METER OF HOW MUCH WATER HAS FLOWED OUT)>>if over the limit>> PIEZO -ON->> LED -ON->>WATER VALVE WITH RELAY -OFF->>if wanna let water flow more >>PRESS PUSH BUTTON>>WATER VALVE WITH RELAY -ON->>can use an app to turn off /ON the water VALVE (MIT APP)

the problem i have while doing this is that the 5v relay keeps on turning on and off !!!!!!!!!!!!

/* A0 = water flow sensor
 * D2-D8 = lcd
 * D9 =water sensor
 * D10 = piezo
 * D11= 5V relay for water solenoid valve
 * D13= push button
 * A1 & A2 = bluetooth module
 */
#include <LiquidCrystal.h>             //
LiquidCrystal lcd (7, 8, 5, 4, 3, 2);
int X;
int Y;
float TIME = 0;
float FREQUENCY = 0;                       //LCD FOR WATER FLOW SENSOR @ WATER METER
float WATER = 0;  
float TOTAL = 0;
float LS = 0;
const int input = A0;
int Contrast=50;                         //

#define Grove_Water_Sensor A5    //WATER SENSOR 

const int RELAY_ENABLE = 12;      //RELAY (WATER VALVE)

const int inPin=13;           //PUSHBUTTONS
int currentState = LOW;
int previousState = LOW;
int outState = LOW;        //

#include <SoftwareSerial.h>             //BLUETOOTH MODULE
SoftwareSerial Bluetooth(A1,A2);
String message;                       //

void setup()
{
   Serial.begin(9600);
   pinMode(Grove_Water_Sensor, INPUT);      //WATER SENSOR
    
   pinMode(RELAY_ENABLE, OUTPUT);         //RELAY
   
   pinMode(inPin, INPUT);                //PUSH BUTTON
   pinMode(A3,OUTPUT);
   pinMode(A4,OUTPUT);
   pinMode (9, OUTPUT);
   
   Bluetooth.begin(9600);              //BLUETOOTH MODULE
   
  {                                       //
    analogWrite(6,Contrast);
    lcd.begin(16,2);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print ("Water Flow Meter");        //LCD FOR WATER FLOW SENSOR (WATER FLOW SENSOR WILL 
    lcd.setCursor(0, 1);                    //SHOW UP WHEN ELECTRIC SUPPLY IS CONNECTED TO IT
    lcd.print ("****************");
    delay(2000);
  }                                        //
}

void loop() 
{
   
     if( digitalRead(Grove_Water_Sensor) == LOW) 
      { 
       { Serial.println("Relay ON");
       digitalWrite(RELAY_ENABLE, LOW);
       delay(3000);}
       {
         X = pulseIn(input, HIGH);
         Y = pulseIn (input, LOW);
         TIME = X + Y;
         FREQUENCY = 1000000/TIME;
         WATER = FREQUENCY/7.F;
         LS = WATER/60;
         if(FREQUENCY >= 0) 
         
        
           if(isinf(FREQUENCY))
                {
                     lcd.clear();
                     lcd.setCursor(0,0);
                     lcd.print("****************");
                     lcd.setCursor(0,1);
                     lcd.print("TOTAL:");
                     lcd.print( TOTAL);
                     lcd.print(" L");
                }
         
        else
         {
           TOTAL = TOTAL + LS;
           Serial.println(FREQUENCY);
           lcd.clear();
           lcd.setCursor(0,0);
           lcd.print("****************");
           lcd.setCursor(0,1);
           lcd.print("TOTAL:");
           lcd.print( TOTAL);
           lcd.print(" L");
         }
           
             
         else if (lcd.print ("1.00 L"))
               {tone (10,494,250);
               delay(2000);
               delay(10);
               digitalWrite(9, HIGH);
               digitalWrite (A3, LOW);
               digitalWrite (A4, LOW);
               Serial.println("Relay ON");
               digitalWrite(RELAY_ENABLE, LOW);
              delay(3000);}
               
               else if (lcd.print ("2.00 L"))
              { tone (10,494,250);
               delay(2000);
               tone (10,494,250);
               delay(2000);
               digitalWrite(9, LOW);
               digitalWrite (A3, HIGH);
               digitalWrite (A4, LOW); 
               Serial.println("Relay ON");
               digitalWrite(RELAY_ENABLE, LOW);
                delay(3000);}
               
               else if (lcd.print ("3.00 L"))
               {tone (10,494,250);
               delay(2000);
               tone (10,494,250);
               delay(2000);
               tone (10,494,250);
               delay(2000);
               Serial.println("Relay OFF");
               digitalWrite(RELAY_ENABLE, HIGH);
               digitalWrite(9, LOW);
               digitalWrite (A3, LOW);
               digitalWrite (A4, HIGH);
               delay(1000);}
            else
              {Serial.println("Relay ON");
               digitalWrite(RELAY_ENABLE, LOW);
               digitalWrite(9, LOW);
               digitalWrite (A3, LOW);
               digitalWrite (A4, LOW);
               delay(1000);}
           
      
           }
      
  

   {
  currentState = digitalRead(inPin);
  if ((currentState == HIGH) && (previousState == LOW));
  {
    if (outState == LOW)
    {outState = HIGH;
     {
     Serial.println("Relay ON");
     digitalWrite(RELAY_ENABLE, LOW);
     
     if (lcd.print ("4.00 L"));
     {Serial.println("Relay OFF");
     digitalWrite(RELAY_ENABLE, HIGH);
     digitalWrite(9, HIGH);
     digitalWrite (A3, HIGH);
     digitalWrite (A4, HIGH);
     }}}
    else
    {outState = LOW;}}
  
  previousState = currentState;
  digitalWrite (RELAY_ENABLE, outState);
  delay(10);
} }
 else //if no water in contact with water sensor
  {
       Serial.println("Relay OFF");
       digitalWrite(RELAY_ENABLE, HIGH);
     digitalWrite(9, HIGH);
     digitalWrite (A3, HIGH);
     digitalWrite (A4, HIGH);
  }
  delay(2000);

 {
  while (Bluetooth.available() > 0)
  {
    delay(10);
    char c = Bluetooth.read();
    message += c;
  }
  if (message.length() >0)
  { Serial.println (message);
  if (message=="ON")
  { Serial.println("Relay ON");
    digitalWrite(RELAY_ENABLE, LOW);}
  if (message=="OFF")
  { Serial.println("Relay OFF");
     digitalWrite(RELAY_ENABLE, HIGH);}
  }
  message = "";
}
}

You've got a few of these:

            if (lcd.print ("4.00 L"));
            {
              Serial.println("Relay OFF");
              digitalWrite(RELAY_ENABLE, HIGH);
              digitalWrite(9, HIGH);
              digitalWrite (A3, HIGH);
              digitalWrite (A4, HIGH);
            }

I don't know what you're trying to do but lcd.print("4.00 L") always returns TRUE so the if(lcd.print("4.00 L")) block will always run.

As a beginner - lose the delay() calls as soon as you can, and learn about millis() timing.
String (capital S) will also cause you grief with RAM & crashes as you become more experienced.

I didn't look too closely, but I doubt you need all those floats - they just eat RAM and CPU cycles if you don't need them. And can introduce roundign errors that will confuse you.

The multiple sequential LCD.prints on the same row could be achieced by a single LCD.print... on the same row, rather than multiple calls...

The simple errors I see in there were made by somone who should get smaller code right before trying things like this.

         if(FREQUENCY >= 0)
         
       
           if(isinf(FREQUENCY))
                {

When you forget braces... you need to take a few steps back.
I can tell that the 1st if() there won't do anything and you can put braces in but you will be going through motions and still lost.

Did you make a working project that just reads the sensor? That would be a nice start to build on, something that works. Also maybe get familiar with the Autoformat Tool (ctrl-t).

So what actually do i need to do..........
I'm so confuse right now tho :o

lastchancename:
As a beginner - lose the delay() calls as soon as you can, and learn about millis() timing.
String (capital S) will also cause you grief with RAM & crashes as you become more experienced.

I didn't look too closely, but I doubt you need all those floats - they just eat RAM and CPU cycles if you don't need them. And can introduce roundign errors that will confuse you.

The multiple sequential LCD.prints on the same row could be achieced by a single LCD.print... on the same row, rather than multiple calls...

Personally - I couldn't make sense of the code - but tried to tidy it up a bit while trying...

Here's your otriginal code (almost) with a bit of structure, tidying up and comments to help you see why I did soe things...

(( Sorry - but my editor tabs expanded into the web page oddly ))

/* A0 = water flow sensor
 * D2-D8 = lcd
 * D9 =water sensor
 * D10 = piezo
 * D11= 5V relay for water solenoid valve
 * D13= push button
 * A1 & A2 = bluetooth module
 */
 
// ############## KEEP CONSTANTS & DEFINITIONS UP HERE ##########
#define LCD_CONTRAST 6
#define RELAY_ENABLE 12 //RELAY (WATER VALVE)
#define BUTTON_PIN 13   //PUSHBUTTONS
#define PULSE_INPUT A0
#define SENSOR_PIN A5   //WATER SENSOR 

// ################ KEEP LIBRARY #INCLUDES TOGETHER ##############
#include <SoftwareSerial.h>             //BLUETOOTH MODULE
#include <LiquidCrystal.h>             //

/* *************************************************************
the preference of using 'const' vs '#define' is historical & personal
There are reasons for both - go with your choce but *stay consistent*...!
************************************************************* */

// ############## KEEP CONSTANTS & DEFINITIONS UP HERE ##########

// without knowing what values are expected - it's hard to say if floats
// are the best choice here - possibly uses up RAM and CPU performance for no good reason
float TIME = 0;
float FREQUENCY = 0; //LCD FOR WATER FLOW SENSOR @ WATER METER
float WATER = 0;  
float TOTAL = 0;
float LS = 0;

// ############### KEEP VARIABLE DECLARATIONS UP HERE ###########
int Contrast=50;
int currentState = LOW;
int previousState = LOW;
int outState = LOW;
int X, Y;

// ################## INSTANTIATE YOUR CLASSES HERE ##############
LiquidCrystal lcd (7, 8, 5, 4, 3, 2);
SoftwareSerial Bluetooth(A1,A2);

// (S)trings are easy to use, but very unsuitable for small microprocessors
// without an operating system to clean up memory rragmentation
String message;                       //

// =================================================
void setup()
{
 Serial.begin(9600);
 Bluetooth.begin(9600);            //BLUETOOTH MODULE

 /// see how these pins are self-documenting
 //  the // comments aren't really necessary !
 pinMode(SENSOR_PIN, INPUT);      //WATER SENSOR
 pinMode(RELAY_ENABLE, OUTPUT);   //RELAY
 pinMode(BUTTON_PIN, INPUT);      //PUSH BUTTON

 // OOPS !  ???? why no pin names ???? 
 // you started so well above !
 pinMode(A3,OUTPUT);
 pinMode(A4,OUTPUT);
 pinMode (9, OUTPUT);

 analogWrite(LCD_CONTRAST, Contrast);
}

// =================================================
void loop() 
{
 if( digitalRead(SENSOR_PIN) == LOW) 
 { 
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);
 delay(3000);}

 // need to know more about this to choose float or other types
 X = pulseIn(INPUT_PIN, HIGH);
 Y = pulseIn (INPUT_PIN, LOW);
 TIME = X + Y;
 FREQUENCY = 1000000/TIME;
 WATER = FREQUENCY/7.F;
 LS = WATER/60;
 
 // -------------------------
 if(FREQUENCY >= 0) 
 {
 if(isinf(FREQUENCY)) // ### Test if FREQUENCY is an infinite value! /  Why here ? ##
 {
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("****************");
 lcd.setCursor(0,1);
 lcd.print("TOTAL:");
 lcd.print( TOTAL);
 lcd.print(" L");
 }
 else
 {
 // -------------------------
 TOTAL = TOTAL + LS;
 Serial.println(FREQUENCY);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("****************");
 lcd.setCursor(0,1);
 lcd.print("TOTAL:");
 lcd.print( TOTAL);
 lcd.print(" L");
 }
 else if (lcd.print ("1.00 L")) // ### these make no sense at all ##
 {
 // -------------------------
 tone (10,494,250);
 delay(2000);
 delay(10);
 digitalWrite(9, HIGH);
 digitalWrite (A3, LOW);
 digitalWrite (A4, LOW);
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);
 delay(3000);
 }
 else if (lcd.print ("2.00 L")) // ### these make no sense at all ##
 {
 // -------------------------
 tone (10,494,250);
 delay(2000);
 tone (10,494,250);
 delay(2000);
 digitalWrite(9, LOW);
 digitalWrite (A3, HIGH);
 digitalWrite (A4, LOW); 
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);
 delay(3000);
 }
 else if (lcd.print ("3.00 L")) // ### these make no sense at all ##
 {
 // -------------------------
 tone (10,494,250);
 delay(2000);
 tone (10,494,250);
 delay(2000);
 tone (10,494,250);
 delay(2000);
 Serial.println("Relay OFF");
 digitalWrite(RELAY_ENABLE, HIGH);
 digitalWrite(9, LOW);
 digitalWrite (A3, LOW);
 digitalWrite (A4, HIGH);
 delay(1000);
 }
 else
 {
 // -------------------------
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);
 digitalWrite(9, LOW);
 digitalWrite (A3, LOW);
 digitalWrite (A4, LOW);
 delay(1000);
 }
 }

 // ???  I'm lost after here !
 {
 currentState = digitalRead(BUTTON_PIN);
 if ((currentState == HIGH) && (previousState == LOW));
 {
 if (outState == LOW)
 {
 outState = HIGH;
 {
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);

 if (lcd.print ("4.00 L")); // does absolutely nothing
 {
 Serial.println("Relay OFF");
 digitalWrite(RELAY_ENABLE, HIGH);
 digitalWrite(9, HIGH);
 digitalWrite (A3, HIGH);
 digitalWrite (A4, HIGH);
 }
 }
 }
 else
 {
 outState = LOW;
 }
 }
 previousState = currentState;
 digitalWrite (RELAY_ENABLE, outState);
 delay(10);
 }
 else //if no water in contact with water sensor
 {
 Serial.println("Relay OFF");
 digitalWrite(RELAY_ENABLE, HIGH);
 digitalWrite(9, HIGH);
 digitalWrite (A3, HIGH);
 digitalWrite (A4, HIGH);
 }
 delay(2000);
 { // for some reason to encapsulate this block of code ??
 while (Bluetooth.available() > 0)
 {
 delay(10);
 char c = Bluetooth.read();
 message += c;
 }
 if (message.length() >0)
 {
 Serial.println (message);
 if (message=="ON")
 {
 Serial.println("Relay ON");
 digitalWrite(RELAY_ENABLE, LOW);
 }
 if (message=="OFF")
 {
 Serial.println("Relay OFF");
 digitalWrite(RELAY_ENABLE, HIGH);
 }
 }
 message = "";
 }
}

Your logic and indentation was a mess and needs to be fixed at the same time so the code & flow becomes readable. (Sorry)

Again - a personal choice of mine is to open curly braces on the same line as the if / while, which makes the code more compact to scroll, and more obvious (to me!)
e.g.

if (message.length() > 0) {
  Serial.println (message);
  if (message=="ON")  {
    Serial.println("Relay ON");
    digitalWrite(RELAY_ENABLE, LOW);
  }
  if (message=="OFF")  {
    Serial.println("Relay OFF");
    digitalWrite(RELAY_ENABLE, HIGH);
  }
}

Something like this makes me ask...

lcd.setCursor(0,1);
lcd.print("TOTAL:");
lcd.print( TOTAL);    <-- note no opening "quotes" ??!
lcd.print(" L");

Why not...

lcd.setCursor(0,1);
lcd.print("TOTAL: TOTAL L");

Once your code compiles and 'almost' does what you want - we'll come back to eliminating the delays and other sins..!

Good luck.
Read about delay() vs millis() timing, Strings vs c-strings, and choose a code style hat works for you.
Cut & paste rarely works when developing original code.

float TOTAL = 0;

...... snip

lcd.setCursor(0,1);
lcd.print("TOTAL:");
lcd.print( TOTAL);    <-- note no opening "quotes" ??!
lcd.print(" L");

Why should a defined variable name need opening quotes?

My bad....
The original structure was so poor, without reading too much - I thought he was setting up a headline for the values below.

I’ll apologise profusely, and hope the gods won’t view my transgression too harshly.

lastchancename:
My bad....
The original structure was so poor, without reading too much - I thought he was setting up a headline for the values below.

I’ll apologise profusely, and hope the gods won’t view my transgression too harshly.

I agree about the mess but do you remember a time when you might have fixed what wasn't broken?

Hi,
Welcome to the forum.

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

Have you written your code in stages?
That is, do you have some code that;
Just reads the sensor and works?
Just writes to the LCD and works?
Just turns the piezo ON and OFF and works?
Just turns the relay ON and OFF and works?
Just passes commands via the Bluetooth and works?
BEFORE you combine each piece of code one at a time, getting each addition to work before adding the next?

I know it sounds long and laborious, but you will end up with better code, and a better understanding of how your code works.

Thanks.. Tom... :slight_smile:

I started a thread - about developing a fairly complex project that uses multiple devices, multiple nodes, radio communications, LCD - displays etc etc

While it may be more than you're planning - I believe it has some tips on ways to approach a project that is new and/or difficult. Ive certainly been doing new things with new devices in there.

Developing a complex project

It's been a work in progress for about three weeks since I started - and has probably another two weeks as the pieces come together. (And I have to use it in earnest in about three weeks !)

I decided to document the effort - for people exacrtly like the OP.
Most worthwhile projects don't come together in a single afternoon without serious plannng.
Having said that - as it comes together, I'm finessing parts of the design as I move through the prototyping. Change the comms protocol, needing more pins (!) etc, although I have to admit being pleased te solution has comne together pretty smoothly - maybe because I PLANNED IT beforehand !