adjustable (Count Down or Up timer) to then reset to different Caseline

Hello

Big NOOB here, been working on my first project and I have found my self continuously looking online for help but this particular time I cant seem to find what I need or even know how to start it.

I have my 3 s electable Modes (with every Click) but what I want now is the activate a 5 to 30 Second Timer to CASE LINE 2 (Mode 2) once it has finished its timer I then want it to switch to a another mode automatically.

I do not want to use Delays… Delays give me no control (I want to be able to bypass the Timer ) if I was to click my manual button again.

any help (be nice) would be appreciated.

Thanks

#include <Event.h>
#include <Timer.h>

#include <Bounce2.h>
#define BUTTON_PIN_1 8

Timer t;
byte switchVal = 0;
byte prevSwitch = 0;
byte counter = 0;
const int BUTTON_PIN = 8; //Manual Button + Relay Driven RF Reciever
const byte LEDSTOP = 13;  //Mode Confirm (STATUS and CONFIRM that NO RELAYS ARE ACTIVE
const byte RELAYOPEN = 7;  //RELAY 1 = OPEN Gate
const byte RELAYCLOSE = 6;  //RELAY 2 = CLOSE Gate

Bounce debouncer = Bounce();  //debounce library installed for mechanical switches
//in the code

void setup()
{
  pinMode(BUTTON_PIN,INPUT_PULLUP);   //Internal Pullup used for pushbutton to switch between modes
  debouncer.attach(BUTTON_PIN); // Debounce Library (attatched for reading value for accruate response
  debouncer.interval(5); // used 5ms this was standard when i set it up and it seemed to work very well
  Serial.begin(9600); //used Serial to Diagnose what output is selected as quickly as possible, just incase I had interefence issues. 
  pinMode (BUTTON_PIN, INPUT_PULLUP);
  pinMode (LEDSTOP, OUTPUT );     //Gate Stop (NOT MOVING) Possition
  pinMode (RELAYOPEN, OUTPUT);    //Gate Openening Possition
  pinMode (RELAYCLOSE, OUTPUT);   //Gate Closing Possition
}

void loop()
{
 { // Update the Bounce instance :
  debouncer.update();

  // Get the updated value :
  int value = debouncer.read();
 }
switchVal = digitalRead(BUTTON_PIN);
if ((switchVal == HIGH) && (prevSwitch == 0))  //counter used to select which case line/mode to use 
{
counter ++;
prevSwitch = 1;
}
else if (switchVal == LOW)
{
prevSwitch = 0;
}
switch (counter)
  {
case 1:                               //Case 1 (Mode 1) used to confirm Gate is in STOP POSSITION and OPEN AND CLOSE RELAYS ARE INACTIVE 
digitalWrite(LEDSTOP, HIGH);
delay (100);
Serial.println("LEDSTOP");
Serial.println();
digitalWrite(RELAYOPEN, LOW);
digitalWrite(RELAYCLOSE, LOW);
break;
case 2:                               //Case 2 (Mode 2) used to confirm Gate is in OPEN POSSITION and CLOSE AND STOP RELAY and LAMP ARE INACTIVE
digitalWrite(RELAYOPEN, HIGH);
delay (100);
Serial.println("LEDOPEN");
Serial.println();
digitalWrite(RELAYCLOSE, LOW);
digitalWrite(LEDSTOP, LOW);
break;
case 3:                               //Case 3 (Mode 3) used to confirm Gate is in CLOSE POSSITION and OPEN AND STOP RELAY and LAMP ARE INACTIVE
digitalWrite(RELAYCLOSE, HIGH);
Serial.println("LEDCLOSE");
Serial.println();
digitalWrite(LEDSTOP, LOW);
digitalWrite(RELAYOPEN, LOW);
break;
default:
counter = 1;                          //Revert Back to Case Line 1 (MODE 1) 
break;
}
}

You have to distinguish actions to be taken on entering an new state, and on a timeout. When you use "counter" to denote the next state to enter, add another "state" variable to hold the current state. When counter!=state, invoke the action to enter the new state switch (counter) .... In a second switch (state) ... you can do whatever is required while a state is current, e.g. wait for a timeout and switch to another state.

So with the following I can change the counter state at the end of any thread ?

Do you also have any information on adding the timer without using a pin out at the end of the timer?

Many thanks

You can consider the counter variable as holding the next state. When a state change is required, update counter to that value.

Software timers, using miilis() or micros(), don't need pins and interrupts. See "blink without delay".

The thing is, the Millis timer example used on the blind without delay example (not only does not seem to work within the case) but also does not re loop.

I appreciate forwarding me to the example but it doesn't quite show me how to implement it in this particular case.

any form of example is greatly appreciated

thank you

Actually ....

is this even the best way forward? to use case lines with a counter?

or should I be using a if and else statements to manage a project such as this?

I am starting to think i have taken the wrong route

Many Thanks

Have you tried drawing a state diagram, with arrows for each event that should force a state change?

Then you know what you have to code in each branch of a switch(state) statement.

Hello

I am not sure what you mean? a diagram so I know where I am?

I only have 3 modes which range from 1, 2 and 3 with each state noted.

or am I completely off one what you mean?

Thanks

Do you mean that when a user selects the 2nd position the Arduino should move on to another position (perhaps position 3) after a time interval even if the user does nothing?

What happens if there is user input during the time interval?

A simple way to move on after an interval is to save the value of millis() when the 2nd position is reached and then keep comparing millis() to the saved value. Then if (millis() - savedValue >= interval) change to the appropriate position.

The demo Several Things at a Time illustrates the use of millis()

It is a good idea to write down the flow of the program and all the conditions in plain language (not code) with one step on each line. See Planning and Implementing a Program

...R