need help understanding loop/while/for

This code is just for an example and I realize for the example the while loop is not necessary but it demonstrates a problem I cannot understand…
Can someone explain the reason each example works or doesn’t work… (and by “works” or not means it is printing 0-xxx to the serial monitor inside the for loop) (this is using a nano)

works

void setup() {
  Serial.begin(115200); 
}

void loop() {
  while (1) {
    for (byte i = 0 ; i < 127 ; i++) {
      Serial.println(i);
    }
  }
}

doesn’t work

void setup() {
  Serial.begin(115200);
}

void loop() {
  while (1) {
    for (byte i = 0 ; i < 128 ; i++) {
      Serial.println(i);
    }
  }
}

works

void setup() {
  Serial.begin(115200); 
}

void loop() {
  while (1) {
    for (int i = 0 ; i < 128 ; i++) {
      Serial.println(i);
    }
  }
}

works

void setup() {
  Serial.begin(115200); 
}

void loop() {
     for (byte i = 0 ; i < 128 ; i++) {
      Serial.println(i);
    }
}

Works/doesn't work for what definition of work?

A byte can hold a value in the range 0 to 255, so all the for loops should be functioning properly, stopping when they are supposed to.

The while loop is completely unnecessary, and is unrelated to whatever problem you are having.

The Serial class derives, indirectly, from Print() which supplies the print() and println() methods. There are not overloads for every possible type, so some types get promoted to other types. Sometimes that promotion causes problems.

PaulS:
Works/doesn't work for what definition of work?

I stated this in my original post "(and by "works" or not means it is printing 0-xxx to the serial monitor inside the for loop) "

PaulS:
A byte can hold a value in the range 0 to 255, so all the for loops should be functioning properly, stopping when they are supposed to.

Agreed

PaulS:
The while loop is completely unnecessary, and is unrelated to whatever problem you are having.

I know it is unnecessary and I stated that in the original post... "This code is just for an example and I realize for the example the while loop is not necessary but it demonstrates a problem I cannot understand... "
Removing the while loop causes the for loop to function correctly.

PaulS:
The Serial class derives, indirectly, from Print() which supplies the print() and println() methods. There are not overloads for every possible type, so some types get promoted to other types. Sometimes that promotion causes problems.

Vague but ok.

doesn't work

What exactly do you mean by this ?

UKHeliBob:
What exactly do you mean by this ?

I stated this in my original post "(and by "works" or not means it is printing 0-xxx to the serial monitor inside the for loop) "

freakdaddy:
I stated this in my original post "(and by "works" or not means it is printing 0-xxx to the serial monitor inside the for loop) "

That is still ambiguous. What does it print, if anything ?

This is fascinating. I can confirm that the OP’s “does not work” code does not work. It just prints an initial 0 and nothing else.

Interestingly it works fine if

  • you change the 128 to 127 or 129.
  • you change the < 128 to <= 128.
  • you comment out the WHILE loop.

The compiler seems to be having a bad-hair day :slight_smile:

By the way I added a delay(200) into my code to give a more human speed and to avoid the risk of the output buffer overflowing. All the examples behaved the same way with the delay() as without it.

…R

UKHeliBob:
That is still ambiguous. What does it print, if anything ?

In the case of it working it prints 0-126 or 127 each on a new line, depending on the example you run. In the case of it not working it prints “0” and that’s it.

Robin2:
This is fascinating. I can confirm that the OP’s “does not work” code does not work. It just prints an initial 0 and nothing else.

Interestingly it works fine if

  • you change the 128 to 127 or 129.
  • you change the < 128 to <= 128.
  • you comment out the WHILE loop.

The compiler seems to be having a bad-hair day :slight_smile:

By the way I added a delay(200) into my code to give a more human speed and to avoid the risk of the output buffer overflowing. All the examples behaved the same way with the delay() as without it.

…R

Correct. This is the exact behavior I see.

This is the exact behavior I see.

But not here. I see the expected printing of 0 to 127 which then repeats

Let's compare notes
I am using IDE version 1.8.5 with a Nano on Win10

IDE 1.8.5 with generic nano on linux. I'm going to test it with some other boards. Not being disrespectful but you are running the example marked "doesn't work" correct?

I did my tests with 1.8.6 and an Uno.

...R

Not being disrespectful but you are running the example marked “doesn’t work” correct?

Don’t worry about asking, we all make mistakes so I just tried it again.

I opened a new IDE sketch, selected the code in your example by clicking the [select] button for the code, right clicked on the selected code, chose copy from the right click menu, went back to the IDE, right clicked in the edit window, chose Select All from the right click menu, right clicked again in the edit window in which the original code was now selected and chose paste from the right click menu to paste in your code to replace the selected code, then clicked the Upload button in the IDE to compile and upload the code.

I already have the Serial monitor set to 115200 so once the upload was complete I opened the Serial monitor and saw the expected result

Here is the code copied back from my IDE using Copy for Forum

void setup() {
  Serial.begin(115200);
}

void loop() {
  while (1) {
    for (byte i = 0 ; i < 128 ; i++) {
      Serial.println(i);
    }
  }
}

and here is a small portion of the output in the Serial monitor

122
123
124
125
126
127
0
1
2
3
4

I have just tried the code on a genuine Uno and it works as expected and produces the same output

UKHeliBob:
Don't worry about asking, we all make mistakes so I just tried it again.

I opened a new IDE sketch, selected the code in your example by clicking the [select] button for the code, right clicked on the selected code, chose copy from the right click menu, went back to the IDE, right clicked in the edit window, chose Select All from the right click menu, right clicked again in the edit window in which the original code was now selected and chose paste from the right click menu to paste in your code to replace the selected code, then clicked the Upload button in the IDE to compile and upload the code.

Lol! That made my day!

Just downloaded 1.8.9 and used a genuine arduino mega 2560. Still fails.

Took my mega to a win10 laptop with 1.8.9. Fails.

Are we having fun yet ?

Frustrating I'll say.

the reason the while loop in your code appears to do nothing is because its doing the same thing that arduinos loop is doing. if you had other code below the while loop it wouldn’t do it. the while loop in your example is an infinite loop. anytime the condition is never met in the first brackets() of a while loop it just repeats the {} brackets forever. arduino’s loop() section is another infinite loop. soon as it hits the bottom it starts again at the top. so the while loop does the same as the loop() function. however if you did have other code below the while loop in your sketch. the whhile loop would prevent it from happening.

when you say while(1) its the same as saying while(1==1)… the {} brackets reapeat untill the () brackets are a false statement. so if you say while(1) or while (23=23) or while(moneys eat bannannas) you repeat forever.

about anything you can do in a “for” loop you can also do in a “while” loop

int i = 0;
while(i<128){
Serial.print(i);
i++;
}
Serial.print("other things");

this above code will print your numbers just the same because as i is counted up the condition is no longer true and the loop is broken. it will also continue to do other things afterwords.

while(1==1){

int i = 0;
while(i<128){
Serial.print(i);
i++;
}

}
Serial.print("other things");

this above code will never do other things. saying while(1) is the same as saying while(1==1).

while(analogRead(A0)>100){


Serial.print("pin zapped");

}

this loop will get stuck printing as long as you have voltage to a pin

With IDE 1.8.4 (avr-gcc 4.9.2) it works as expected. With IDE 1.8.8 (avr-gcc 5.4.0) it fails, prints 0, once. Must be another 5.4.0 bug. Use the 4.9.2 toolchain.