Multiple if statement DELAY lines to have a input detection, and turn off more precisely

Hello,

I am trying to use the following piece of code and it is not behaving the way I need it to.

Open for FULL CODE!! Keeping the post neat.
//BLOCK COMMENT
//https://forum.arduino.cc/t/cyclic-relay2a-2b/889080/10
#define ProjectName "Solenoids"
// CONSTANT DEFINITION
// you need to change these constants to your hardware
const byte Relays[] {3, 7, 8, 4};
const byte Buttons[] {2};
int tt;
// VARIABLE DECLARATION
enum {One, TwoA, TwoB, TwoC};
struct BUTTON
{
  byte pin;
  int pressedState;  // LOW for Active Low
  bool wasPressed;
  int counter;
  unsigned long lastStateChangeTime;
  unsigned long debounceInterval;
} button {Buttons[One], 1, 0, 0, 20};

void setup()
{
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);
  pinMode (A0,INPUT);
  for (auto Relay : Relays) pinMode ( Relay, OUTPUT);
  for (auto Button : Buttons) pinMode ( Button, INPUT_PULLUP);
}

void loop ()
{
tt = analogRead(A0) /10.23;
  Serial.print("Time in Seconds due to Potentiometer :");
  Serial.println (tt);
  unsigned long currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);

  bool buttonIsPressed = digitalRead(button.pin) == button.pressedState;
  if (buttonIsPressed != button.wasPressed &&
      currentTime - button.lastStateChangeTime >= button.debounceInterval)
  {
    // State Change Detected
    button.wasPressed = buttonIsPressed;
    button.lastStateChangeTime = currentTime;
    {
      // Button was just pressed
      button.counter = (button.counter + 1) % 6;

      static unsigned long TimeOfLastButtonPress = 0;

      unsigned long timeBetweenButtonPresses = currentTime - TimeOfLastButtonPress;
      TimeOfLastButtonPress = currentTime;

      for (auto Relay : Relays)
        digitalWrite ( Relay, LOW);

      if (timeBetweenButtonPresses > 200) // longer than a second and a half
        SlowPressCycle(button.counter);
      else if (timeBetweenButtonPresses > 100) // Longer than half a second
        MediumPressCycle(button.counter);
      else
        StandardCycle(button.counter);
    }
  }
}

// When the Pulse is SLOW (like every 2 Seconds)
// I would like all Relays (TwoA, B & C) same time
void SlowPressCycle(int count)
{
  switch (count)
  {
    case 0: 
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
end1:
digitalWrite ( Relays[One] , LOW);
      break;
    case 1:
      digitalWrite ( Relays[TwoA] , HIGH);
      digitalWrite ( Relays[TwoB] , HIGH);
      digitalWrite ( Relays[TwoC] , HIGH);
      break;

    case 2:
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
delay(tt);if (digitalRead(2) == LOW)goto end2;
end2:
digitalWrite ( Relays[One] , LOW);
      break;

    case 3:
      digitalWrite ( Relays[TwoA] , HIGH);
      digitalWrite ( Relays[TwoB] , HIGH);
      digitalWrite ( Relays[TwoC] , HIGH);
      break;

    case 4:
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
delay(tt);if (digitalRead(2) == LOW)goto end3;
end3:
digitalWrite ( Relays[One] , LOW);
      break;

    case 5:
      digitalWrite ( Relays[TwoA] , HIGH);
      digitalWrite ( Relays[TwoB] , HIGH);
      digitalWrite ( Relays[TwoC] , HIGH);
      break;
  }
}

// When the Pulse is faster (every 1 second)
// to have cycle between TwoA,B then TwoB,C
void MediumPressCycle(int count)
{
  switch (count)
  {
    case 0:
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
delay(tt);if (digitalRead(2), LOW)goto end4;
end4:
digitalWrite ( Relays[One] , LOW);
      break;

    case 1:
      digitalWrite ( Relays[TwoA] , HIGH);
      digitalWrite ( Relays[TwoB] , HIGH);
      break;

    case 2:
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
delay(tt);if (digitalRead(2), LOW)goto end5;
end5:
digitalWrite ( Relays[One] , LOW);
      break;

    case 3:
      digitalWrite ( Relays[TwoB] , HIGH);
      digitalWrite ( Relays[TwoC] , HIGH);
      break;

    case 4:
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
delay(tt);if (digitalRead(2), LOW)goto end6;
end6:
digitalWrite ( Relays[One] , LOW);
      break;

    case 5:
      digitalWrite ( Relays[TwoC] , HIGH);
      digitalWrite ( Relays[TwoA] , HIGH);
      break;
  }
}

// When the Pulse is Fastest (faster than 1 second)
// Standard Cycle TwoA, then TwoB, then TwoC.
void StandardCycle(int count)
{
  switch (count)
  {
    case 0: digitalWrite ( Relays[One] , HIGH); 
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
delay(tt);if (digitalRead(2), LOW)goto end7;
end7:
digitalWrite ( Relays[One] , LOW);break;
    case 1: digitalWrite ( Relays[TwoA] , HIGH); break;
    case 2: digitalWrite ( Relays[One] , HIGH); 
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
delay(tt);if (digitalRead(2), LOW)goto end8;
end8:
digitalWrite ( Relays[One] , LOW);break;
    case 3: digitalWrite ( Relays[TwoB] , HIGH); break;
    case 4: digitalWrite ( Relays[One] , HIGH);
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
delay(tt);if (digitalRead(2), LOW)goto end9;
end9:
digitalWrite ( Relays[One] , LOW);break;
    case 5: digitalWrite ( Relays[TwoC] , HIGH); break;
  }
}

Basically, My Arduino when Input goes high it's supposed to turn on Relay 1, then when it goes LOW and turns on Relays 2a/b/c. bit of complex stuff for speed control etc.

