help going back to start of sketch from an "if" statement


I’m trying to use an arduino (Duemilanove) to replicate the lost functionality in a gate controller.
Basically what I need is the following:

  1. press a button (or in my case I’ll use a GSM relay but it’s the same thing)
  2. turn on relay 1, run for 12 seconds, stop relay 1
  3. 2 seconds after relay 1 has been on, start relay 2, run for 12 seconds, stop relay 2
  4. wait 45 seconds
  5. turn on relay 3, run for 12 seconds, stop relay 3
  6. 2 seconds after relay 3 has been on, start relay 4, run for 12 seconds, stop relay 4
  7. go back to waiting for button press

What I’ve managed so far (I have no experience programming so the last 4 days since I started this endeavour have been an exercise in hair pulling :slight_smile: )

const int buttonpin = 2;
const int relay6 = 6;
const int relay7 = 7;
int buttonstate = 0;
unsigned long time_button_was_pressed = 0;
unsigned long current_time = 0;

void setup () 
  pinMode (buttonpin, INPUT);
  pinMode (relay6, OUTPUT);
  pinMode (relay7, OUTPUT);

void loop (){
buttonstate = digitalRead(buttonpin);
if (buttonstate == HIGH){
  time_button_was_pressed = millis();
  digitalWrite(relay6, HIGH);

current_time = millis();
if (current_time > time_button_was_pressed + 10000)
{digitalWrite(relay6, LOW);}
if (current_time > time_button_was_pressed + 3000)
{digitalWrite(relay7, HIGH);}
if (current_time > time_button_was_pressed + 13000)
{digitalWrite(relay7, LOW);}

Now, the problem is: the relay board behaves erratically: a relay gets activated before I press the button!! Once I press the button (see the attached picture) the program runs as it should but the led on the second relay stays on, shouldn’t it turn itself off?

I don’t know what is going on but I suspect I need the loop to go back to the beginning of the sketch if “buttonstate” is not HIGH.

Now, I understand this may seem trivial to some people but if someone takes the time to help me I would greatly appreciate it.


PS. In the picture there is a 2 relay board but I also have an 8 relay board which exhibits the same behaviour.

Does an active "button" yield a high or a low? In this sketch, I assumed that it would be a High (High when pushed). I used different pins. I didn't use any millis(). Once the button is fired it commits to the whole gateAction() function. It doesn't look for the button again till it's finished with that.

Anyway, the loop () just looks for a button push. If that happens then it goes to gateAction.

const int buttonpin = 11;

const byte relay1 = 2;
const byte relay2 = 3;
const byte relay3 = 4;
const byte relay4 = 5;

void setup ()

void loop ()
  if (digitalRead(buttonpin) == 1)

void gateAction ()
  digitalWrite(relay1,HIGH); // secs = 0
  digitalWrite(relay2,HIGH); // secs = 2
  digitalWrite(relay1,LOW);  // secs = 12
  digitalWrite(relay2,LOW);  // secs = 14

  digitalWrite(relay3,HIGH); // secs = 59
  digitalWrite(relay4,HIGH); // secs = 61
  digitalWrite(relay3,LOW);  // secs = 71
  digitalWrite(relay4,LOW);  // secs = 73

I strongly recommend using millis() rather than delay() for anything but the most trivial program. delay() completely paralyses the Arduino until the period has elapsed. It is much easier to start a project with millis() than to convert later from delay() to millis() when the deficiencies of delay() emerge.

When using millis() you should always use subtraction so that there is no problem when millis() rolls over from 2^32 to 0. For example "if (millis() - prevMillis > interval) { }".

I wrote an extended demo of the Blink Without Delay technique in the first post in this Thread.


@Robin2 : yes, I understand the importance of using millis() (that's why I was trying to use it) and I had already read the thread you indicated even before I posted here. Thank you for your reply.

@Runaway Pancake's: your code just works!! Thank you very much!!!!

I won't abandon trying to work with millis() since I plan to add an emergency stop (in the form of an infrared sensor), but in the mean time I will have a working gate.

Thanks again to both.