restart program?

Hey

for my project I'm making a countdown clock.
so it start at 24 and goes to 0.
But I also want to know how to reset the countdown to 24 (also when the clock is still counting down)
I don't know if there's some easy structure to restart my program.
I just want the countdown to restart when I press a button.

Can someone help me please?

Gilles

Are you wanting to just restart a timer in the serial monitor or an actual LCD ? I need more info

Seeing your current code would help (big hint), but how about reading the button state each time through loop() and if it is pressed resetting the time variable(s). If you are currently using delay() as part of your countdown timer then you will need to switch to the principle used in the BlinkWithoutDelay example in the IDE or the button will not be very quick to respond to a press.

If you write a function to do the reset then you can call it from setup() to do the initial time setting and when the button is pressed.

if (counter==0)
  counter=24;

take a look at the Library's
<Time.h>
<TimeAlarms.h>
you can call a alarm when you want to

Alarm.timerOnce(24, OnceOnly);             // called once after 24seconds

GillesVanGestel:
But I also want to know how to reset the countdown to 24 (also when the clock is still counting down)
I don't know if there's some easy structure to restart my program.
I just want the countdown to restart when I press a button.

Basically what you need to do is reset the variables that are holding your countdown state back to the value they had at the start of the countdown.

this is my code. At the moment it's only one led, but that doesn't matter I think.

const byte numeral[25] = // at the moment it's only one let, but that doesn't matter.
{
//ABCDEFGHI
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0
  B11110110, //9
  B11111110, //8
  B11100000, //7
  B10111110, //6
  B10110110, //5
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0
  B11110110, //9
  B11111110, //8
  B11100000, //7
  B10111110, //6
  B10110110, //5
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0      
};

int inputPin = 2;
int val = 0;
const int segmentPins [8] = { 11,10,9,8,7,6,5,4};

void setup()
{
  for (int i=0; i < 8; i++)
  {
    pinMode (segmentPins[i], OUTPUT); 
  }
  pinMode (inputPin, INPUT);
}

void loop()
{
  for (int i = 0; i <= 25; i++)
  {
    showDigit(i);
    delay (1000);
  }
}
void showDigit ( int number)
{
  boolean isBitSet;
  
  for (int segment = 1; segment < 8; segment++)
  {
    if (number < 0 || number > 24)
    {
      isBitSet = 0;
    }
    else
    {
      isBitSet = bitRead(numeral[number], segment);
    }
    //isBitSet = ! isBitSet; 
    digitalWrite( segmentPins[segment], isBitSet);
  }
  val = digitalRead(inputPin);
  if (val == HIGH)
    {
      //here I want to restart the program
    } 
}
  val = digitalRead(inputPin);
  if (val == HIGH)
    {
      //here I want to restart the program
    }

First, why is this in showDigit()? It should be in loop().

Second, what does "restart the program" mean? Anytime people try to figure out how to reset the Arduino in code, they are trying to solve the wrong problem.

If you want the timer to be reset to 0, say that. The delay() in loop() has to go. The blink without delay example will show you how to make something happen on a regular basis (show a new number) without making everything else stop, like delay() does.

The showdigit is something I got out of the 'arduino cookbook'.
I just want that when I press the button, that the code restarts from the top. Just that it starts the code all over and restarts counting down.

Just that it starts the code all over

Why do you need to execute the pinMode() calls over again?

Try something like this:

int counter = 24;
unsigned long lastTime = 0;
int lastState = LOW;

void loop()
{
   if(millis() - lastTime >= 1000)
   {
      if(counter >= 1)
         counter--;
      lastTime = millis();
   }

  showDigit(counter);

   currState = digitalRead(inputPin);
   if(currState != lastState && currState == HIGH)
   {
      counter = 24;
   }
   lastState = currState;
}

This will call showDigit() on every pass through loop. It will change the value shown only once a second. It will reset the counter value each time the switch transitions to pressed, not just when the switch IS pressed. So, you can start the program and the counter will count down. The value will be shown continuously. You can press and hold the switch, and the counter will reset to 24. It will continue to count down until you release and press the switch again.

I found it, I meant the return function....

GillesVanGestel:
I found it, I meant the return function....

What return function are you talking about?

just return, it restarts the whole program

const byte eersteLed[25] = 
{
//ABCDEFGHI
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0
  B11110110, //9
  B11111110, //8
  B11100000, //7
  B10111110, //6
  B10110110, //5
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0
  B11110110, //9
  B11111110, //8
  B11100000, //7
  B10111110, //6
  B10110110, //5
  B01100110, //4
  B11110010, //3
  B11011010, //2
  B01100000, //1
  B11111100, //0      
};
const byte tweedeLed[25] = 
{
//ABCDEFGHI
  B11011010, //2
  B11011010, //2
  B11011010, //2
  B11011010, //2
  B11011010, //2
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B01100000, //1
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0
  B11111100, //0      
};
const int eersteLedPins[8] = { 14,13,12,11,10,9,8,7};
const int tweedeLedPins[8] = { 14,6,5,4,3,2,1,0}; //poorten van Arduino die met de letter verbonden zijn
int knop24 = 5;
int val24 = 0;

