Avoid waiting for multiple "delay(500);" in 'void loop'

I have a 3 wire analog rain sensor connected to an Arduino UNO board. I have a relay shield mounted on the UNO board. The relays operate automatic doors and shutters / curtains independently. ( 4 units, 8 scenarios )
I pulse a relay for half a second when it meets certain criteria and then move on to the next relay…
The sketch works fine just the way it is, but I need the code in “void loop” to run without the whole loop waiting for each ‘delay()’. ( I do this 8 times on 4 relays with different values from the rain sensor in each case. )

Problem: Two of the 8 units are 2 wire switching so they use a single sequential pulse to open, stop and/or close. The units take up to 20 seconds to complete their movement. I have a reed switch to indicate when the unit is closed, but to avoid changes in humidity from initiating a second pulse, I need to disable the relay a countdown / timer in the code without stopping the ‘void loop’ to wait for the long delay.

The code below is a bit long, but it runs completely like this.

unsigned int stat_relay1_h;
unsigned int stat_relay2_h;

const int buttonPin = 8;     // the number of the reed switch pin
int buttonState = 0;         // variable for reading the reed switch status

const int relay1 = 4;        // the number of relay1 pin
const int relay2 = 5;        // the number of relay2 pin

void setup() {
  pinMode(relay1, OUTPUT);  // Relay 1
  pinMode(relay2, OUTPUT);  // Relay 2

  Serial.begin(115200);
}

void loop() {

  buttonState = digitalRead(buttonPin);  // read the state of the reed value:
  if (buttonState == LOW) {
  //Relay1
  if (stat_relay1_h == 0) {
    if (analogRead(0) < 500) {   //      Analog rain sensor (3 wire)
      digitalWrite(relay1, HIGH);
      delay(500);  ////// This is the delay I am trying to avoid please..........
      digitalWrite(relay1, LOW);
      stat_relay1_h = 1;
    }
  }
  if (analogRead(0) > 499) {
    if (stat_relay1_h == 1) {
      stat_relay1_h = 0;
    }
  }

  //Relay2
  if (stat_relay2_h == 0) {
    if (analogRead(0) < 400) {
      digitalWrite(relay2, HIGH);
      delay(500);
      digitalWrite(relay2, LOW);
      stat_relay2_h = 1;
    }
  }
  if (analogRead(0) > 399) {
    if (stat_relay2_h == 1) {
      stat_relay2_h = 0;
    }
  }
  delay(500); // Makes the code more stable...?
}
}

Please study blink without delay, which is in the examples in the IDE under digital and apply the lessons learnt to your code.
Also study
Using millis for timing
Demonstration for several things at the same time

Apply what you learn to your code. Come back and ask if you get stuck.

Enjoy :slight_smile:

unsigned long Relay1StartTime = 0;

void loop()
{
  unsigned long currentTime = millis();

  // Turn Relay1 off 500 milliseconds after turning on
  if (Relay1StartTime != 0 && currentTime - Relay1StartTime >= 500)
  {
    digitalWrite(relay1, LOW);
    Relay1StartTime = 0;
  }

  if (analogRead(0) < 500)     //      Analog rain sensor (3 wire)
  {
    digitalWrite(relay1, HIGH);
    Relay1StartTime = currentTime;  // Turn off 500 milliseconds from now
    stat_relay1_h = 1;
  }
}

Thank you Perry and John, that's why I asked. I truly appreciate your help. Problem solved so far...

Built it around the code you suggested John and works perfectly. Just needed to add:

long currentTime = 0;        // will store last time Relay was updated

fatman1961:
Built it around the code you suggested John and works perfectly. Just needed to add:

long currentTime = 0;        // will store last time Relay was updated

Glad you got it working but it will stop working in roughly 20 days. You MUST use unsigned long AKA uint32_t for all millis() related time variables. Millis() used unsigned values, you must do the same.

fatman1961:
Built it around the code you suggested John and works perfectly. Just needed to add:

long currentTime = 0;        // will store last time Relay was updated

Why would you do that when the code I wrote already contains:

void loop()
{
  unsigned long currentTime = millis();

AND already contains a global variable to store "last time Relay was updated" (actually, the last time the relay was turned on):

unsigned long Relay1StartTime = 0;

johnwasser:
Why would you do that when the code I wrote already contains:

void loop()

{
 unsigned long currentTime = millis();



AND already contains a global variable to store "last time Relay was updated" (actually, the last time the relay was turned on):


unsigned long Relay1StartTime = 0;

It wouldn't compile, as the IDE said currentTime was undefined...? No biggy, it works fine and I'll use unsigned long to complete it as Perry said.
However, Is it OK though to ask for help and advice here, as I feel that I'm being judged for not being perfect?

fatman1961:
However, Is it OK though to ask for help and advice here, as I feel that I'm being judged for not being perfect?

You aren't being judged. You are being coached.

fatman1961:
However, Is it OK though to ask for help and advice here, as I feel that I'm being judged for not being perfect?

It's OK to ask questions, it's OK to ask seemingly dumb questions. Those of us who reply are not perfect either, and most if not all of us are not trained teachers so we maybe miss the finer points of teaching people properly.