Decrementing for loop never ending for some reason

I am trying to make a countdown timer for my gym sessions. I am using an arduino nano, buzzer, push button and 4 digit 7-segment display.

The issue arises in my for loop when I am trying to increment through each digit and display the time left. I am new to coding in arduino so I must be doing something wrong as the for loop does not even decrement once, as I can tell from my serial.print commands.

I know my code is actually not even producing a functioning timer outside of the erroneous for loop, but I hope to fix the rest after.

The loop is the second loop in the nest. Lastly, the custom functions turn on and off the LEDs and are proven to work as they were pulled from a tutorial.

void loop() {
  // put your main code here, to run repeatedly:
  int L = 0;
  if (t > 999) {
    L = 4;
    Serial.println("Time has 4 digits");
  }
  else if (t > 99) {
    L = 3;
    Serial.println("Time has 3 digits");
  }
  else if (t > 9) {
    L = 2;
    Serial.println("Time has 2 digits");
  }
  else {
    L = 1;
    Serial.println("Time has 1 digits");
  }
  Serial.println(L);
  for (int i = t; i > 0; i--) {
    Serial.print("Begining Loop 1, time left = ");
    Serial.flush();
    Serial.println(i);
    Serial.flush();
    for (int l = L; l > 0; l--) {
      Serial.println("Beginning Loop 2");
      Serial.flush();
      Serial.print("l = ");
      Serial.flush();
      Serial.println(l);
      Serial.flush();
      clearLEDs();
      pickDigit(5 - l);
      Serial.print("Digit picked is ");
      Serial.flush();
      Serial.println(5 - l);
      Serial.flush();
      //int disp = String(t).charAt(L-l);
      unsigned disp = int((t / pow(10, float(l) - 1))) % 10;
      Serial.print("disp =");
      Serial.flush();
      Serial.println(disp);
      Serial.flush();
      pickNumber(disp);
      Serial.println(l);
      Serial.flush();
    }
    delay(1000);
  }
}

Thanks in advance!

Can you post your entire sketch? It will be hard to know what the problem is without knowing what t and L are entering the loop and if pickNumber() is causing any side effects.

yeah, my bad. Thanks for looking into it :slight_smile:

const int a = 12;
const int b = 10;
const int c = 8;
const int d = 7;
const int e = 6;
const int f = 11;
const int g = 9;
int p = 0;

int startStopReset = 13;

const int d1 = 1;
const int d2 = 2;
const int d3 = 3;
const int d4 = 4;

long t = 30; //start time -> CAN CHANGE TO WHATEVER TIME YOU WANT
int x = 100;
int del = 55; //delay value
//int L = length(String(t));

void setup() {
  // put your setup code here, to run once:
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(p, OUTPUT);
  pinMode(startStopReset, INPUT);
  digitalWrite(startStopReset, HIGH);

  Serial.begin(9600);
  Serial.println("Setup Done");
}

void loop() {
  // put your main code here, to run repeatedly:
  int L = 0;
  if (t > 999) {
    L = 4;
    Serial.println("Time has 4 digits");
  }
  else if (t > 99) {
    L = 3;
    Serial.println("Time has 3 digits");
  }
  else if (t > 9) {
    L = 2;
    Serial.println("Time has 2 digits");
  }
  else {
    L = 1;
    Serial.println("Time has 1 digits");
  }
  Serial.println(L);
  for (int i = t; i > 0; i--) {
    Serial.print("Begining Loop 1, time left = ");
    Serial.flush();
    Serial.println(i);
    Serial.flush();
    for (int l = L; l > 0; l--) {
      Serial.println("Beginning Loop 2");
      Serial.flush();
      Serial.print("l = ");
      Serial.flush();
      Serial.println(l);
      Serial.flush();
      clearLEDs();
      pickDigit(5 - l);
      Serial.print("Digit picked is ");
      Serial.flush();
      Serial.println(5 - l);
      Serial.flush();
      //int disp = String(t).charAt(L-l);
      unsigned disp = int((t / pow(10, float(l) - 1))) % 10;
      Serial.print("disp =");
      Serial.flush();
      Serial.println(disp);
      Serial.flush();
      pickNumber(disp);
      Serial.println(l);
      Serial.flush();
    }
    delay(1000);
  }
}

