Serial Comms and String manipulation results unwanted unprintable characters

Problem - I'm using an example sketch as the basis (Serial Event example). There is a problem setting a msg in my function Vobcabulary(). if the msg is 2 or 3, msg 1 will never be shown correctly as seen in Test#2-4.

Test#1
Vocabulary CORRECT
start
Started Here i've started in the correct sequence
Vocabulary Key word 'start' diplays msg 1. 'end' diplays msg 2
end Msg 3 is for any other entry
ending...

Test#2
Vocabulary FAULTY
end
ending... I've started with 'end' and it displays the correct msg#2
Vocabulary the 1st recognized word 'start' now displays msg#3
start
Not in my Vocabulary

Test#3
Vocabulary FAULTY
test
Not in my Vocabulary I've started with 'test' and it
Vocabulary displays the correct msg#3
end Now the word 'start or'end' displays
Not in my Vocabulary msg#3

Test#4
Vocabulary FAULTY
test
test As in end#3, same results. I've added an extra print
Not in my Vocabulary and it shows the Second print.
Vocabulary Then on the second input on the Second print it has
end altered into an unprintable character( )
Not in my Vocabulary (Note the unprintable character)

Problem - The code only runs for 2 inputs loops and as you there are no counters. - unresolved as of yet

Here is what I've tried so far-
-switched from a Arduino Nano to a Arduino Uno.
-changed if statement detection, I've tried almost all of the String manipulations and settled on startsWith.

  • i don't think that there is a memory issue. Here is the report after uploading:

Sketch uses 3690 bytes (11%) of program storage space. Maximum is 32256 bytes.
Global variables use 253 bytes (12%) of dynamic memory, leaving 1795 bytes for local variables. Maximum is 2048 bytes.

Here is my code:

/*-----------------credits---------------------
  Serial Event example

  created 9 May 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/SerialEvent
*/
//-------------------------------------------------------------------------------

const int LED = 13;
String inputString = "";         // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

//-------------------------------------------------------------------------------

void setup() {
  // initialize serial:
  Serial.begin(115200);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Vocabulary(inputString);  //my Vocaulary() function
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}
//-------------------------------------------------------------------------------

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
//-------------------------------------------------------------------------------
String Vocabulary(String RxStr) {
  Serial.println("Vocabulary"); //fault-finding, remove later
  Serial.print(RxStr);          //First print. fault-finding, remove later
  if (RxStr.startsWith("start")){
    Serial.print(RxStr);        //Second Print. fault-finding, remove later
    digitalWrite(LED, HIGH);    //fault-finding, remove later
    Serial.println("Started");  //msg#1
    //call function
  }else if (RxStr.startsWith("end")){
    Serial.print(RxStr);        //Second Print. fault-finding, remove later
    digitalWrite(LED, LOW);     //fault-finding, remove later
    Serial.println("ending..."); //msg#2
    //call function
  }else {
    Serial.print(RxStr);        //Second Print. fault-finding, remove later
    Serial.println("Not in my Vocabulary");//msg#3
  }
  RxStr = "";                   //null the string
}
//-------------------------------------------------------------------------------

Any Help would be Greatly appreciated.

I'm having a real hard time figuring out what exactly the problem is. Can you give a clear and succinct explanation of your project? What is it supposed to do?

Can you give us a test case of the exact inputs the code expects - and the corresponding outputs you expect from the code?

basically the project is to take serial commands ("start", "end" and a trap for anythings else) (i'll expand the word list at a later date) and call the appropriate function.

p/o the problem is in serial monitor, serial monitor will only accept 2, maybe 3, serial cmds before becoming non-responsive.

The other p/o the problem is, unless the cmds are in the correct sequence (Test#1 - first cmd "start" and second cmd "end")

Test#1 first cmd "start" and second cmd "end"
Vocabulary CORRECT
start
Started Here i've started in the correct sequence
Vocabulary Key word 'start' diplays msg 1. 'end' diplays msg 2
end Msg 3 is for any other entry
ending...
Worked as expected

Test#2 first cmd "end" and second cmd "start"
Vocabulary FAULTY
end
ending... I've started with 'end' and it displays the correct msg#2
Vocabulary the 1st recognized word 'start' now displays msg#3
start
Not in my Vocabulary
the first cmd produced the correct O/P "ending...". the second cmd "start" produced "Not in my Vocabulary", which is the trap for unrecognized cmd

Test#3 first cmd "test" and second cmd "end"
Vocabulary FAULTY
test
Not in my Vocabulary I've started with 'test' and it
Vocabulary displays the correct msg#3
end Now the word 'start or'end' displays
Not in my Vocabulary msg#3
the first cmd produced the correct O/P "Not in my Vocabulary" not being a recognized cmd. the second cmd "end" (a recognised cmd) produced "Not in my Vocabulary", which is the trap for unrecognized cmd

In Test#4 I've added a second print cmd
Test#4 first cmd "test" and second cmd "end"
Vocabulary FAULTY
test
test As in end#3, same results. I've added an extra print
Not in my Vocabulary and it shows the Second print.
Vocabulary Then on the second input on the Second print it has
end altered into an unprintable character( )
Not in my Vocabulary (Note the unprintable character)

So the unprintable character are a major problem in trying to recognise serial cmds.
Hope this will explain things

I don’t normally use String. I use char arrays.

char inputString[201];
int i = 0;


void setup() 
{
  // initialize serial:
        Serial.begin(115200);

}

void loop() 
{
    char inChar;

    if (Serial.available())
    {
        //read the byte
        inChar = Serial.read();

        if (inChar != '\r')
        {
            inputString[i] = inChar;
            Serial.print(i);
            Serial.println(inChar);
            i++;        
        }
        else
        {
            // all the characters have been received

            inputString[i] = '\0';          //terminate with the NULL

            //look for start
            char startString[6];
            strncpy(startString, inputString, 5);
            startString[5] = '\0';          //terminate with the NULL
            int result;
            result = strcmp("start", startString);
            if (result == 0)
            {
                Serial.println("starting");
                inputString[0]= '\0';
                i = 0;
                return;
            }

            //look for end
            char endString[4];
            strncpy(endString, inputString, 3);
            endString[3] = '\0';
            Serial.println(endString);
            int result2;
            result2 = strcmp("end", endString);
            if (result2 == 0)
            {
                Serial.println("ending");
                inputString[0]= '\0';
                i= 0;
                return;
            }

            //the code drops to here if neither of the above is true
            Serial.println("not in my vocabulary");
            i = 0;
            inputString[0]= '\0';
            
        }
    }
}

@ ieee488 thanks for your code, although doing the same testing I discovered some of the same problems. Here is one O/P:

1⸮0e //garbage seen in Serial Monitor(it changes Monitor window to Monitor window.
1n
2d
end
ending //This is the correct o/p for the cmd
0

1s
2t
3a
4r
5t

st
not in my vocabulary //unfortunately this goes back to the same problem that I've had
0

still looking at the code

Thank you

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

If you can control the format of the data being sent then the technique in the 3rd example will be the most reliable.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

sean_felts:
p/o

sean_felts:
O/P:

What do p/o and o/p mean?

neiklot:
What do p/o and o/p mean?

I was wondering the same.

I suspect 'O/P:' might be code for output.

Since 'p/o' is the reverse of 'O/P:' (output ?) maybe it means input ?

Of course you are correct the o/p is 'output' and sorry for the confusion, p/o is 'part of'.