Arduino: Unwanted delay & "0" after Serial.parseInt

  • Thread starter Swamp Thing
  • Start date
  • Tags
    Arduino
In summary, the article discusses an issue encountered with Arduino's `Serial.parseInt()` function, where an unwanted delay and a "0" value are returned under certain conditions. This problem typically arises due to the way the function handles input data, particularly when no valid integer is available. The article offers troubleshooting tips, including ensuring proper input formatting and checking for any stray characters that could interfere with parsing. It emphasizes the importance of managing serial communication effectively to avoid such delays and errors.
  • #1
Swamp Thing
Insights Author
970
670
This Arduino sketch is supposed to wait for a number and then print it back with a message. But for some reason its gets an extra "0" from the TTY each time I actually type a number. There is about half second delay before the "0" is responded to.
Code:
int num;
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
}

void loop() {
Serial.print("Enter a number: ");
while(Serial.available()==0){}
num=Serial.parseInt();
//Serial.parseInt();           //    <----  Tried reading and discarding the "0". Well, that works -- but the delay remains.
Serial.println(num);
Serial.print("Your number is: ");
Serial.println(num);
Serial.println("=====\n");
}

Here is what happens in the TTY:
Code:
Your number is: 1
=====

Enter a number: 0
Your number is: 0
=====

Enter a number: 22
Your number is: 22
=====

Enter a number: 0
Your number is: 0
=====

Enter a number:

I can read and discard the "0" as per the commented line #11 --- but that doesn't remove the small delay.

How can I get rid of the extra delay?
 
Last edited:
Technology news on Phys.org
  • #2
I think it has to do with this:
https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/ said:
  • Parsing stops when no characters have been read for a configurable time-out value, or a non-digit is read;
  • If no valid digits were read when the time-out (see Serial.setTimeout()) occurs, 0 is returned;
I'm not familiar with Arduino, but while(Serial.available()==0){} seems to be a weird statement. An if(Serial.available()>0) seems to be more appropriate somewhere inside a loop.
 
  • Like
Likes Swamp Thing
  • #3
I'm not familiar with Arduino Serial.available. Do you enter a carriage return after the number and is it handling a carriage return as you expect?
 
  • #4
If I put a LF, CR, or CR+LF or even any non-numeric like "Q" at the end, then the response is immediate ("Your number is 125"). This is followed by a delay before prompting for the next input. The "0" thing does not happen in this case. So it doesn't seem to care whether the number is terminated by a CR, CRLF or something else -- it just responds to the numeric part BUT delays the prompt for the next number. This would be the acceptable option if the delay didn't matter. But I will be having Python talking to the Arduino at some stage, and the delays wouldn't be nice then.

If I don't put any terminating character, the delay happens before the response. After the required response it asks for the next input right away, gets a "0" and responds to that, and finally asks for the next actual input. This would also be somewhat acceptable for manual interaction if we added the read-and-discard line, but not so good for programmatic data exchange.

I think I will try inputting the number as a string and then converting it to integer. I will post back later how this works out.
 
  • #5
If the input device is an actual TTY (TeleType machine), try cleaning the commutator (serializer) in it. Also check for dirty or intermittents in the connecting cables between there and the computer.
 
  • #6
It's just a virtual TTY window within the Arduino IDE :smile:

Maybe TTY is a misnomer here, my bad.

The connection is actually via USB and gets converted to plain vanilla serial lines in an IC on the Arduino PCB.
 
  • #7
OK. I would suspect the extra Zero may be sent by the transmitting device then, perhaps as an End-Of-Message character. Is there any way of checking; perhaps in assembly language?

Cheers,
Tom
 
  • #8
Just found these lessons -- maybe the right method is explained here. I'll update after watching and trying his tips.

Using an Arduino with Python LESSON 1: Introduction, Prerequisites and Class Gear​


 
  • Like
Likes FactChecker
  • #9
Based on the video...
The key point is to use Serial.readStringUntil('\r') which waits for a CR.
jack action said:
but while(Serial.available()==0){} seems to be a weird statement. An if(Serial.available()>0) seems to be more appropriate somewhere inside a loop.
The video also uses while which is funny, given that's it's already within a polling loop.
Based on jack action's suggestion I changed it to an if.

So this is the code that works nicely without the delay and the "0" thing...
Code:
String cmd;

void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(13,OUTPUT);
Serial.println("Waiting for Input...");

}

void loop() {
  // put your main code here, to run repeatedly:

//while(Serial.available()==0){}   // blocks the polling loop --- bad!
if(Serial.available())        // won't block the loop (thanks, jack action!)
{

    cmd=Serial.readStringUntil('\r');
    Serial.println(cmd);
    if(cmd=="ON")
        {digitalWrite(13,HIGH);}
    else
        {digitalWrite(13,LOW);};

}
 
  • Like
Likes jack action and FactChecker
  • #10
The parseInt() function has a timeout (which can be set). I guess it defaults to about half a second. When you enter a number and hit return you send a number plus some sort of line termination, probably CRLF. The parseInt() function handles the number part fine and then chokes for half a second on the non-numeric part.

You can kludge by adding this code right after the parseInt() call:

Code:
while (Serial.available()) Serial.read();

That will work okay as long as you are just a human typing at human speed. But a better method would be to read the characters into a buffer using Serial.read() and then parse the buffer.

Then again, for a simple sketch it's often the case that a quick and dirty solution actually is better since it will save you a lot of time. But it might be instructive to learn to do it the "proper" way.

Good luck!
 
  • Like
Likes Swamp Thing

FAQ: Arduino: Unwanted delay & "0" after Serial.parseInt

Why am I experiencing unwanted delay in my Arduino code?

Unwanted delay in Arduino code can occur due to various reasons such as using delay() function excessively, inefficient code structure, or blocking operations. It is recommended to use non-blocking techniques like millis() function for timing instead of delay() to avoid unwanted delays.

Why do I get a "0" value after using Serial.parseInt() in Arduino?

The "0" value after using Serial.parseInt() in Arduino can occur if there is no valid integer value present in the serial input buffer. Make sure that the serial input contains only numerical values and check for any leading or trailing characters that may affect the parsing process.

How can I troubleshoot and debug unwanted delays in my Arduino code?

To troubleshoot and debug unwanted delays in Arduino code, you can use serial communication to print debug messages at different points in your code. This can help you identify the specific sections causing delays and optimize them accordingly. Additionally, you can use tools like Serial Monitor or a logic analyzer to analyze the timing of your code execution.

Is there a way to optimize my Arduino code to reduce unwanted delays?

Yes, there are several ways to optimize Arduino code to reduce unwanted delays. Some of the techniques include using non-blocking code structure, minimizing the use of delay() function, optimizing loops and conditional statements, and avoiding unnecessary operations that can cause delays. By following best coding practices and optimizing your code, you can significantly reduce unwanted delays in Arduino projects.

How can I improve the performance of Serial.parseInt() function in Arduino?

To improve the performance of Serial.parseInt() function in Arduino, you can ensure that the serial input buffer contains only valid numerical values without any extraneous characters. Additionally, you can use error handling techniques to handle cases where no valid integer value is present in the serial input buffer. By optimizing the input data and error handling, you can enhance the performance of Serial.parseInt() function in your Arduino code.

Similar threads

Replies
9
Views
2K
Replies
1
Views
3K
Replies
1
Views
3K
Replies
1
Views
6K
Replies
5
Views
5K
Replies
2
Views
12K
Replies
3
Views
10K
Back
Top