void pickDigit(int x) //changes digit
{
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);

  switch (x)
  {
    case 1:
      digitalWrite(d1, LOW);
      break;
    case 2:
      digitalWrite(d2, LOW);
      break;
    case 3:
      digitalWrite(d3, LOW);
      digitalWrite(p, HIGH); //new
      break;
    default:
      digitalWrite(d4, LOW);
      break;
  }
}

void pickNumber(int x) //changes value of number
{
  switch (x)
  {
    default:
      zero();
      break;
    case 1:
      one();
      break;
    case 2:
      two();
      break;
    case 3:
      three();
      break;
    case 4:
      four();
      break;
    case 5:
      five();
      break;
    case 6:
      six();
      break;
    case 7:
      seven();
      break;
    case 8:
      eight();
      break;
    case 9:
      nine();
      break;
  }
}

void dispDec(int x)
{
  digitalWrite(p, LOW);
}

void clearLEDs()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(p, LOW);
}

void zero()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void one()
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void two()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}

void three()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}

void four()
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void five()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void six()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void seven()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void eight()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void nine()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

You've got some fine serial debug statements in there. Can you please post the serial output here?

I'm not really sure what you are trying to do here, but the value of t is not changing anywhere within your nested for loops, so you will always display the save number.

      unsigned disp = int((t / pow(10, float(l) - 1))) % 10;

david_2018:
I'm not really sure what you are trying to do here, but the value of t is not changing anywhere within your nested for loops, so you will always display the save number.

      unsigned disp = int((t / pow(10, float(l) - 1))) % 10;

Wow, making the time decrease at the end was actually it, I think I overlooked it because I thought the error was contained within the nested loop, where I meant to simply change digit and display number, for a given static time.
Thanks!!
Now I just need to adjust the timings of how the numbers will be displayed.

aarg:
You've got some fine serial debug statements in there. Can you please post the serial output here?

Haha yeah, I'm used to Matlab and having that kind of feedback lol. But it's sorted for now, thank you.

You could vastly reduce the size of your code if you use arrays for pins and pin states.

@op.
this statment:
if (t > 999) {
L = 4;
Serial.println("Time has 4 digits");
}
else if (t > 99) {
L = 3;
Serial.println("Time has 3 digits");
}
else if (t > 9) {
L = 2;
Serial.println("Time has 2 digits");
}

I believe this logic is "incorrect"
if t>999 all the three conditions are true and will be executed.
if t>99 the second and the third one are and ...
and so on.

No. Look up what “else” means in this context.

a7

abdelhmimas:
I believe this logic is "incorrect"
if t>999 all the three conditions are true and will be executed.
if t>99 the second and the third one are and ...
and so on.

Nope. That would be the case if there were "if"s rather than "else if"s.

ToddL1962:
Nope. That would be the case if there were "if"s rather than "else if"s.

So what would happen if t>999
I am still confused

It would print

Time has 4 digits

to the serial monitor.

Srsly, you need to look into this if/else thing a bit.

HTH

a7

Here I googled it for you

Java, sry, but it all applies in most languages.

a7

alto777:
Here I googled it for you

Java If else - Javatpoint

Java, sry, but it all applies in most languages.

a7

I followed the link and it is exactly what I understood.
Let me explain:
If t>999
The first test will be true, and will be executed
If t>999 it is also >99
The second test will be true and executed
If t>999 it is also > 9
.....

That is my point

abdelhmimas:
I followed the link and it is exactly what I understood.
Let me explain:
If t>999
The first test will be true, and will be executed
If t>999 it is also >99
The second test will be true and executed

No, it won't. I suggest you just go an test it. You'll see.

Let me explain:
If t>999
The first test will be true, and will be executed
If t>999 it is also >99
The second test will be true and executed
If t>999 it is also > 9

It has been said several times, the if/else construct prevents this. When a condition is true the code skips the rest of the tests.

See this reference
https://www.arduino.cc/reference/en/language/structure/control-structure/else/

Each test will proceed to the next one until a true test is encountered. When a true test is found, its associated block of code is run, and the program then skips to the line following the entire if/else construction.

cattledog:
It has been said several times, the if/else construct prevents this. When a condition is true the code skips the rest of the tests.

See this reference
else - Arduino Reference

You are right, apologize. Was clear in this link
Thanks also alto

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.