multiple relay input to multiple relay output

So I am trying to do this step by step.

I am trying to read tstatValue1 when HIGH for example and have it turn on zone1 for a half of second and then off while the tstatValue1 is still HIGH. Then when tstatValue1 changes back to LOW zone1 is still LOW and waiting to turn on again. Now to make it fun zonereverse1 is doing exactly opposite zone1. I will then replicate that across 4 independent inputs.

The thing I am trying to do with code. zone 2,3,4 was just me trying to see if I could get it to work without the half second turn off hence why it is commented out:

const int zone1 = 1;
const int zone2 = 2;
const int zone3 = 3;
const int zone4 = 4;
const int zonereverse1 = 5;
const int zonereverse2 = 6;
const int zonereverse3 = 7;
const int zonereverse4 = 8;
const int tstat1 = A0;
const int tstat2 = A1;
const int tstat3 = A2;
const int tstat4 = A3;
int tstatValue1 = LOW;
int tstatValue2 = LOW;
int tstatValue3 = LOW;
int tstatValue4 = LOW;
int tstatState1 = LOW;
int tstatState2 = LOW;
int tstatState3 = LOW;
int tstatState4 = LOW;

void setup ()
pinMode(tstat1, INPUT);
pinMode(tstat2, INPUT);
pinMode(tstat3, INPUT);
pinMode(tstat4, INPUT);
pinMode(zone1, OUTPUT);
pinMode(zone2, OUTPUT);
pinMode(zone3, OUTPUT);
pinMode(zone4, OUTPUT);
pinMode(zonereverse1, OUTPUT);
pinMode(zonereverse2, OUTPUT);
pinMode(zonereverse3, OUTPUT);
pinMode(zonereverse4, OUTPUT);

void loop ()

tstatValue1 = digitalRead(tstat1);

//tstatValue2 = digitalRead(tstat2);

//tstatValue3 = digitalRead(tstat3);

//tstatValue4 = digitalRead(tstat4);

if (tstatValue1 == HIGH && tstatState1 == LOW)
digitalWrite(zone1,HIGH); // relay1 is power-on
digitalWrite(zonereverse1,LOW); // relay5 is power-off
delay(500); //half-second close
digitalWrite(zone1,LOW); // relay1 is powered-off
digitalWrite(zonereverse1,HIGH); // relay5 is power-on
delay(500); //half-second close
digitalWrite(zonereverse1,LOW); // relay5 is power-off
tstatState1 = HIGH;

if (tstatValue == HIGH && tstatState == HIGH) //do nothing if input is still HIGH

if (tstatValue == LOW && tstatState == HIGH) // if input swings LOW reset tstatState1 to LOW
tstatState1 = LOW;

//if (tstatValue2 == HIGH)
//digitalWrite(zone2,HIGH); // relay1 is power-on
//digitalWrite(zonereverse2,LOW); // relay1 is power-on
//digitalWrite(zone2,LOW); //relay1 is power-off
//digitalWrite(zonereverse2,HIGH); // relay1 is power-on

//if (tstatValue3 == HIGH)
//digitalWrite(zone3,HIGH); // relay1 is power-on
//digitalWrite(zonereverse3,LOW); // relay1 is power-on

//digitalWrite(zone3,LOW); //relay1 is power-off
//digitalWrite(zonereverse3,HIGH); // relay1 is power-on

//if (tstatValue4 == HIGH)
//digitalWrite(zone4,HIGH); // relay1 is power-on
//digitalWrite(zonereverse4,LOW); // relay1 is power-on

//digitalWrite(zone4,LOW); //relay1 is power-off
//digitalWrite(zonereverse4,HIGH); // relay1 is power-on

Now I do not know the best way to do this and I figure you peeps are more than able to guide me. I need help mind hurts too much coffee. Not enough water.



In order to read several inputs and do what you want you need to stop using delay() because while the delay is occurring then nothing else will happen. Switch to using millis() to record the moment at which an input changed state then compare the saved value with millis() each time through loop() until the required period has elapsed and you take the required action.

The BlinkWithoutDelay example in the IDE will show you the principle. This is the basic idea

start of loop
  if input is HIGH
    set start equal to millis()
  end if

  if millis() minus start is greater than period
    do actions for end of waiting period
  end if
end of loop

Get that working with one input/output and then move on to more inputs/outputs using arrays to hold values so that you can reduce the code.

 if (tstatValue == HIGH && tstatState == HIGH)  //do nothing if input is still HIGH

Why include code that does nothing ?

You should update yourself on the concepts of a state machine an then start by drawing a state diagram before you start to code. I had a hard time understanding you description, there are lots of ambiguities. For example, what should happen if the button is released within 0.5s. What do you mean by waiting? etc. All this must be solved before starting to code.

Once that is done its fairly easy converting the state diagram into scalable and bug free code using my state machine library found here:
instruction for installing a library are here:

You got me pointed to an interesting problem, if it is possible to make an array of identical state machines sharing the same states. It is! here is the code:

#include <SM.h>
const int noSwitches = 4;
int i;//identifies current state machine

//create and intialise 4 identical state machines
SM timedTurnoff[noSwitches] = {SM(waiting), SM(waiting), SM(waiting), SM(waiting)};
const int ledPin[noSwitches] = {8, 9, 10, 11};
const int btnPin[noSwitches] = {2, 3, 4, 5};

void setup(){
  for(i = 0; i < noSwitches; i++) pinMode(ledPin[i], OUTPUT);

void loop(){
  for(i = 0; i <noSwitches; i++) EXEC(timedTurnoff[i]);

State waiting(){
  digitalWrite(ledPin[i], 0);
  if(digitalRead(btnPin[i])) timedTurnoff[i].Set(turnOn);

State turnOn(){
  digitalWrite(ledPin[i], 1);
  if(!digitalRead(btnPin[i])) timedTurnoff[i].Set(waiting);
  if(timedTurnoff[i].Timeout(500)) timedTurnoff[i].Set(turnOff);

State turnOff(){
  digitalWrite(ledPin[i], 0);
  if(!digitalRead(btnPin[i])) timedTurnoff[i].Set(waiting);

timed turnoff.png