Timing relays and sensors

Hello everybody ,
first off all i will explain to you parts of my project. I have Arduino Mega2560+ lcd shield with buttons (on this ard+shield i have lcd menu so this may be one of problems which cause problem i am asking for help), 2x DHT11 ,real time module,relays, NodeMCU.

My problem now is timing realys. When you look in code in "if" you will see 2 variables "pozad_vlh" and "trt"..... "pozad_vlh" is required humidity and "trt" is value of humidity from sensor. Inside IF it should turn on relay for 1 sec and then turn off for 2 seconds, but it stopped at turn on and dont turn off. I know it's doing it like it should but i need turn it on for 2 seconds let's say and then turn it off for 15 min for example. Afther this 15 minutes program again run this "IF" and compare this two variables. But there may cause problem this two DHT11 sensors which i use with delay(2000), and delay in menu, for buttons and lcd screen. In code i post you may see that i put value 50 into "trt". It's for simulating sensor value, then you can see in IF that i wanted simulate change of this value after turning on relays.

If is needed more from my code only say.

Thank you for your help and sorry for my english. :slight_smile:

int pozad_vlh;
int trt=50 ;

class Flasher
{
  // Class Member Variables
  // These are initialized at startup
  int ledPin;      // the number of the LED pin
  long OnTime;     // milliseconds of on-time
  long OffTime;    // milliseconds of off-time
 
  // These maintain the current state
  int ledState;                 // ledState used to set the LED
  unsigned long previousMillis;   // will store last time LED was updated
 
  // Constructor - creates a Flasher 
  // and initializes the member variables and state
  public:
  Flasher(int pin, long on, long off)
  {
  ledPin = pin;
  pinMode(ledPin, OUTPUT);     
    
  OnTime = on;
  OffTime = off;
  
  ledState = LOW; 
  previousMillis = 0;
  }
 
  void Update()
  {
    // check to see if it's time to change the state of the LED
    unsigned long currentMillis = millis();
     
    if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      ledState = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(ledPin, ledState);  // Update the actual LED
    }
    else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      ledState = HIGH;  // turn it on
      previousMillis = currentMillis;   // Remember the time
      digitalWrite(ledPin, ledState);   // Update the actual LED
    }
  }
};
 
 
Flasher led1(36, 1000, 2000);
//Flasher led2(13, 350, 350);




