Automatic change of liquid, at selected day and time

Hi all, I have a problem with my code, I am building an auto replacement system in the tank, for this I have two relays, each connected to the pump of the system.

My code, however, does not work properly because I do not know how to stop the change and exit the main program, the execution is at the last step, im first time in this forum and i dont know how to put code with tags, the program stop at last step and i dont know how to quit from function :confused:

char DOW[][4]={"SUN","MON","TUE","WED","THU","FRI","SAT"};


DateTime now = RTC.now();

  lcd.init(); 
  lcd.backlight();
  lcd.setCursor(0,0);
  p2d(now.hour());
  lcd.print(":");
  p2d(now.minute());
  lcd.print(":");
  p2d(now.second());
  lcd.setCursor(0,1);
  lcd.print("Data: ");
  lcd.print(now.day());
  lcd.print("/");
  lcd.print(monthName[now.month()-1]);
  lcd.print("/");
  lcd.print(now.year());

  int startTime = now.minute();

  delay(500);


if(DOW[0][4] = "SUN" and startTime == 40 ){


//start 

if (startLiqid){ 

  if (min > distance()) { 

    digitalWrite(p1, LOW); start pump one

  } else {

    startLiqid = false;

  }

} else {

  if (max < distance()) { 

    digitalWrite(p1, HIGH);
    digitalWrite(p2, LOW);

  } else { 
    

       if(distance() <7){
        digitalWrite(p1, HIGH);
        digitalWrite(p2, HIGH);
        
       //program stop in this moment how to quit to main program

    }
  }

}




//end

  
 
  } else {
    
  //some kode
    
  }
