Go Down

Topic: While loop causing Serial.print output errors (Read 2207 times) previous topic - next topic

_Leo_

Everyone,

I've got something I can't figure out....

If I use this code:

Code: [Select]
void setup()
{
}

void loop()
{
    Serial.begin(9600);   
    delay(100);
    Serial.println("Test 1 2 3 ....");
    Serial.end();
}


I get clean output:

Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....


however if I use this:

Code: [Select]
void setup()
{
}

void loop()
{
  while(1)
  {
    Serial.begin(9600);   
    delay(100);
    Serial.println("Test 1 2 3 ....");
    Serial.end();
  }
}


or

Code: [Select]
void setup()
{
  while(1)
  {
    Serial.begin(9600);   
    delay(100);
    Serial.println("Test 1 2 3 ....");
    Serial.end();
  }
}

void loop()
{
}


I get errors in output:

Test 1 2 3 ....
Test 1 2 3 ....áTest 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....áTest 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....áTest 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....áTest 1 2 3 ....
Test 1 2 3 ....
Test 1 2 3 ....

Why is that?


Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de

jraskell

I'm not seeing the errors when I run your code, but try putting a small delay (delay(1)) after Serial.end();  There's a bit more overhead in repeatedly calling loop() then in a while loop (the loop() call itself is actually in a while loop of it's own).  So there may be a potential timing issue there.

AWOL

Which IDE are you using, and why keep intialising the serial port?
"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

PaulS

Why are you calling Serial.end()? Why are you calling Serial.begin() in loop()? Neither of those functions is quick/cheap.

There are, obviously, things that happen in main(), between calls to loop() that affect Serial. By not allowing the program to return to main, you prevent those things from happening.
The art of getting good answers lies in asking good questions.

_Leo_


I'm not seeing the errors when I run your code, but try putting a small delay (delay(1)) after Serial.end();  There's a bit more overhead in repeatedly calling loop() then in a while loop (the loop() call itself is actually in a while loop of it's own).  So there may be a potential timing issue there.


jraskell, thank you so much. Always these little and simple bits that keep holding me up.

The following did the trick.

Code: [Select]
void setup()
{
  while(1)
  {
    Serial.begin(9600);   
    delay(10);
    Serial.println("Test 1 2 3 ....");
    Serial.end();
    delay(5);
  }
}

void loop()
{
}
Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de

WizenedEE

There was a post a few days ago about how Serial.end() has a small bug -- it doesn't wait for the last one or two characters to be sent before ending. That's probably the problem.

_Leo_


There was a post a few days ago about how Serial.end() has a small bug -- it doesn't wait for the last one or two characters to be sent before ending. That's probably the problem.


Thank you for the tip. That would make sense. Workaround is to add a delay. Atleast that's what's working for me atm.

Side note: I'm using IDE 1.0.1
Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de

bperrybap

But if you simply moved the Serial.begin() to setup() and eliminated the Serial.end()
you wouldn't run into the issue.

--- bill

_Leo_


But if you simply moved the Serial.begin() to setup() and eliminated the Serial.end()
you wouldn't run into the issue.

--- bill


Yes, but then my Arduino project would fail. I'm beyond the point of simply printing out "Hello world..."  :)
Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de

bperrybap



But if you simply moved the Serial.begin() to setup() and eliminated the Serial.end()
you wouldn't run into the issue.

--- bill


Yes, but then my Arduino project would fail. I'm beyond the point of simply printing out "Hello world..."  :)


Huh? You are going to have to explain that one.
Why do you need to shutdown the USART continually re-initialize it?
Unless you using some deep sleep modes in the AVR
or you are doing something unusual like trying to share the UART pins with some other function or changing
baud rates on the fly, I see no need to continually call the code to re-initialize the USART, which has
to perform calculations and re-write clocking divisors, etc...

The reason you were seeing the corrupted transmission is because you were reprogramming the USART
clock registers while the USART was still transmitting.
This occurred because of the weak/poor code in HardwareSerial flush() and end() doesn't properly wait
for the last character to be fully transmitted.
It only waits for the s/w buffers to empty.
There can be up to 2 characters still remaining to be transmitted inside the USART after flush() or end() return
- 1 in the data register
- 1 in the shift register being transmitted.

If your code must really know when the characters are fully sent,
you must wait 2 character times after you call Serial.flush()
The delay time will be dependent on the baud rate but can easily be calculated.

--- bill


_Leo_

Bill, thanks for the detailed explanation.

The code I posted was only a simple example.

In essence, the serial port needs to be active only when Processing communicates with the Arduino. At all other times the ports need to be deactivated because the Rx & Tx pins are needed for other duties.
Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de

PaulS

Quote
In essence, the serial port needs to be active only when Processing communicates with the Arduino.

How do you know, on the Arduino, when Processing is about to talk to it, so you can enable the UART in time?

What are all the other pins doing? Perhaps an Arduino with more pins, or multiplexing is more appropriate.
The art of getting good answers lies in asking good questions.

Go Up