Problem with String equality in if statement condition

Hello All,

I am trying out an example code found in the Arduino forum allows us to use the keyboard input from serial monitor to increment servo motors (from here: https://forum.arduino.cc/index.php?topic=385624.0)

When I use the Serial.read() function and obtain a character “a” or “s” from the serial monitor I can verify that the stored character is indeed the one I typed. Next the char is converted to string which I verified is still the same letter I typed by printing in the serial monitor. Then, when I try to use an if statement to check whether the string is “a” or “s” for some reason it never goes into either of the if statements. I added Serial print in the two if statements but they never get displayed. Please help, thank you!

I changed the code a bit for simplicity and removed irrelevant parts to the question.

#include<Servo.h>
String readString;

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

void loop()
{
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
    Serial.print("readstring value:");
    Serial.print(readString);
  }
  if (readString.length() >0) {
    if(readString == "a"){
      Serial.print("equal a ");
      //increment motor
    }
    if (readString == "s"){
      Serial.print("equal s ");
      //decrement motor
    }
  }
  readString=""; //empty for next input
}

What have you got Line ending set to in the Serial monitor ?

UKHeliBob:
What have you got Line ending set to in the Serial monitor ?

Thanks for the reply, it's set to new line.
If it helps....I am seeing readString value as "a" when serial printing it.

The newline character ‘\n’ is part of the String.

To get your String match either set your monitor to “no line ending” or change your match criteria to include the new line

if(readString == "a\n"){

Thanks so much, that works!

readString.trim();

removes those nasty \r and \n's (and other leading/trailing whitespace)

For a tutorial on stepper motor control with user inputs check out
my Multi-tasking in Arduino

That delay(2) is 'bad'
For single chars try

//https://forum.arduino.cc/index.php?topic=733454.0
// modified from
// readOneChar.ino
// Reads one char cmds from Serial
// https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/index.html
// Pros: Extremely Simple, Non-blocking and Robust
// Cons: Nothing really. You can do a lot with 52 one char cmds (A..Z,a..z)

void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
}

void loop() {
  char c = Serial.read(); // note read() returns an int, char c = converts it to a char
  if (c != -1) {  // read() return -1 if there is nothing to be read.
    // got a char handle it
    Serial.println(c);
    if (c == 'a') {
      Serial.println("inc");
      //increment motor
    } else if (c == 's') {
      //decrement motor
      Serial.println("dec");
    }
  }
}

For reading a String try this code
This will return the input line when '\n' found OR if no more input for 1sec (non-blocking)
so works with \r\n and \n line endings and also No line ending

// readStringUntilLimitedTimeout.ino
// Reads chars into a String until newline '\n'
// https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/index.html
// Pros: Simple. Non-Blocking, Robust against unexpectedly long input lines and missing termination, until_c char
// Cons: Nothing really.

String input;

void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  Serial.println(F("readStringUntilLimitedTimeout.ino"));
  input.reserve(20); // expected line size
}

// read Serial until until_c char found or limit char read or timeout, returns true when found/limited else false
// non-blocking, until_c, if found, is returned as last char in String, updates input String with chars read
bool readStringUntil(String& input, char until_c, size_t char_limit) { // call with char_limit == 0 for no limit
  static bool timerRunning; static unsigned long timerStart;     // timeout static variables
  static const unsigned long timeout_mS = 1000; // 1sec  set to 0 for no timeout

  while (Serial.available()) {
    timerRunning = false; // set true below if don't return first
    char c = Serial.read();
    input += c;
    if (c == until_c) {
      return true;
    }
    if (char_limit && (input.length() >= char_limit)) {
      return true;
    }
    // restart timer running
    if (timeout_mS > 0) {  // only start if we have a non-zero timeout
      timerRunning = true;
      timerStart = millis();
    }
  }
  if (timerRunning && ((millis() - timerStart) > timeout_mS)) {
    timerRunning = false;
    return true;
  }
  return false;
}

char terminatingChar = '\n';
void loop() {
  if (readStringUntil(input, terminatingChar, 20)) { // read until find newline or have read 20 chars, use 0 for unlimited no chars
    if (input.lastIndexOf(terminatingChar) >= 0) {   // could also use check  if (input[input.length()-1] == terminatingChar) {
      Serial.print(F(" got a line of input '")); Serial.print(input); Serial.println("'");
    } else {
      Serial.print(F(" reached limit or timeout without newline '")); Serial.print(input); Serial.println("'");
    }
    input = ""; // clear after processing for next line
  }
}

Yes let me correct the math to match the text

Erik_Baas:
72? Really?

Maybe he meant 72 octal? That would be closer to right.... :slight_smile:

Thank you Dr. Ford, the multi-tasking tutorial will come in very handy for my project eventually!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.