Counting backwards from 100 to 0 stops at 55

Status
Not open for further replies.

heyjudemw

Member
Hi forum! I'm trying to learn from a book that recommends trying to count backwards from 100 to zero using the serial monitor. I tried:
Code:
void setup() {
  for (int index = 100; index > -1; index--)
  {
    Serial.print ("index: ");
    Serial.println (index);
  }

}

void loop() {
}

but Serial Monitor only counted down until it reached 55:
...
16:00:15.210 -> index: 57
16:00:15.210 -> index: 56
16:00:15.210 -> index: 55
16:00:15.210 -> index

If "index > -1 " is replaced with any number up to 41 (for example "index > 26" or "index > 41"), it still only counts down to 55
HOWEVER
if I use "index > 42" or any number between 42-53, The serial monitor will count down past 55 until it reaches the number.

For example:
Code:
void setup() {
  for (int index = 100; index > 42; index--)
  {
    Serial.print ("index: ");
    Serial.println (index);
  }

}

void loop() {
}

yields:
...
16:02:20.107 -> index: 45
16:02:20.107 -> index: 44
16:02:20.107 -> index: 43

1. Why is it stopping at 55 when using numbers below 42?
2. Why do numbers 42-53 allow me to go lower than 55 while numbers lower than 42 do not?
3. How do I get serial monitor to count down to 0?

Thanks!

P.S. Is it a coincidence that 42 is the answer to the meaning of life, the universe, and everything?
 
Might help to know more about your setup, like which teensy, and what computer are you running this too? Windows? Mac? Linux? ...

The problem is more typically on the host side where that fast of output, is overflowing the hosts serial handling. There have been a few different threads recently about high speed serial problems for the different platforms.

If you just want to get this to work, try putting in a delay. Like:
Code:
void setup() {
  for (int index = 100; index > 42; index--)
  {
    Serial.print ("index: ");
    Serial.println (index);
    delay(100);
  }

}

void loop() {
}
 
Thanks for the reply, Kurt. I'm using a Teensy 3.2 on macos 10.13.3.

BTW I just repeated the test counting up and got:
...
16:26:45.560 -> index: 46
16:26:45.560 -> index

which is the same number of lines as 55 counting down.
 
I tried the delay and it successfully counted all the way down to 0. Weird. How can I avoid that? What's really weird is that I just did this without delay and got to a million, no problem:
Code:
void setup() {
  for (int index = 0; index < 1000001; index++)
  {
    Serial.print ("index: ");
    Serial.println (index);
    //delay (100);
  }

}

void loop() {
}

But When I count to 100 it stops at 46. Weird.
 
Try adding these three statements at the beginning of the setup function.
Code:
  Serial.begin(9600);
  while(!Serial);
  delay(1000);

Pete
 
Hi el_supremo, thanks for the reply. I tried those 3 statements individually to see what effect each would have.

"Serial.begin(9600)" didn't change anything and I did verify that the baud rate matched.

Delay(70) was the minimum that resulted in every number being printed. That's great for counting to 100 but counting to 500,000 is pretty slow

while(!Serial) worked amazingly well. Wow. Serial almost instantly printed every number asked for. Why is that? What is that function? Is there a setting in Arduino IDE that would solve this or do I need to use that function whenever I do this sort of thing?
 
The Teensy ARM hardware has NATIVE 12 Mbps USB hardware - so that baud rate in the .begin() is just for looks and compatibility.

The while(!Serial) just waits for Teensy to establish a USB connection to the host computer before starting.

Once it is connected it runs at full USB 12 Megabit speed, and that typically overwhelms the Serial Monitor which means it cannot print everything the Teensy sends it.

I didn't try this on your sketch but how does this run:
Code:
void setup() {
  for (int index = 0; index < 1000001; index++)
  {
     if ( Serial.availableForWrite() > 15 ) {
       while(!Serial);
       Serial.print ("index: ");
       Serial.println (index);
     }
  }
}

void loop() {
}
 
Hi defragster, thanks for the info. I tried the code you wrote and got the first time:
...
18:35:27.865 -> index: 191497
18:35:27.865 -> index: 191498
18:35:27.865 -> index: 191499
18:35:27.865 -> index: 191500

then the second time:
...
18:38:58.095 -> index: 50528
18:38:58.095 -> index: 50529
18:38:58.095 -> index: 50530
18:38:58.095 -> index: 50531

Both times it stopped far short of 1,000,000 which was not originally a problem. When "index < 101" which was the original problem, I get:
...
18:40:44.095 -> index: 0
18:40:44.095 -> index: 1
18:40:44.095 -> index: 2
18:40:44.095 -> index: 3
18:40:44.095 -> index: 4
 
Yeah something very not right there.

My code was supposed to do something like this …
Code:
void setup() {
	pinMode(LED_BUILTIN, OUTPUT);
	while (!Serial); // here
	int index = 0;
	// while ( index < 1000001)
	while ( index < 10001)
	{
		if ( Serial.availableForWrite() > 20 ) {
			if ( !(index % 20) ) Serial.print (" X >>>>");
			Serial.print ("index: ");
			Serial.println (index);
			index++;
		}
		else delayMicroseconds(20);
		//else delayMicroseconds(2000);
	}

	while (1)
		digitalWriteFast( LED_BUILTIN, !digitalReadFast( LED_BUILTIN ) );
}

void loop() {
}

As shown it FAILS - but I don't think it should. It did finish to 10,000 one time out of 5 and two times stalled under 400.
> The Printing Stops
> It does not activate the LED even after waiting

It can get this far then halts:
...
index: 9737
index: 9738
index: 9739
X >>>>index: 9740
index: 9741
index: 9742
index: 9743
index: 9744
or:

index: 372
index: 373
index: 374
index: 375
index: 376
index: 377

If this line "else delayMicroseconds(20);" is commented and the other one uncommented it seems to be running on and on so far … I stopped it here:
Code:
…
index: 559419
 X >>>>index: 559420
index: 559421
index: 559422
index: 559423
index: 559424
...

I used delayMicroseconds() because it doesn't call out to yield(). Though adding a yield(); doesn't help.
 
Looks like 2 separate issues here.

Printing before the serial monitor is ready is doing weird things. Still not sure why, but it's been reported on other systems too, worst problems for Raspberry Pi.

Looks like something is also wrong with Serial.availableForWrite(). I've added this to my list of bugs to investigate.
 
Looks like 2 separate issues here.

Printing before the serial monitor is ready is doing weird things. Still not sure why, but it's been reported on other systems too, worst problems for Raspberry Pi.

Looks like something is also wrong with Serial.availableForWrite(). I've added this to my list of bugs to investigate.

I was surprised - when I wrote it properly in a while() that it didn't behave as expected. Posted similar code on the T4 Beta thread - based on recent posts there - in case it helps when looking there to refine the USB code - except on T4 it goes a few times too many faster and for now won't run without this mod for now: if ( 1) { // Serial.availableForWrite() > 20 ) {

So this on T_3.6's Serial might be easier to see - I did it BTW at 256 MHz of course.

Indeed printing before Serial True seems to fill/hold some buffered data - at least on T4 - but not clear on typical or best T_3.x behavior. I have posted T4 sketches where while( !Serial ) Serial.print( millis() ); did show times up to that going TRUE and progressed from there normally..
 
Status
Not open for further replies.
Back
Top