Saving Serial.read() as a string, and splitting the string

Hi.
So I'm having a problem:
How do I save whatever I send to the serial as a string (as in String response = Serial.read() where the final result would be response == "Hi")?

And how do I split a string? For example, in Javascript, there is such thing as a var splitstring = response.split(" "); , but I can't find anything similar in Arduino. If there is a way, how do I do it?

How do I save whatever I send to the serial as a string (as in String response = Serial.read()

Start with re-writing the HardwareSerial class so that Serial.read() returns a String.

The existing version does not. There are other methods in that class that do read more than one byte, IF there is something in the serial data stream that tells them when to stop reading.

None of them return a String though. And, there's a very good reason for that.

but I can't find anything similar in Arduino.

That's because Arduino is hardware. The software is C or C++. There are plenty of string handling functions in C, like strtok(). Of course, you need a string, not a String, to use them.

In a nutshell...

Do a loop that reads characters from the serial port and writes them into an array.

NULL terminate the "string" as you go.

When you have all the characters do something with them.

If you want a proper split() equivalent you'll have to write it yourself, however if you just want to chop the string into two or three pieces that's easy.


Rob

A simple example of capturing a string sent from the serial monitor and seperating the string into two parts.

// zoomkat 12-13-11 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 1.0
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550
// use serial monitor to test

#include <Servo.h> 
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo 
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control 
  myservo2.attach(7);
  Serial.println("two-servo-test-1.0"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(3);  //delay to allow buffer to fill 
    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); //see what was received
      
      // expect a string like 07002100 containing the two servo positions      
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters 
      
      Serial.println(servo1);  //print to serial monitor to see parsed results
      Serial.println(servo2);

      int n1 = servo1.toInt();
      int n2 = servo2.toInt();

      Serial.println("the numbers are :");
      Serial.println(n1);  //print to serial monitor to see number results
      Serial.println(n2);
            
      myservo1.writeMicroseconds(n1); //set servo position 
      myservo2.writeMicroseconds(n2);
    readString="";
  } 
}

zoomkat:
A simple example of capturing a string sent from the serial monitor and seperating the string into two parts.

// zoomkat 12-13-11 serial servo (2) test

// for writeMicroseconds, use a value like 1500
// for IDE 1.0
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550
// use serial monitor to test

#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control
  myservo2.attach(7);
  Serial.println("two-servo-test-1.0"); // so I can keep track of what is loaded
}

void loop() {

while (Serial.available()) {
    delay(3);  //delay to allow buffer to fill
    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); //see what was received
     
      // expect a string like 07002100 containing the two servo positions     
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters
     
      Serial.println(servo1);  //print to serial monitor to see parsed results
      Serial.println(servo2);

int n1 = servo1.toInt();
      int n2 = servo2.toInt();

Serial.println("the numbers are :");
      Serial.println(n1);  //print to serial monitor to see number results
      Serial.println(n2);
           
      myservo1.writeMicroseconds(n1); //set servo position
      myservo2.writeMicroseconds(n2);
    readString="";
  }
}

Okay, two issues with that.
For one, when I do that, the first character of the 'string' starts out with a strange number/symbol/thing. I will try your example, and will post pic if it does it again with that example.
Second, I want it to split conditionally, and wherever I want it to split (for example, I want to send "Hi. My name's | Billy Bob" and "My friend is | Jilly Joe", and the code will separate both strings into four arrays: "Hi. My name's " and " Billy Bob", and as for the other string "My friend is " and " Jilly Joe". Do you know what I mean? I don't know EXACTLY where to split the string, so I want the code to do that for me.

As mentioned there is no split() in C so you'll have to write something.

char str [] = "Hi. My name's | Billy Bob";
char * str_ptr [] = {str, 0};        // pointers to each sub string

get_string_from_serial_and_put_into_the_str_array();  // use one of many code snippets available like zoomkat's

str_ptr[1] = strstr( str_ptr[0], "|");   // find the |

* str_ptr[1]++ = '\0';    // overwrite the | with a NULL, that terminates the first string. Then move the pointer to the first char of the next string

str should now look like this

"Hi. My name's \0 Billy Bob\0"  // may still have \n at the end, depends on how you saved the chars from the serial port

Which is essentially two separate strings printed as such

Serial.print (str_ptr[0]);
Serial.println (str_ptr[1]);

This concept can be expanded to be a generic split() function if required.


Rob

#8 on the below page has info on some string functions with example code of each. If you want to parse the name out of the string "Hi. My name's Billy Bob", and the "Hi. My name's " will always be the same, then the name will always start at the 15th character in the string and continue to the end. Also, the name will always start one character beyond the "s" in the string. lots of different ways to do things. If you have control over how strings are sent to the arduino, then just send the name without the Hi stuff.

That's because Arduino is hardware. The software is C or C++. There are plenty of string handling functions in C, like strtok(). Of course, you need a string, not a String, to use them.
[/quote]

PaulS:
Start with re-writing the HardwareSerial class so that Serial.read() returns a String.

I'd rather not. I'll probably screw something up. I will attempt to save it as a string, as zoomkat mentioned by going
thing =+  "asdf"; //(or was it +=?)

PaulS:
That's because Arduino is hardware. The software is C or C++. There are plenty of string handling functions in C, like strtok(). Of course, you need a string, not a String, to use them.

Yes, I know that. I was talking about the code that Arduino uses and whatnot. Sorry if there was a misunderstanding.
And yes, I am looking at strtok, and although I don't initially get it, I will have to play with it to understand it. Thanks for the advice.

Graynomad:
Do a loop that reads characters from the serial port and writes them into an array.
NULL terminate the "string" as you go.

Yes, I am thinking about that. It seems like the... best way for me to do things. I believe I will do that, since that will also let me check if the next character is the character I want to split it at.

Graynomad:
If you want a proper split() equivalent you'll have to write it yourself, however if you just want to chop the string into two or three pieces that's easy.

PaulS told me about strtok(), and although it's interesting, I will have to test both ways (the aforementioned method and the said strtok() function)

zoomkat:
#8 on the below page has info on some string functions with example code of each. If you want to parse the name out of the string "Hi. My name's Billy Bob", and the "Hi. My name's " will always be the same, then the name will always start at the 15th character in the string and continue to the end. Also, the name will always start one character beyond the "s" in the string. lots of different ways to do things. If you have control over how strings are sent to the arduino, then just send the name without the Hi stuff.

http://arduino.cc/en/Tutorial/HomePage

I will look at it, but I believe I have the method I want to use (see previous post)