I am out of the home so can't test code but this is program I would test
#define ResetTimer millis()
#define ENABLED true
#define DISABLED false
#define RelayOFF HIGH
#define RelayON LOW
#define PUSHED LOW
#define RELEASED HIGH
const byte Switch_Pin1 = 4;
const byte Switch_Pin2 = 5;
const byte Switch_Pin3 = 6;
const byte Switch_Pin4 = 7;
const byte Relay_Pin1 = 8;
const byte Relay_Pin2 = 9;
const byte Relay_Pin3 = 10;
const byte Relay_Pin4 = 12;
boolean FLAG1 = DISABLED;
boolean FLAG2 = DISABLED;
boolean FLAG3 = DISABLED;
boolean FLAG4 = DISABLED;
byte lastSwitch_Pin1 = RELEASED;
byte lastSwitch_Pin2 = RELEASED;
byte lastSwitch_Pin3 = RELEASED;
byte lastSwitch_Pin4 = RELEASED;
//timing stuff
unsigned long checkSwitchesTime;
unsigned long currentTime;
unsigned long relayTime1;
unsigned long relayTime2;
unsigned long relayTime3;
unsigned long relayTime4;
const long interval = 4000ul;
void setup()
{
// begin serial port with baud rate 9600bps
Serial.begin(9600);
// configure inputs pins for switche's
pinMode(Switch_Pin1, INPUT_PULLUP);
pinMode(Switch_Pin2, INPUT_PULLUP);
pinMode(Switch_Pin3, INPUT_PULLUP);
pinMode(Switch_Pin4, INPUT_PULLUP);
pinMode(Relay_Pin1, OUTPUT);
pinMode(Relay_Pin2, OUTPUT);
pinMode(Relay_Pin3, OUTPUT);
pinMode(Relay_Pin4, OUTPUT);
digitalWrite(Relay_Pin1, RelayON);
digitalWrite(Relay_Pin1, RelayON);
digitalWrite(Relay_Pin3, RelayON);
digitalWrite(Relay_Pin4, RelayON);
}
void loop()
{
//capture the current time in milliseconds
currentTime = millis();
//time to check our switches ?
if (currentTime - checkSwitchesTime >= 50)
{
//restart this TIMER
checkSwitchesTime = ResetTimer;
checkSwitches();
}
//if enabled, is this TIMER expired ?
if (FLAG1 == ENABLED && currentTime - relayTime1 >= interval)
{
//we are now finished with this TIMER
FLAG1 = DISABLED;
digitalWrite(Relay_Pin1, RelayON);
}
//if enabled, is this TIMER expired ?
if (FLAG2 == ENABLED && currentTime - relayTime2 >= interval)
{
//we are now finished with this TIMER
FLAG2 = DISABLED;
digitalWrite(Relay_Pin2, RelayON);
}
if (FLAG3 == ENABLED && currentTime - relayTime3 >= interval)
{
//we are now finished with this TIMER
FLAG3 = DISABLED;
digitalWrite(Relay_Pin3, RelayON);
}
if (FLAG4 == ENABLED && currentTime - relayTime4 >= interval)
{
//we are now finished with this TIMER
FLAG4 = DISABLED;
digitalWrite(Relay_Pin4, RelayON);
}
}
void checkSwitches()
{
//********************************* Switch_Pin1
byte currentState = digitalRead(Switch_Pin1);
//did this switch change state ?
if (lastSwitch_Pin1 != currentState)
{
//update to the new state
lastSwitch_Pin1 = currentState;
//if we are not timing, is the switch now pushed ?
if (FLAG1 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
FLAG1 = ENABLED;
digitalWrite(Relay_Pin1, RelayOFF);
//reset this TIMER
relayTime1 = ResetTimer;
}
else
{
//do nothing here
}
} //END of this switch
//********************************* Switch_Pin2
currentState = digitalRead(Switch_Pin2);
//did this switch change state ?
if (lastSwitch_Pin2 != currentState)
{
//update to the new state
lastSwitch_Pin2 = currentState;
//if we are not timing, is the switch now pushed ?
if (FLAG2 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
FLAG2 = ENABLED;
digitalWrite(Relay_Pin2, RelayOFF);
//reset this TIMER
relayTime2 = ResetTimer;
}
else
{
//do nothing here
}
}
currentState = digitalRead(Switch_Pin3);
//did this switch change state ?
if (lastSwitch_Pin3 != currentState)
{
//update to the new state
lastSwitch_Pin3 = currentState;
//if we are not timing, is the switch now pushed ?
if (FLAG3 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
FLAG3 = ENABLED;
digitalWrite(Relay_Pin3, RelayOFF);
//reset this TIMER
relayTime3 = ResetTimer;
}
else
{
//do nothing here
}
}
currentState = digitalRead(Switch_Pin4);
//did this switch change state ?
if (lastSwitch_Pin4 != currentState)
{
//update to the new state
lastSwitch_Pin4 = currentState;
//if we are not timing, is the switch now pushed ?
if (FLAG4 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
FLAG4 = ENABLED;
digitalWrite(Relay_Pin4, RelayOFF);
//reset this TIMER
relayTime4 = ResetTimer;
}
else
{
//do nothing here
}
}
}
Pay attention to the style and code formatting to see how you can achieve documentation and readability in your projects.
In the software that you write, try to follow a similar style.
Note:
In the following sketch pin 12 was moved over to pin 11.
A heartbeatLED was added.
This LED gives a good indication if code is blocking; the LED should toggle every 1/2 second.
//********************************************^************************************************
//
// https://forum.arduino.cc/t/how-to-get-rid-of-this-blocking-delay/1025651
//
//********************************************^************************************************
// 0_Arduino_Skeleton_Sketch.ino
//
//
// Version YY/MM/DD Comments
// ======= ======== ========================================================
// 1.01 22/08/25 Running code
// 1.02 22/08/25 Added code to handle relays 4 and 5, move from pin12 to pin 11
//
//********************************************^************************************************
#define RESETtime millis()
#define ENABLED true
#define DISABLED false
#define RelayOFF HIGH
#define RelayON LOW
#define PUSHED LOW //+5V---[Pullup]---[Input Pin]---[Switch]---GND
#define RELEASED HIGH
//********************************************^************************************************
const byte Switch1 = 4;
const byte Switch2 = 5;
const byte Switch3 = 6;
const byte Switch4 = 7;
const byte Relay1 = 8;
const byte Relay2 = 9;
const byte Relay3 = 10;
const byte Relay4 = 11;
const byte heartbeatLED = 13;
boolean TimerFlag1 = DISABLED;
boolean TimerFlag2 = DISABLED;
boolean TimerFlag3 = DISABLED;
boolean TimerFlag4 = DISABLED;
byte lastSwitch1 = RELEASED;
byte lastSwitch2 = RELEASED;
byte lastSwitch3 = RELEASED;
byte lastSwitch4 = RELEASED;
//timing stuff
const long interval = 4000ul;
unsigned long currentTime;
unsigned long heartbeatTime;
unsigned long checkSwitchesTime;
unsigned long relay1Time;
unsigned long relay2Time;
unsigned long relay3Time;
unsigned long relay4Time;
// s e t u p ( )
//********************************************^************************************************
void setup()
{
Serial.begin(9600);
pinMode(Switch1, INPUT_PULLUP);
pinMode(Switch2, INPUT_PULLUP);
pinMode(Switch3, INPUT_PULLUP);
pinMode(Switch4, INPUT_PULLUP);
pinMode(heartbeatLED, OUTPUT);
pinMode(Relay1, OUTPUT);
pinMode(Relay2, OUTPUT);
pinMode(Relay3, OUTPUT);
pinMode(Relay4, OUTPUT);
digitalWrite(Relay1, RelayON);
digitalWrite(Relay2, RelayON);
digitalWrite(Relay3, RelayON);
digitalWrite(Relay4, RelayON);
} //END of setup()
// l o o p ( )
//********************************************^************************************************
void loop()
{
//capture the current time in milliseconds
currentTime = millis();
//********************************* heartbeat TIMER
//is it time to toggle the heartbeatLED (every 500ms)?
if (currentTime - heartbeatTime >= 500ul)
{
//restart this TIMER
heartbeatTime = RESETtime;
//toggle the heartbeatLED
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//********************************* checkSwitches TIMER
//time to check our switches ?
if (currentTime - checkSwitchesTime >= 50ul)
{
//restart this TIMER
checkSwitchesTime = RESETtime;
checkSwitches();
}
//********************************* Relay1 TIMER
//if enabled, is this TIMER expired ?
if (TimerFlag1 == ENABLED && currentTime - relay1Time >= interval)
{
//we are now finished with this TIMER
TimerFlag1 = DISABLED;
digitalWrite(Relay1, RelayON);
}
//********************************* Relay2 TIMER
//if enabled, is this TIMER expired ?
if (TimerFlag2 == ENABLED && currentTime - relay2Time >= interval)
{
//we are now finished with this TIMER
TimerFlag2 = DISABLED;
digitalWrite(Relay2, RelayON);
}
//********************************* Relay3 TIMER
//if enabled, is this TIMER expired ?
if (TimerFlag3 == ENABLED && currentTime - relay3Time >= interval)
{
//we are now finished with this TIMER
TimerFlag3 = DISABLED;
digitalWrite(Relay3, RelayON);
}
//********************************* Relay4 TIMER
//if enabled, is this TIMER expired ?
if (TimerFlag4 == ENABLED && currentTime - relay4Time >= interval)
{
//we are now finished with this TIMER
TimerFlag4 = DISABLED;
digitalWrite(Relay4, RelayON);
}
//*********************************
//other non blocking code goes here
//*********************************
} //END of loop()
// c h e c k S w i t c h e s ( )
//********************************************^************************************************
void checkSwitches()
{
byte currentState;
//********************************* Switch1
currentState = digitalRead(Switch1);
//did this switch change state ?
if (lastSwitch1 != currentState)
{
//update to the new state
lastSwitch1 = currentState;
//if we are not timing, is the switch now pushed ?
if (TimerFlag1 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
TimerFlag1 = ENABLED;
digitalWrite(Relay1, RelayOFF);
//reset this TIMER
relay1Time = RESETtime;
}
} //END of this switch
//********************************* Switch2
currentState = digitalRead(Switch2);
//did this switch change state ?
if (lastSwitch2 != currentState)
{
//update to the new state
lastSwitch2 = currentState;
//if we are not timing, is the switch now pushed ?
if (TimerFlag2 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
TimerFlag2 = ENABLED;
digitalWrite(Relay2, RelayOFF);
//reset this TIMER
relay2Time = RESETtime;
}
} //END of this switch
//********************************* Switch3
currentState = digitalRead(Switch3);
//did this switch change state ?
if (lastSwitch3 != currentState)
{
//update to the new state
lastSwitch3 = currentState;
//if we are not timing, is the switch now pushed ?
if (TimerFlag3 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
TimerFlag3 = ENABLED;
digitalWrite(Relay3, RelayOFF);
//reset this TIMER
relay3Time = RESETtime;
}
} //END of this switch
//********************************* Switch4
currentState = digitalRead(Switch4);
//did this switch change state ?
if (lastSwitch4 != currentState)
{
//update to the new state
lastSwitch4 = currentState;
//if we are not timing, is the switch now pushed ?
if (TimerFlag4 == DISABLED && currentState == PUSHED)
{
//enable this TIMER
TimerFlag4 = ENABLED;
digitalWrite(Relay4, RelayOFF);
//reset this TIMER
relay4Time = RESETtime;
}
} //END of this switch
//*********************************
} //END of checkSwitches()
//********************************************^************************************************