I have added a potentiometer to limit how long I want Relay 1 to stay on for (0-5s).
I had an issue and reduced the time to 1s.

I had a problem where the potentiometer would keep relay 1 too long, past when the input is supposed to turn it off.

Then I thought to create a bunch of small delays which detect inputsignal then adds more delay if the input is still HIGH

The problem is the Relay1 is only on for what feels like 100ms, i have stuffed up the following code and would like some help correcting it

Basically the way I understand the following snippet of code is
Start by turning on Relay 1.
Add a delay = what the potentiometer is.. (100ms) MAX
now if inputsignal (pin2) has gone LOW move onto END1.
If the input is still high it should add another 100ms of delay
and so on.

What do I need to do to ensure that it will stay on for multiple passes of those if statements?

    case 0: 
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
delay(tt);if (digitalRead(2) == LOW)goto end1;
end1:
digitalWrite ( Relays[One] , LOW);
      break;
    case 1:
      digitalWrite ( Relays[TwoA] , HIGH);
      digitalWrite ( Relays[TwoB] , HIGH);
      digitalWrite ( Relays[TwoC] , HIGH);
      break;```

EDIT:

This was resolved by changing

delay(tt);if (digitalRead(2) == LOW)goto end1;
to
delay(tt);if (digitalRead(2) == HIGH)goto end1;

I have a new problem,
When I increase the input signal speed. I am not getting good detection of the input signal,
because of the way I have added so much code.

reducing the number of
delay(tt);if (digitalRead(2) == HIGH)goto end1;
has helped. but can anyone provide suggestions to increase performance for the the fast cycle code

void StandardCycle(int count)
{
  switch (count)
  {
    case 0: digitalWrite ( Relays[One] , HIGH); 

digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), HIGH)goto end7;
delay(tt);if (digitalRead(2), HIGH)goto end7;
end7:
digitalWrite ( Relays[One] , LOW);break;

    case 1: digitalWrite ( Relays[TwoA] , HIGH); break;

    case 2: digitalWrite ( Relays[One] , HIGH); 
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), HIGH)goto end8;
delay(tt);if (digitalRead(2), HIGH)goto end8;
end8:
digitalWrite ( Relays[One] , LOW);break;

    case 3: digitalWrite ( Relays[TwoB] , HIGH); break;

    case 4: digitalWrite ( Relays[One] , HIGH);
digitalWrite ( Relays[One] , HIGH);
delay(tt);if (digitalRead(2), HIGH)goto end9;
delay(tt);if (digitalRead(2), HIGH)goto end9;
end9:
digitalWrite ( Relays[One] , LOW);break;

    case 5: digitalWrite ( Relays[TwoC] , HIGH); break;

It would be much better to use millis() for non blocking timing rather than a series of small delay()s

See Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

Thank you kindly UKHeliBob. I will look at this,
I remember you menioning to use this for my lighting system in my wall computers years ago, I dont know what it did to help, so long ago..

would using millis replace me needing 10x lines of delay?

Using millis work in this scenario;

lets say within a 4second gap (the input is tied with the input HIGH/LOW/HIGH/LOW)
1s. relay1 on / relay 2 off
2s, relay 1 off / relay 2 on
3s, relay 1 on / relay 2 off
4s, relay 1 off / relay 2 on

If I use a single millis as a delay for relay 1. the potentiometer has set a millis delay of 5 seconds
would relay 1 stay on during the full 5 seconds or would it turn off again? at second 2.

Hope that makes sense..

Yes. What you do is to save the value of millis() as the start time when any action requiring timing occurs, for instance a input going LOW (as opposed to it being LOW) then keep going round loop(), reading inputs, writing outputs, printing messages, whatever as long as what you do leaves loop() running freely. Also, in loop() you check whether the current value of millis() minus the start time equals or is greater than your required period for the action that you are timing. If not then keep going round loop() until the period has ended and then take the necessary action

As to your other questions, the answer is yes. If you are timing several events at the same time then you will, of course, need a different start time variable and period variable for each of them if they start at different times and/or have different timing periods/ You can, of course, set the timing period by reading a pot if that is what you want to do

Further to the above, if your sketch can be in one of a number of states at any point in time then it is convenient to write it using switch/case based on the current state. Doing this it is easy to control what code is running and how long for (using millis(), of course) and you can still have general purpose code in loop() such as reading an input or a pot to change the timing or flow of the sketch

consider fragment

enum { Off = HIGH, On = LOW };

// -----------------------------------------------------------------------------
void
sensorChk (
    unsigned long tt)
{
    unsigned long msecLst = millis ();

    digitalWrite ( Relays[One] , On);

    while ((millis() - msecLst) < 10 * tt)
        if (LOW == digitalRead (sensorPin))
            break;

    digitalWrite ( Relays[One] , Off);
}

// -----------------------------------------------------------------------------
void SlowPressCycle (
    int count)
{
    Serial.println (__func__);

    switch (count) {
    case 0:
    case 2:
        sensorChk (200);
        break;

    case 1:
    case 3:
    case 4:
        digitalWrite ( Relays[TwoA] , On);
        digitalWrite ( Relays[TwoB] , On);
        digitalWrite ( Relays[TwoC] , On);
        break;
    }
}

other optimizations possible

also, when are Relays TwoA, TwoB and TwoC ever set LOW?

Depending of the switching rate of the input signal
High low high low.. the relays are as such

Inputsignal high = r1
Inputsignal low = r2

Slow speed
R1
R2a/b/c

Medium speed
R1
R2a/b
R1
R2b/c
R1
R2c/a

Fast speed
R1
R2a
R1
R2b
R1
R2c

That is the order of the cycle.