void setup() {
Serial.begin(115200);
Serial1.begin(4800);
}
void loop() {
while (Serial1.available() > 0) {
//int val = ArduinoSerial.parseInt();
  if (Serial1.read() == 'p') {
    pozad_vlh = Serial1.parseInt();
    Serial.println("poz.vlh:"); 
    Serial.println(pozad_vlh);
    }
  if (Serial1.read() == 'f') {
     int asd = Serial1.parseInt();
    Serial.println("Frek.hnoj:"); 
    Serial.println(asd);
    }

 if (Serial1.read() == 'm') {
   int lkj = Serial1.parseInt();
    Serial.println("min.tep:"); 
    Serial.println(lkj);
    }   
}
if(pozad_vlh >= trt) 
  {
   led1.Update();
   trt +=5;
   Serial.println("zaplo");
  
  }
delay(100);
}
  Flasher(int pin, long on, long off)
  {
  ledPin = pin;
  pinMode(ledPin, OUTPUT);

You should NOT be diddling with the hardware in your constructor. You do NOT know that the hardware is ready to be diddled with.

while (Serial1.available() > 0) {
//int val = ArduinoSerial.parseInt();
  if (Serial1.read() == 'p') {
    pozad_vlh = Serial1.parseInt();
    Serial.println("poz.vlh:");
    Serial.println(pozad_vlh);
    }
  if (Serial1.read() == 'f') {
     int asd = Serial1.parseInt();
    Serial.println("Frek.hnoj:");
    Serial.println(asd);
    }

 if (Serial1.read() == 'm') {
   int lkj = Serial1.parseInt();
    Serial.println("min.tep:");
    Serial.println(lkj);
    }

If there is at least one character to read, read it. If it isn't a 'p', read another character. Oops.

You need to read ONCE and test three times.

Inside IF it should turn on relay for 1 sec and then turn off for 2 seconds, but it stopped at turn on and dont turn off.

In the body of the if(pozad_vlh >= trt) statement, you call led1.Update(). That is not a blocking method, so it compares now with the last time the pin was toggled. There are several mysteries here. First, why is now given the stupid name currentMillis? What's wrong with now? Second, why is the last time the pin changed state called previousMillis? That is a dumb name that gives no indication of what the time in the variable is the time of. Third, why is the class to deal with pins that relays are attached to called Flasher? You aren't flashing a relay. Why is the pin name called ledPin? There isn't an LED connected to the pin. Why is instance of the class that is meant to deal with a relay called led1?

Regardless, once you call led1.Update(), you change the value of trt. Why?

Why would you expect led1.Update() to be called again later, when you keep changing the conditions under which it should be called?

Thanks for your help and sorry for late answer.

First of all, that class Flasher i used is example from adafruit page for blinking multiple leds. Now i am using leds instead of relays for testing so i let that names what is in that code. In that serial read i am sending more that one variable so i think it could be like is now . It’s working properly .

And at the end i completly reworked that code and it’s whole without delays. It’s working fine, sensors are reading, relays turning on like they should BUT there can became error if i change something.

So if u can help me with this i will be verry pleased. So i will explain.

When you look into code in loop you can see first if. vlh_zem is humidity from DHT11 so its changing every 1 sec. pozad_vlh is required humidity we set up. So when condition is met it will call function updateLed_A_State(); . But there can came error what i am talked about. It seems working fine but when that Led is HIGH and meantime vlh_zem become higher than pozad_vlh LED should turn off but it stayed HIGH. If this happens when Led is LOW it stays LOW.
So i was thinking about something like this : if((led_A_State == HIGH)||(pozad_vlh < vlh_zem)){digitalWrite(40, LOW);}
But it still won’t help. So if u can guide me to something what turn off led when vlh_zem become higher that pozad_vlh.

And something similar is needed in second if. I am changing interval how long Led should be LOW. Basicaly i set up time how often led should turn on for time which i declared. When i set up 0 it should turn off led.

Thank you for your help and time.

void loop() {
currentMillis = millis();  
switchLeds();

if((pozad_vlh >= vlh_zem)||(led_A_Interval==0))
                            {
                                updateLed_A_State();  
                              
                            }
                           
                      else {digitalWrite(40, LOW);}
                      
                      if(led_B_Interval > 0)
                            {
                                updateLed_B_State();  }
                        
                             
                      else {digitalWrite(41, LOW);}

}
void switchLeds() {
      // this is the code that actually switches the LEDs on and off

 
  digitalWrite(led_A_Pin, led_A_State);
  digitalWrite(led_B_Pin, led_B_State);
 
}





void updateLed_A_State() {

  if (led_A_State == LOW) {
    if (currentMillis - previousLed_A_Millis >= led_A_Interval) {
       led_A_State = HIGH;
       previousLed_A_Millis += led_A_Interval;
      
    }
  }
  else {
    if (currentMillis - previousLed_A_Millis >= blinkDuration) {
       led_A_State = LOW;
       previousLed_A_Millis += blinkDuration;
    } 
  }    
}

void updateLed_B_State() {

  if (led_B_State == LOW) {
    if (currentMillis - previousLed_B_Millis >= led_B_Interval) {
       led_B_State = HIGH;
       previousLed_B_Millis += led_B_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_B_Millis >= blinkDuration) {
       led_B_State = LOW;
       previousLed_B_Millis += blinkDuration;
    }
  }    
}

In that serial read i am sending more that one variable so i think it could be like is now . It's working properly .

No, it isn't. If you send 'p', the code works. If you send 'f', the code reads a character, and sees that it isn't a 'p', so it throws it away. Then, it reads another character, regardless of whether the is anything to read, or not, and may see that that isn't an 'f'.

You need to read the character, and save it. Then compare the saved character to 'p', 'f', and 'm'.

And at the end i completly reworked that code and it's whole without delays. It's working fine, sensors are reading, relays turning on like they should BUT there can became error if i change something.

And, yet, you didn't post all of the new code. And what you did post still looks like it was typed by a drunken monkey.

So if u can guide me to something what turn off led when vlh_zem become higher that pozad_vlh.

if(vlh_zem > pozad_vlh)
   digitalWrite(whateverPin, LOW);

Thanks for your reply,

i posted only that part of my code with i need help. Thanks for marking me as "drunken monkey". I don't know what is bad at that code. And

if(vlh_zem > pozad_vlh)
   digitalWrite(whateverPin, LOW);

doesn't work. It still doing same thing . LED don't lights like normal but it stayed stucked and dont turn off when vlh_zem>pozad_vlh .

So when we imagine that it's relay with pump then it can stuck when pumping water. This stuck only become when value of vlh_zem change when LED is HIGH. So it stays stucked at HIGH i tried multiple solutions but it doesn't worked. Like i said it don't lights like when it should be HIGH not that bright and sometimes change brightness. So i think it may be hardware problem ? Maybe high current collection?

Thanks again