help with serial text recognition

Hey everybody!

I'm starting to experiment with some serial inputs for arduino, and right now the project that I'm trying is just to enter a string in to the serial monitor and have the arduino recognize it. I can get an array (fairly efficiently I think) and shove that into a String (successfully?), but when I compare the assembled String to a "known" String it will not return True. I've tried trimming off the whitespace, and the number returned by string.length matches the desired "known" string. What am I doing wrong? Thanks!

 char serIn[20]; //var that will hold the bytes in read from the serialBuffer
String string1 = ""; 
String name = "paul";
String stringtrimmed = "";

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

 
}

void loop () {
  for(int i=0; i <20; i++){
    serIn[i] = ' ';
  }
  string1 = "";
  //int choice1 = 0;
  //int choice2 = 0;
  //int choice3 = 0;
  //int choice4 = 0;
  boolean input1 = false;
  //boolean input2 = false;
  //boolean input3 = false;
  //boolean input4 = false;
  Serial.println("Please enter user name..");
  Serial.flush();
  while (input1 ==false){
    int i = 0;
    while(Serial.available()) {    
        serIn[i] = Serial.read();
        serIn[i+1] = '\0';
        i++;
        delay(2);
    }
    if(serIn[0] != ' '){
      for(int i =0; i <20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        Serial.println(serIn[i]);
        delay(100);
        }
      }
      for(int i =0; i<20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        string1 = String(string1 + serIn[i]);
        }
      }
      String stringtrimmed = string1.trim();
      Serial.println("");
      Serial.print(stringtrimmed);
      Serial.println("<-------- end of string");
      //Serial.println(stringtrimmed.length());
      //Serial.println(name.length());
      input1 = true;
    }
  }   
  if(stringtrimmed.equalsIgnoreCase(name)){
      Serial.println("");
      Serial.println("Welcome Paul!...Access granted");
  }
  delay(10000);
}

You have a bit to learn about strings. A string (lower case s) is a NULL terminated array of characters.

  for(int i=0; i <20; i++){
    serIn[i] = ' ';
  }

How many NULLS are needed to terminate the string? Hint: It isn't 20.

    while(Serial.available()) {    
        serIn[i] = Serial.read();
        serIn[i+1] = '\0';
        i++;
        delay(2);
    }

Serial data transmission is relatively slow. You may be through the loop before the sending application has finished sending the data. You really need to add some sort of end-of-packet marker, and keep reading (or waiting) until that end-of-packet marker arrives.

What is this code supposed to be doing?

      for(int i =0; i <20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        Serial.println(serIn[i]);
        delay(100);
        }
      }

Serial.println(serIn); will print the entire array, up to the first NULL.

What is this supposed to do?

      for(int i =0; i<20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        string1 = String(string1 + serIn[i]);
        }
      }

string1 = serIn; is sufficient.

Add Serial.print statements, to print name (bracketed) and stringtrimmed (bracketed) just before the if test.

Serial.print("name: >");
Serial.print(name);
Serial.print("<\n");
Serial.print("stringtrimmed: >");
Serial.print(stringtrimmed);
Serial.print("<\n");

Nothing really jumps out as the cause of the problem, but the extra prints will help narrow down the issue.

First off, sorry for the poorly commented code. Usually I do a better job, but this was intended as a simple experiment with getting text from the serial monitor into a String.

yeah, trying to make sense of this data type has been...odd.

I used this loop to fill the array (an arbitrary size of 20 since I don't know many words bigger than that) with something recognizable as whitespace.

 for(int i=0; i <20; i++){
    serIn[i] = ' ';
  }

The next section was intended to grab serial bytes from the buffer (with a delay of 2 milliseconds which seems to keep the read from "outrunning" the buffer, not the best way, but it solved a problem that I was having) and put them into an array that always has a '\0' NULL as the position immediately following the last received non-whitespace character.

while(Serial.available()) {
        serIn[i] = Serial.read();
        serIn[i+1] = '\0';
        i++;
        delay(2);
    }

This code was just a way for me to see what ended up in each index of the array. The for statement prints until it encounters two spaces ' ' in a row to indicate the end of the words. Includes a delay to have a chance to read it. Doesn't really do much.

for(int i =0; i <20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        Serial.println(serIn[i]);
        delay(100);
        }
      }

This section is how I proposed to put the elements from the char array into a String. By starting with a String full of nothing but whitespace and using concatenation to add each element in order, was how I was trying to make words from individual chars passed from Serial.read. This was the main part of my experiment. string1 = serIn; will transfer the array data into the String type without a problem then?

for(int i =0; i<20; i++){
        if(serIn[i] != ' ' || serIn[i+1] != ' '){
        string1 = String(string1 + serIn[i]);
        }
      }

I'll try the other modifications and see what happens. By the way, what does "\n" do in relation to Serial.print? "\t" prints a tab by my understanding.

Thanks for the help!

facepalm

by using

String stringtrimmed = string1.trim();

I redefined stringtrimmed as an empty String. I rewrote the code and it works fine. In fact I used the recommendations and it works better and with way less code than before. It seems that the .trim() step is unnecessary (as well as several other parts of the code...)

Thanks for the debugging tips for a newb, I'm sure I'll use that technique again soon!

I'm starting to experiment with some serial inputs for arduino, and right now the project that I'm trying is just to enter a string in to the serial monitor and have the arduino recognize it.

The below takes input from the serial monitor and forms a string for manipulation.

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for 0019 and later

String readString = String(100);
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
      Serial.begin(9600);
        myservo.attach(9);
        }

void loop() {

        while (Serial.available()) {
        delay(10);  
          if (Serial.available() >0) {
        char c = Serial.read();  //gets one byte from serial buffer
        readString += c;} //makes the string readString
        }
        
      if (readString.length() >0) {
      Serial.println(readString);
      int n;
      char carray[6];
      readString.toCharArray(carray, sizeof(carray));
      n = atoi(carray); 
      myservo.writeMicroseconds(n);
      //myservo.write(n);
      readString="";
      } 
   }

@zoomkat
You keep posting this code:

        while (Serial.available()) {
        delay(10);
          if (Serial.available() >0) {
        char c = Serial.read();  //gets one byte from serial buffer
        readString += c;} //makes the string readString
        }

I have no problem with you doing that, but I really think you should fix it, first.

The if test will not be reached unless there is serial data to read. After a delay of 10 milliseconds, there might even be more serial data available to read, but there can not possibly be less data.

So, what purpose does the if test serve?

Below is the updated sample code with the unneeded "if" removed. Also the readString declariation is corrected for the current IDE. I just post code that I find works, not necessarily what is the best. The only reason I feel the need to post my poor but functioning code is that of all the "gurus" on the board, 90% of their input to code issues is non functioning snippits and "chat" (which to non coders like me is often the equivilant of "what dogs hear"). I find it unfortunate, but that is the way it is.

// zoomkat 10-27-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// Servo.h default servo position 1500 on startup
// for Arduino IDE 0019 and later

#include <Servo.h> 
String readString;
Servo myservo;  // create servo object to control a servo 

void setup() {
      Serial.begin(9600);
        myservo.attach(9);
        }

void loop() {

        while (Serial.available()) {
        delay(10);  
          
        char c = Serial.read();  //gets one byte from serial buffer
        readString += c;} //makes the string readString
                
      if (readString.length() >0) {
      Serial.println(readString);
      int n;
      char carray[6];
      readString.toCharArray(carray, sizeof(carray));
      n = atoi(carray); 
      myservo.writeMicroseconds(n);
      //myservo.write(n);
      readString="";
      } 
   }