Returning To Setup After Pressing Button

I’m currently working on a toy car drag race system. The program works but I have to reset each time the race is finished. I am trying to find a way where when you press the button, it returns to the setup and the program runs again. Any help would be appreciated.

Here is the code I have

#include<LiquidCrystal.h>
#include<Servo.h>

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
Servo startingGate;

const byte buttonPin = 5;
const byte servoPin = 4;
const byte finishSensor1Pin = A0;
const int darkThreshold = 900;

int finishSensor1;
boolean finishFlag = false;
long startTime;
long stopTime;
float raceTime;

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);

  startingGate.attach(servoPin, 1000, 2000);
  startingGate.write(0);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("Car #1 Timer");
  lcd.setCursor(0, 1);
  lcd.print("Push to start");

  while (digitalRead(buttonPin) == HIGH)
  {
  }

  lcd.clear();
  lcd.print("Go!");

  startingGate.write(180);
  startTime = millis();
}

void loop()
{
  finishSensor1 = analogRead(finishSensor1Pin);
  if ((finishFlag == false) && (finishSensor1 < darkThreshold))
  {
    finishFlag = true;
    stopTime = millis();
    raceTime = stopTime - startTime;
    lcd.clear();
    lcd.print("Car 1 Time:");
    lcd.setCursor(0, 1);
    lcd.print(raceTime / 1000, 3);
    lcd.print(" Seconds");
   
    }

  }

I don’t see anything special about what setup() is doing that needs doing again. You COULD wait for the switch to be pressed again, in loop(), wherever that is appropriate.

Or... if setup() is so important, simply put the button across the RESET pin ?!

There are four active tasks in the setup() –

  1. Servo position at 0.
  2. And then to position servo at 180 after sensing the active condition of the Button.
  3. Cursor position at 0 of line-2
  4. Display of the Go! message (to indicate beginning of game).

Seems like wiring the button to the RESET pin is the most reasonable solution.

In ASM Programming, we can interrupt the MCU over INT0-pin. From the ISRINT0 interrupt subroutine, we can force the MCU to begin execution at Reset Vector - 0x0000 by manipulating the Stack and the Return Address.

Can the similar things be done in C/C++?

Simple shortcut is using the WDT

Put this portion of code

  startingGate.write(0);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("Car #1 Timer");
  lcd.setCursor(0, 1);
  lcd.print("Push to start");
  while (digitalRead(buttonPin) == HIGH)
  {
  }
  lcd.clear();
  lcd.print("Go!");
  startingGate.write(180);
  startTime = millis();

In its own function and remove it from setup(). Call the new function from setup() and at any time that you wish to reset the system to its start state

What @UKHeliBob has suggested seems like the best option.

However setup() is just a regular function and your code could call it any time it wishes. Note, however, that calling setup() does not mean that the whole Arduino resets.

...R

UKHeliBob:
[put]... In its own function and remove it from setup(). Call the new function from setup() and at any time that you wish to reset the system to its start state

That's the "right"way, I'd say.

(Yes, I know, any way that works is a right way, but some ways are righter :wink: )

Robin2:
However setup() is just a regular function and your code could call it any time it wishes. Note, however, that calling setup() does not mean that the whole Arduino resets.

What we (me and my co-workers; others are excluded) see in an Arduino sketch are the setup(){} and loop(){} functions. Program execution begins from setup()function. ATmega328P also begins program execution from the Reset Vector (0x0000 or Boot Section). At conceptual level, are they not equivalent?

Program execution begins from setup()function.

Actually it doesn’t
Here is what runs when the Arduino is started or reset

/*
  main.cpp - Main loop for Arduino sketches
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
 init();

 initVariant();

#if defined(USBCON)
 USBDevice.attach();
#endif
 
 setup();
    
 for (;;) {
 loop();
 if (serialEventRun) serialEventRun();
 }
        
 return 0;
}

GolamMostafa:
Program execution begins from setup()function.

It doesn't, actually. It starts (invisibly to we mere humans) in main() which if my memory serves me runs init() or something before it calls setup(). So it's conceivable that there could be something in main() or init() which would run with a reset, but not with a call to setup().

(edit: as UKHeliBob said)

Plus a reset / power-on may do some hardware stuff which setup() won't, I wouldn't know.

GolamMostafa:
What we (me and my co-workers; others are excluded) see in an Arduino sketch are the setup(){} and loop(){} functions. Program execution begins from setup()function. ATmega328P also begins program execution from the Reset Vector (0x0000 or Boot Section). At conceptual level, are they not equivalent?

Not quite.

When power is applied to an Arduino (or the Reset button is pressed) the hidden function main() starts and calls various background initialisation functions. Then it calls setup() and when setup() finishes it calls loop() repeatedly.

Calling setup() from within a program misses out all the initialisation stuff.

In short, when an Arduino restarts setup() gets called. But when setup() is called the Arduino does not get restarted.

…R

Robin2:
Note, however, that calling setup() does not mean that the whole Arduino resets.

Robin2:
In short, when an Arduino restarts setup() gets called. But when setup() is called the Arduino does not get restarted.

Now, I have understood (to a greater extent) the meaning of the 'top quote' from the 'information' of 'bottom quote'.

Reset/Restart begins from main(), init(), ..., setup() (whole Arduino Reset). Calling setup(), from some other section of the sketch, by-passes main(), init(), ..., -- hence, the Arduino does not get restarted.

elvon_blunden:
It doesn't, actually. It starts (invisibly to we mere humans) in main()

...and before main is crt0.
Quite important, that one.

AWOL:
...and before main is crt0.

I'm game: what's that?

elvon_blunden:
I'm game: what's that?

You know all those globals and statics that get zeroed, or set to some other specific initial value?

Ever wonder how that happens?

AWOL:
You know all those globals and statics that get zeroed, or set to some other specific initial value?
No

Ever wonder how that happens?
Didn't know about them, so "no" to that too.

But I'm happy to hear that they do get initialised, given they exist :wink:

AWOL:
You know all those globals and statics that get zeroed, or set to some other specific initial value?

Ever wonder how that happens?

To accomplish those initialization, there are needed some executable instructions. Are those codes lie outside the so called main() function?

In DOS OS/Programming, we came to know something called 'Kernel' -- the tiny ROM-based codes that got executed before the Boot Loader was called upon and then the DOS.