0

Every time I send an integer from computer to Arduino an extra zero is displayed on the LCD connected to Arduino. I don't know the reason. Why?

Here is the code:

#include <LiquidCrystal.h>

int en = 2, rs = 3, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
int a;
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);

void setup() {    
    Serial.begin(9600);
    lcd.begin(16,2);

}

void loop() {
    Serial.println("Enter a number");
    while(Serial.available()==0){}
    a=Serial.parseInt();
    lcd.print(a);
}

The result is as follows:

  • Enter a number
  • When I enter the number 1
  • The result 10 is displayed instead of 1
  • and what you get if you print a back to Serial Monitor? – Juraj Aug 25 '18 at 9:33
  • It is a typical problem when reading the serial input. The more experienced arduino users do not use such a while-statement to wait for input and do not use the Serial.parseInt functions. You might send a linefeed as well, and the Serial.parseInt can not make a number from the linefeed and returns zero or perhaps it has a timeout and returns zero. arduino.cc/en/Reference/StreamParseInt – Jot Aug 25 '18 at 11:24
  • Is there any alternate command/function instead of using Serial.available() and Serial.ParseInt()??? – Rizwan Ullah Aug 25 '18 at 13:20
  • @Jot, not true. parseInt has no problem with LF or any other character. we still don't know what is the value of a – Juraj Aug 25 '18 at 13:46
  • @Juraj there could be a linefeed and there could be a timeout. I'm pretty sure the parseInt returns a normal number the first time and a zero with the next call to parseInt. In my opinion it is very obvious (even without actually testing it). – Jot Aug 25 '18 at 13:57
2

The Serial.parseInt returns zero when it can not find a number within a timeout. That timeout is default one second.
When a number is typed in the serial monitor, often a linefeed is added to it. That linefeed is read by Serial.parseInt. It can not make a number out of that and waits until the timeout and returns zero.

There is no way to tell if the Serial.parseInt returns zero because the number was zero, or if it returns zero because there was a timout.

You can try the next sketch to show the problem. Set the line ending in the serial monitor to linefeed or carriage return or both or nothing and see what happens.

int a;

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

void loop() {
  Serial.println("Enter a number");
  while(Serial.available()==0){}
  a=Serial.parseInt();   // it returns zero with a linefeed !
  Serial.println(a);
}

The easiest way to fix this, is to use a number that is only a single digit. The function isdigit is used to check the incoming characters.

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a number (a single digit)");
}

void loop() {
  if (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isdigit(inChar)) {
      int value = inChar - '0';
      Serial.println(value);
    }
  }
}

The Serial.parseInt is not completely useless, but the number zero can not be used. The next sketch ignores the input when Serial.parseInt returns zero.

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a integer, but not zero, with a linefeed at the end");
}

void loop() {
  if (Serial.available() > 0) {
    int value = Serial.parseInt();
    if (value != 0) {
      Serial.println(value);
      Serial.println("Enter a integer, but not zero, with a linefeed at the end");
    }
  }
}

To be able to allow to type the number 0, the Serial.parseInt can no longer be used. To avoid waiting and delays, every character is immediately put into a buffer. The sketch becomes larger, but there is no other way. Either use Serial.parseInt or do it right.

#define BUFFER_SIZE 40
char buffer[BUFFER_SIZE];
int index;

void setup() {    
  Serial.begin(9600);

  Serial.println("Enter a integer, with a linefeed at the end");
}

void loop() {
  if (Serial.available() > 0) {
    bool ready = false;

    int inChar = Serial.read();
    buffer[index] = (char) inChar;
    index++;
    if (index >= BUFFER_SIZE) {
      index = BUFFER_SIZE - 1;
      ready = true;
    }

    if (inChar == '\n' || inChar == '\r') {
      ready = true;
    }

    if (ready) {
      if (isdigit(buffer[0]) || buffer[0] == '-') {
        buffer[BUFFER_SIZE - 1] = '\0';
        int value = atoi(buffer);
        Serial.println(value);
        Serial.println("Enter a integer, with a linefeed at the end");
      }
      index = 0;
    }
  }
}
  • thank you so much..@Jot.. Thank to all of you.. – Rizwan Ullah Aug 26 '18 at 9:09

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.