void setup()
{
  for (int i=0; i < 8; i++)
  {
    pinMode (eersteLedPins[i], OUTPUT); //allemaal outputs maken, leds laten branden 
  }
  for (int j=0; j < 8; j++)
  {
    pinMode (tweedeLedPins[j], OUTPUT);
  }
  pinMode (knop24, INPUT);
}

void loop()
{
  for (int i = 0; i <= 25; i++)
  {
    showDigit(i);
    delay (1000);
    val24 = digitalRead(knop24);
      if (val24 == HIGH)
        {
          return;
        } 
  } 
  for (int j = 0; j <= 25; j++)
  {
    showDigit(j);
    delay (1000);
    val24 = digitalRead(knop24);
      if (val24 == HIGH)
        {
          return;
        } 
  }  
}
void showDigit ( int number)
{
  boolean isBitSet;
  
  for (int segment = 1; segment < 8; segment++)
  {
    if (number < 0 || number > 24)
    {
      isBitSet = 0; //alles uit
    }
    else
    {
      isBitSet = bitRead(eersteLed[number], segment);
    }
    //isBitSet = ! isBitSet; 
    digitalWrite( eersteLedPins[segment], isBitSet);
  }
  for (int segment = 1; segment < 8; segment++)
  {
    if (number < 0 || number > 24)
    {
      isBitSet = 0; //alles uit
    }
    else
    {
      isBitSet = bitRead(tweedeLed[number], segment);
    }
    //isBitSet = ! isBitSet; 
    digitalWrite( tweedeLedPins[segment], isBitSet);
  }
}

Now it always resets the counter to 24, but I also want it to reset to 14, I don't know if that's possible.

You have something that checks the button 1 time a second only.

PaulS handed you the key to real time multitasking and you go for clunky blocking code.

No, the return does not restart the program. It simply puts you back to the start of loop(), in a very weird way.
You actually don't want to restart the program. You want to reset the count, right?

Two things you should know.

  1. setup() is the first thing that runs, and it runs only once.
  2. loop() is the next thing that runs, and it will keep running, over and over again.

So, the only thing you need to do to restart the count is to break out of the for loop. Give this a try:

void loop()
{
  for (int i = 0; i <= 25; i++) {
    showDigit(i);
    delay (1000);
    val24 = digitalRead(knop24);
    if (val24 == HIGH) {
      break;
    } 
  } 
}  
}

What happens? Well, you are counting up to 25, showing the count, reading the switch. You will do this 25 times, then loop() will start again, starting with the for loop.

If you press the switch (assuming you have it wired correctly), you will execute the break statement, which will drop you out of the for loop, and your loop() will start again.

It's still going to have a variable-lag response due to the delay().

GoForSmoke:
It's still going to have a variable-lag response due to the delay().

Of course, but I wanted to address one thing at a time.

lar3ry, the break function worked. I also found that when I put i = -1 it also restarts. What do you think is the best?

GillesVanGestel:
lar3ry, the break function worked. I also found that when I put i = -1 it also restarts. What do you think is the best?

In general, it's better to use symbolic values or statements that describe what's happening than to do things like messing with the loop counter. Yes, there are times when you might find it easiest to change the value of a loop counter, but when there's no need to, why bother? The break statement is a standard C statement that is as clear as you are going to get, to describe what the code is doing. it says "break out of the current code block, whether it be a for, a while or an if".

I want to show you something about readability of code...

Have a look at these two examples:

void loop(){
  for (int i = 0; i <= 25; i++) {
    showDigit(i);
    delay (1000);
    if (digitalRead(knop24) == HIGH) {
      break;
    } 
  } 
}
void loop(){
  for (int i = 0; i <= 25; i++) {
    showDigit(i);
    delay (1000);
    if (digitalRead(knop24)) {
      break;
    } 
  } 
}

These are exactly equivalent. In the first example, we are reading the state of the switch, and testing to see if it's HIGH. HIGH is defined as 1, so we could use 1 instead of HIGH, but HIGH tells us that we are looking for a HIGH on that pin, so that many days or weeks or months later, if we are looking at our code in order to change it, upgrade it, or even fix a problem, we will find the HIGH to be more helpful in understanding the operation.

In the second case, we are taking advantage of the facility in the compiler that makes true and 1 equivalent, and are doing away with the test on the variable. In this case it's a good thing we are, because the variable has a horrible name, having nothing to do with the value 24. So, the second example says "if the value read from pin knop24 is true (equivalent to 1 or equivalent to HIGH), then break (out of the for loop). But again, it might be a little less clear a month down the road, when you are looking at your code, and if there's one thing you really want to strive for, it's clarity in your code.

Now that it's working, you can concentrate on testing the switch more often, in order to minimize the chance of missing the switch transition while you Arduino is busy doing nothing but waiting for the delay to end. Check that link you were given to see how.

After that, you can figure out how to reset it to a different number, and to figure out how to count down instead of up, how to the intended number instead of 1 higher, etc.