Comparing Serial.readString() to text

Hi,

I’m trying to compare a String input (from the Terminal) to the text “edit” (to initiate certain code.)
It APPEARS that the variable “a” also includes the Carriage Return, but I’m not sure. If this is so, I’ve been struggling in how to have the variable JUST capture the text sent via the Terminal.

THANKS for the help!!!

Test Code:

#include <Streaming.h>
String a;

void setup() {
  Serial.begin(115200);
  Serial << ("Ready") <<endl;
}

void loop() {
  while(Serial.available()) {
    a = Serial.readString();           // read the incoming data as string
    if (a.equals("edit")) {
      Serial <<("Input '") << a << ("' equals 'edit'") << endl;
    }
      if (a != "edit") {
      Serial <<("Input '") << a << ("' does NOT equals 'edit'") << endl;
    }
    Serial <<("a = ") << a << endl;
  }
}

Terminal Output:

Ready
Input 'edit
' does NOT equals 'edit'
a = edit

SOLVED: It was the Whitespace at the end of the captured text.

Used the "string.trim();" command and all is good.

If it's ok, figured I'd keep this up in case any one else has a similar issue.

Serial.readString() reads everything that is in the serial buffer until it times out. Therefore, everything you send will be inside the poorly named variable 'a' (No, really. Name it 'command' or whatever, but don't name it 'a').

Also, what is going on with all the parenthesis in your Serial code? Remove them, they are unnecessary. Same with the while loop, replace it with an if statement to keep the rest of the loop responsive.

I suggest to not use the readString or readStringUntil functions from the Stream class. They are relying on the String class, which is best to be avoided (dynamic memory allocation, memory fragmentation).

Instead, read a single byte and check if it is the '\n' character. Or the '\r' character, depending on what you set your line ending in the serial monitor. Check out the Serial Input Basics tutorial.

Agreed on “a”… was just for this question to the forum.

I’m trying to initiate an “edit” subroutine based on the Terminal input of the text “edit”

Here’s the code that seems to work:

  while(Serial.available()) {
    termtext = Serial.readString();
    termtext.trim();
    if (termtext.substring(0) == "edit"){
      Serial << "ready to do code" << endl;
    }

I admit not understanding your concern about relying on the Stream Class regarding the memory, etc. Could you expand on that or suggest a reference that I can research?

Thanks for the feedback!

When you invoke the Serial.readUntil method, it will create an instance of the String class and append single characters to the buffer, until the timeout is reached.

To append a character, the String class first checks if its internal buffer is large enough to hold the new data plus the old data. Because the internal buffer starts out empty, most of the times you append to a String it will need to dynamically allocate more memory for its internal buffer.

Imagine you have 100 bytes of memory. First, you allocate 20 bytes for a serial command to be received. Next you reserve 50 bytes to unpack the serial command into separate payload sections. You have now allocated 70 of 100 bytes, leaving you with 30 bytes of free memory.

-------------------------------------
|  20 bytes | 50 bytes  | 30 bytes  |
|    used   |    used   |    free   |
-------------------------------------

Now your receiving loop ends and the memory allocated for the serial command is free’d. You have 30 bytes + 20 bytes = 50 bytes of free memory.

-------------------------------------
|  20 bytes | 50 bytes  | 30 bytes  |
|    free   |    used   |    free   |
-------------------------------------

Let’s say now you need another 40 bytes to create a response String to send over the serial. Although you have 50 bytes of memory left, you will not be able to allocate the 40 bytes you need because they are composed of smaller pieces of free memory.

This is called memory fragmentation. It happens a lot with excessive use of the String class and leads to undefined behaviour (what happens when you can’t reserve enough memory to store the incomming command?).

Bwanna:
Agreed on “a”… was just for this question to the forum.

I’m trying to initiate an “edit” subroutine based on the Terminal input of the text “edit”

Here’s the code that seems to work:

  while(Serial.available()) {

termtext = Serial.readString();
   termtext.trim();
   if (termtext.substring(0) == “edit”){
     Serial << “ready to do code” << endl;
   }

Loose the while loop! The “loop” function will already do that for you.

Your version will only work, if you send "edit " (note the whitespace at the end). The substring command does nothing (a substring from the beginning to the end is just the string itself).

If you want to keep using String:

void loop() 
{
  if(Serial.available() > 0)
  {
    String terminalText = Serial.readStringUntil('\n');

    if(terminalText == "edit")
    {
      Serial.println("ready to do code");
    }
  }
}

LightuC - THank you very much! That feedback put me on the right path and the code is working very well.