Arduino Serial Communication - String Comparison Issue

Greetings;

I'm facing a problem with Serial Communication Between Application and Micro Controller.

Intended: The Application sends a Command to Arduino; Arduino Receives the Command; Performs a String Comparison and Performs the Corresponding Action (Let's say Reply Back with Serial.println("some result back")).

Problem:
The Arduino properly receives and transforms the command string; but is unable to perform a String comparison when command is sent by Application.
Under Arduino IDE Serial Monitor; after sending the EXACT same command; the Code performs the comparison without any sort of problem.

It looks like The Arduino "says" that the string received from application is not exactly equal. Yet it is!
Under my Application I tried sending the Command with and without the terminating char \0 or \n.
The same result applies.
I've been stuck for days now and still can't understand why the Comparison result doesn't match a clearly EQUAL String.

Interesting Fact:
I've tried using indexOf("myCommand") instead of a String Comparison and it actually checks the String correctly.
However this will interfere with remaining commands as each one belongs to a specific group (word) and therefore calling "indexOf" will actually call all commands containing the first 3 chars in a command group.

/* Serial Data Configuration */
String inData;
bool hasNewData = false;
char SerialReceivedChars[32];
char endMarker = '\n';
int maxNrChars = 32;


const String GetBoardInfo = "GetBoardInfo";

/* Set User Selected Mode */
void SetMode(String cmd)
{
  Serial.println("Received: " + cmd); 

  if (cmd.equals(GetBoardInfo))    { Serial.println("Command Match"); }
}

/* Listen for Incomming Serial Data from PC */
void SerialListen()
{
    static byte ndx = 0; /* Data Received in Bytes */
    char receivedChar;

    while (Serial.available() > 0 && !hasNewData)
    {
        receivedChar = Serial.read();

        /* While Received Data (Payload) hasn't Received the Terminator Char */
        /* Add Received Chars to rc Variable */
        if (receivedChar != endMarker)
        {
            SerialReceivedChars[ndx] = receivedChar;
            ndx++;

            /* Limit Received Chars to the Maximum Number of Chars. */
            /* Whenever a new Char is Received While Maximum Number of Chars is Already Occupied: Replace Last Char with New Char. */
            if (ndx >= maxNrChars) { ndx = maxNrChars - 1; }
        }

        /* else: Terminator Char was Received. */
        /* Terminate Number of Defined Characters Variable. */
        /* [Note]: In C/C++ a string is an array of char terminated with a NULL byte ('\0'); */
        /* Set newData Variable to True. Meaning: New Data Has Been Received. */
        else
        {
            SerialReceivedChars[ndx] = '\0'; /* Terminate the string. Default: '\0' or '\n' */
            ndx = 0;
            hasNewData = true;
        }

        if (hasNewData)
        {
            inData = String((char*)SerialReceivedChars);
            
            SetMode(inData);
           
            hasNewData = false;
            inData = "";
        }
    }
}

/* Component Initialization */
void setup()
{ 
  Serial.begin(115200);
}

/* Loop */
void loop()
{
  SerialListen();
}

Any suggestions or thoughts why the Arduino is not performing a String comparison correctly?

Thanks in advance.

I expect your PC is sending CR and LF. The CR is ending up in the string you read, hence it doesn't match.

xrtekk:
Any suggestions or thoughts why the Arduino is not performing a String comparison correctly?

Your code has enough in common with the code in my Serial Input Basics Tutorial to make me wonder why you went to the trouble of changing it.

If you use c-strings (as in my Tutorial) the strstr() function will find one string inside another.

...R

Greetings;

@Robin; thanks for pointing me out that the code source was from you (fantastic piece of code).
Have been wondering where I got it for quite some time.
I've changed a little bit for the sake of understanding and still fight with it a little bit.
In my honest opinion the variable names are quite difficult to read and follow a logic.
I don't remember what I've changed in code; back then I simply needed something that worked for what I was working on.
I'll take a look to the source as soon as possible and add a comment on the code regarding you as the author.

@WildBill: Just read about CR and LF (I wasnt't aware of the terms. Always good to learn more and get more specific).

On my PC I'm configuring SerialPort with:

"NewLine = Environment.NewLine,"

Just found out that this is the Source of the Issue.
The command string gets changed with this.

For now I need to:
Either configure the Arduino code to expect the "new line" (Configured on PC SerialPort); or remove the new line configuration from SerialPort and add a Null Teminatin Byte / Terminating char anytime a command is send or written.

Thanks both for the replies.

xrtekk:
In my honest opinion the variable names are quite difficult to read and follow a logic.

If you tell us what you are finding difficult I will try to help.

Have you tried the example from my Tutorial without any changes?

...R

If you are using Strings, this is simpler
Check out my tutorial Taming Arduino Strings

/* Serial Data Configuration */
String inData;
const String GetBoardInfo = "GetBoardInfo";

/* Set User Selected Mode */
void SetMode(String& cmd)
{
  cmd.trim(); // handle CR NL problems
  Serial.println("Received: " + cmd);
  if (cmd.equals(GetBoardInfo))    { Serial.println("Command Match"); }
}

// stopC is the char to stop at
// returns true when get stopC and input contains the input up to then
// else return false
bool readStrUntil(char stopC, String& input) {
  while (Serial.available()) {
    char c = Serial.read();
    if (c == stopC) {
      return true;
    }
    // else
    input += c; // good for >1000 char lines on UNO
  }
  return false;
}

/* Component Initialization */
void setup()
{
  Serial.begin(115200);
}

/* Loop */
void loop() {
  if (readStrUntil('\n',inData)) {
      SetMode(inData);    
      inData = ""; // clear for next line
   }
}

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