if(DOW[0][4] = "SUN" and startTime == 40 ){

The DOW array does NOT have an element at [ 0 ][4].

The element at DOW[0] is a string. You do NOT compare strings using ==.

i dont know how to put code with tags

Read the damned stickies at the top of the forum. There is NOTHING hard about:

  1. Copy the code
  2. Press the </> icon
  3. Paste the code.

Thanks for the answer, I also thought the problem was some conditions before, but the same code uploaded to the Arduino stops in the same place without going to the main section, or something I do not understand :(, I wanted a simple algorithm to pump 15cm of fluid once you pump out the oil Run the second pump until the sensor shows 5cm. When finished exit I am weak in programming :frowning:

if (startLiqid){ 

  if (min > distance()) { 

    digitalWrite(p1, LOW); //start pump one

  } else {

    startLiqid = false;

  }

} else {

  if (max < distance()) { 

    digitalWrite(p1, HIGH); //off pump one
    digitalWrite(p2, LOW); //start pump two

  } else { 
    

       if(distance() <7){
        digitalWrite(p1, HIGH); //turn off all pump
        digitalWrite(p2, HIGH);
        
       //program stop in this moment how to quit to main program

    }
  }

}

What tank? Fish tank? Gas tank? Only you can see the equipment in front of you.

Can you post a complete program with setup() and loop() which shows the problem? Describe exactly what it does and exactly what you want it to do.

What is distance()? Who is max? It looks like you might have an ultrasonic distance sensor to measure the level in one of your tanks but that's just guessing.

//program stop in this moment how to quit to main program

No, it doesn't stop. You don't have any code there which makes anything stop. However it's quite possible that you've got your logic wrong - you turned off the pumps when the top of the waves in the tank measured 7 although the tank is not yet filled to 7. When the waves settle the rest of the code (which you didn't show) waits forever.

The tank is a aquarium without fish.

So you’re right my logic does not work :frowning:

Algorithm:

  1. Every Saturday at 19 o’clock, the liquid change function is activated.
  2. Switch on the pump 1 and measure the distance to 30 cm.
  3. When the distance reaches 30 cm, the pump 1 is switched off, and the second pump is switched on, the liquid is replenished.
  4. When the measurement shows 7 cm, the second pump is to turn off.
    5 End of replacement liquid out to main program.

And the algoritm almost works but irly dont know what i do wrong

The all code i have

main

#include <Wire.h>
#include "RTClib.h"
#include <OneWire.h>
#include <DS18B20.h>
RTC_DS1307 RTC;

#include <LiquidCrystal_I2C.h> // Dołączenie biblioteki do obsługi LCD
 LiquidCrystal_I2C lcd(0x3F, 16, 2); // Konfiguracja portu LCD 0x3F, ilość znaków w jednej linii 16, ilość linii 2 

#define trigPin 6
#define echoPin 7
#define p1 2 
#define p2 3 
#define p3 4 
#define p4 5 

int max = 15; 
int min = 30; 

const char *monthName[12] = {"Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paz", "Lis", "Gru"};

// the pin 8 temperature sensor
#define ONEWIRE_PIN 8

byte address[8] = {0x28, 0xFF, 0xD8, 0x96, 0xB4, 0x16, 0x03, 0x46};
OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);


void setup()
{
  pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
  pinMode(echoPin, INPUT); //a echo, jako wejście

  pinMode(p1, OUTPUT);
  pinMode(p2, OUTPUT);
  pinMode(p3, OUTPUT);
  pinMode(p4, OUTPUT);
  digitalWrite(p1, HIGH);
  digitalWrite(p2, HIGH);
  digitalWrite(p3, HIGH);
  digitalWrite(p4, HIGH);



//time
    Wire.begin();
    RTC.begin();;
    RTC.adjust(DateTime(__DATE__, __TIME__));
//timne

//temperature
  sensors.begin();
  sensors.request(address);
//temperature

}

void loop()
{

timeRTC();

showTemperature();


 
} 


//ultrasonic sensor 

int distance() {
  long czas, dystans;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  czas = pulseIn(echoPin, HIGH);
  dystans = czas / 58;
  return dystans;
}
 
//add 0 to time
void p2d(int number) {
  if (number >= 0 && number < 10) {
    lcd.write('0');
  }
  lcd.print(number);
}

Luiqid Repl code

int startLiq = 1;
void liquidReplenishment()
{
  
      lcd.init(); 
      lcd.backlight();
      lcd.setCursor(0, 0); 
      lcd.print("Liquid");
      lcd.setCursor(0, 1);      
      lcd.print("Replenishment"); 
      delay(2000);

if (startLiq){ 
  
  if (15 > distance()) { // start pump one

    digitalWrite(p1, LOW);
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
      
      lcd.setCursor(0, 0); 
      lcd.print("Pump one work");
      lcd.setCursor(0, 1);    
      lcd.print(distance()); 
      lcd.println(" cm             ");
      delay(2000);

  } else { 

    startLiq = false;
    
  }
 
} else {
 
  if (30 < distance()) {
    
    digitalWrite(p1, HIGH); 
    digitalWrite(p2, LOW); 

    
     
      lcd.setCursor(0, 0); 
      lcd.print("Pump two work");
      lcd.setCursor(0, 1);     
      lcd.print(distance()); 
      lcd.println(" cm             ");
      delay(2000); 
    
  } else {
    
        if(distance() <7){     

            digitalWrite(p1, HIGH);
            digitalWrite(p2, HIGH); 

            lcd.setCursor(0, 0);
            lcd.print("Finished");
            lcd.setCursor(0, 1);     
            lcd.print(distance()); 
            lcd.println(" cm             ");
            delay(2000); 

            startLiq = false;
             
        
    }
    
  }
  
}



}

Time finction code

void timeRTC() {
  char DOW[][4]={"SUN","MON","TUE","WED","THU","FRI","SAT"};


DateTime now = RTC.now();

  lcd.init(); 
  lcd.backlight();
  lcd.setCursor(0,0);

  lcd.print("Time:");
  p2d(now.hour());
  lcd.print(":");
  p2d(now.minute());
  lcd.print(":");
  p2d(now.second());
  lcd.setCursor(0,1);
  lcd.print("Data: ");
  lcd.print(now.day());
  lcd.print("/");
  lcd.print(monthName[now.month()-1]);
  lcd.print("/");
  lcd.print(now.year());
  
  int czasS = now.hour();
  int startLiq = 1;
  delay(500);


if(czasS = 22){

liquidReplenishment();

  } else {
    
if (czasS == 10){
  digitalWrite(p3, LOW);
  } 
if(czasS == 17){
  digitalWrite(p3, HIGH);
  }
  
if (czasS == 12){
  digitalWrite(p4, LOW);
  } 
if(czasS == 13){
  digitalWrite(p4, HIGH);
  }
    
  }
}

Temperature code

void showTemperature(){
  
    if (sensors.available())
  {
    float temperature = sensors.readTemperature(address);
    lcd.clear();
    lcd.init();   
    lcd.backlight();
    lcd.setCursor(0,0);
    lcd.print("Water temperature");
    lcd.setCursor(0,1);
    lcd.print(temperature); 
    lcd.print(char(223)); 
    lcd.print(F ("C")); 
    sensors.request(address);
    delay(5000);
    
  }

  }

tabs.jpg

The distance() function return type is int. Why are you actually returning a long?

//add 0 to time

That is NOT what that code does.

The code, as posted makes no sense. With that little code, it all belongs in ONE file. I can't piece together the stuff you posted. Functions are not logically grouped. Variables appear in one code box, but are not defined there, or in the main file. Way too hard to follow.

“The distance() function return type is int. Why are you actually returning a long?”

This function return “cm” from ultrasonic sensor, and i can print this on LCD some like this 15cm, 13cm

"That is NOT what that code does.

Code: [Select]
//add 0 to time"

This code add 0 to time before get 10 some like this 22.05.23 if i dont use this i get on lcd 22.5.23

“The code, as posted makes no sense. With that little code, it all belongs in ONE file. I can’t piece together the stuff you posted. Functions are not logically grouped. Variables appear in one code box, but are not defined there, or in the main file. Way too hard to follow.”

I know the code is in the haze, but I have a problem with the program is in one place, the rest works.

I wrote a program with only this one action.

#include <Wire.h>

#include <OneWire.h>



#include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x3F, 16, 2);



#define trigPin 6
#define echoPin 7
#define p1 2 
#define p2 3 



int startLiq = 1;



void setup() {
  
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  pinMode(p1, OUTPUT);
  pinMode(p2, OUTPUT);
  
  lcd.init(); 
  lcd.backlight();

}

void loop() {

 
if (startLiq){ 

  if (30 > distance()) { // turn on pump one

    digitalWrite(p1, LOW);
    digitalWrite(p2, HIGH);
    lcd.setCursor(0, 0); 
    lcd.print("Pump one work");
    lcd.setCursor(0, 1);    
    lcd.print(distance()); 
    lcd.println(" cm             ");
    delay(2000);
    
  } else { 
    
    startLiq = false;
    
  }

} else {

  if (15 < distance()) { //tunr off pump one, turn on pump two 

    digitalWrite(p1, HIGH);
    digitalWrite(p2, LOW);
    lcd.setCursor(0, 0); 
    lcd.print("Pump two work");
    lcd.setCursor(0, 1);    
    lcd.print(distance()); 
    lcd.println(" cm             ");
    delay(2000);

  } else { 
    
       if(distance() <7){ //turn off all pump
        
      digitalWrite(p1, HIGH);
      digitalWrite(p2, HIGH);
      lcd.setCursor(0, 0); 
      lcd.print("Finish");
      lcd.setCursor(0, 1);    
      lcd.print(distance()); 
      lcd.println(" cm             ");
      delay(2000);
      startLiq = false;
    }
  }

}

//end function




}



int distance() {
  long czas, dystans;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  czas = pulseIn(echoPin, HIGH);
  dystans = czas / 58;
  return dystans; // return distance in "cm"
}

Geniose:
I wrote a program with only this one action.

Does it do the action you intended?

If i look at my algoritm

  1. If the liquid change function is activated. (every saturday at 19)
  2. Switch on the pump 1 and measure the distance to 30 cm.
  3. When the distance reaches 30 cm, the pump 1 is switched off, and the second pump is switched on, the liquid is replenished.
  4. When the measurement shows 7 cm, the second pump is to turn off.
    5 End of replacement liquid out to main program.

ALmost work but i dont have a 5 step.

The program stop in this moment

 if (15 < distance()) { //tunr off pump one, turn on pump two 

    digitalWrite(p1, HIGH);
    digitalWrite(p2, LOW);
    lcd.setCursor(0, 0); 
    lcd.print("Pump two work");
    lcd.setCursor(0, 1);    
    lcd.print(distance()); 
    lcd.println(" cm             ");
    delay(2000);

  } else { 
    
       if(distance() <7){ //turn off all pump
        
      digitalWrite(p1, HIGH);
      digitalWrite(p2, HIGH);
      lcd.setCursor(0, 0); 
      lcd.print("Finish");
      lcd.setCursor(0, 1);    
      lcd.print(distance()); 
      lcd.println(" cm             ");
      delay(2000);
      startLiq = false;
    }
  }

The status is that my LCD has Finish 6cm. However, when I pick up the distance sensor again at 30 cm starts pumping the second pump. And I would like to after finishing the last condition the prgram ended this action and wait again 7 days. I have tried in the last if give return; but that does not help. Somehwre in code i must give signal but how :slight_smile:

OK, try this...

void loop() {
  Serial.println(distance());
}

Look at what you get on the Serial Monitor. Move the sensor until you are close to 7. Notice that it flickers back and forth between 6 and 7? Your code is executing that algorithm but the input values are not stable. If it gets one single reading of 7, then it stops the pumps, even if the very next reading is 6.

This is probably OK. You're really seeing a level of 6.99cm but the integer conversion is truncating this to 6.

Your code hasn't stopped. You just never told it to put anything different on the screen after it put "Finished". As you noticed, it will still respond to changes on the sensor, so you know it hasn't stopped.

What else is this thing going to do? If it has no other jobs to do after filling the tank, I would just put in a long delay, like delay(60000); and then make it write something else to the screen like "waiting for next week." Note that your simple time formulas will make this try to refill the tank ALL THE TIME during that special minute once per week. But adding a minute delay means that it gets out of that minute without re-starting the cycle. [The correct way is to determine when you've just switched into the special minute and then set a value to say "refill requested" which gets turned off after the fill and doesn't get set back to "request" while you are still inside the minute. Adding seconds to the calculation doesn't help because a second is a very long time for an Arduino.]

Why don't you start by drawing a small state machine that describes

State of your system
What important event can happen in such a state that needs to trigger some action
What state the system ends up after that has been triggered

For example you start in the WAITING state. The only meaningful event (according to your explanations) is "is it Saturday 7pm?"

So write a function boolean isItTimeForOilChange() that returns true if this is the right time and false if not

When you are in the WAITING state your loop needs to only call isItTimeForOilChange() until it's true.

At that time an action needs to happen: you turn on pump #1 (write a function cleaningPumpON())and then you have a new state EVACUATING

In the EVACUATING state the only meaningful event is "is my level low enough"? So write a function boolean isMyLevelLowEnough() retuning true if it's the case

So when you are in the EVACUATING state the only thing your loop needs to do is call isMyLevelLowEnough() until it's true (I would also recommend a timeout). When the call returns true the action is Stop the pump #1 and activate pump #2 and you are in a new state FILLINGUP (write two functions to stop pump1 and start pump2 cleaningPumpOFF() and fillingPumpON()

In the FILLINGUP state the only thing you care about is "is my tank full" so write a function boolean isMyTankFull() that returns true if the tank is full and false otherwise. Then the only thing that your loop does is call that function until it's true. When it's true you stop pump #2 (write a function fillingPumpOFF()) and go back to WAITING state

So the loop looks very simple - something like

void loop()
{
    switch (state) {

       case WAITING:
           if (isItTimeForOilChange()) {
              cleaningPumpON();
              state = EVACUATING;
           }
       break;

       case EVACUATING:
          if (isMyLevelLowEnough()) {
             cleaningPumpOFF();
             fillingPumpON();
             state = FILLINGUP;
          }
       break;

        case FILLINGUP:
            // you get the idea I let you fill that in
        break;
   }
}

See by breaking up your challenge in smaller chunks it's easier to focus on getting one thing done and then you put it all together

Go ahead write all the utility functions read a bit about enum to define the states and complete the setup and the loop and you'll be in business (you will need to implement edge cases - what if sensors do not work, what if there is a power outage on the arduino and not the pump, etc)