reading strings through UART?

I have the serial uart working and can read bytes using the serial.read() command.
How can I read character strings through the serial port?
I want to send it text and be able to read and store the text string.

Thx,
R

How can I read character strings through the serial port?

The same way that they are sent - one character at a time.

I want to send it text and be able to read and store the text string.

Permission granted.

Ugh .. I need more coffee!

http://hacking.majenko.co.uk/reading-serial-on-the-arduino

After coffee, and more coffee..

How about add some detail to the question. What kind of device is originating the data that you want to read and store on the Arduino? What Arduino model and what pins are you using? Do you have any code developed yet? If so, post it. Look at the icons above the text window. Click the # icon.

  String storedData = "";
  if( Serial.available() ){ // if new data is coming from the HW Serial
    while(Serial.available())          // reading data into char array 
    {
      char inChar = Serial.read();
      storedDAta += inChar;
// This makes a string named storedData
    }
  }

This reads one character at a time and adds it to the string storedData until the Serial incoming buffer is empty. Experienced users tell me this is the type "character" which causes some problems corrupting memory, and to use the type "Byte". But I have no example of that. And broke my brain trying to figure it out. Hope this helps.

Coffee. Good idea!

Experienced users tell me this is the type "character" which causes some problems corrupting memory, and to use the type "Byte".

Nope.

A byte is just an unsigned char.

The problem is the use of the String class. You should use C strings (character arrays) instead. Read my link up the page.

Very simple character capture code.

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(2);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);

    readString="";
  } 
}

zoomkat:
Very simple character capture code.

However, not recommended because it is blocking (the sketch can't do anything else while it is waiting for the serial input to dribble in), relies on the serial input being received at the speed it is expected (which means it is vulnerable to being overrun if the serial port is faster than the speed that the receive loop is hard-coded for), assumes that all input messages are transmitted as a continuous bit stream (would fail to receive a complete message if there were any pauses in the transmission of a given message) and that there is a big enough gap between messages (would fail to separate messages correctly if messages are transmitted contiguously), and uses the Serial class which is a known cause of memory corruption up to version 1.0.4 and introduces the possibility of memory fragmentation in all versions.

A better approach is to simply accumulate the received characters into a c-string (null terminated character array) with code to explicitly detect when a complete message has been received. Here is an example which uses carriage return and newline characters to indicate the end of a message:

// incomplete, untested
void handleSerial()
{
    const int BUFF_SIZE = 32; // make it big enough to hold your longest command
    static char buffer[BUFF_SIZE+1]; // +1 allows space for the null terminator
    static int length = 0; // number of characters currently in the buffer

    if(Serial.available())
    {
        char c = Serial.read();
        if((c == '\r') || (c == '\n'))
        {
            // end-of-line received
            if(length > 0)
            {
                handleReceivedMessage(buffer);
            }
            length = 0;
        }
        else
        {
            if(length < BUFF_SIZE)
            {
                buffer[length++] = c; // append the received character to the array
                buffer[length] = 0; // append the null terminator
            }
            else
            {
                // buffer full - discard the received character
            }
        }
    }
}

void handleReceivedMessage(char *msg)
{
	if(strcmp(msg, "on") == 0)
	{
		// handle the command "on"
	}
	else
	{
		// etc
	}
}

// incomplete, untested

Sad, when you going to post something that is not broken and works?

when you going to post something that is not broken and works?

Don't bother, Peter. If you do, zoomkat won't be able to remember that you did, and will, 10 minutes later, insist that you do it again. Believe me, I've posted plenty of examples of reading code into char arrays, in a non-blocking fashion, and zoomkat can't remember that.

I've posted plenty of examples of reading code into char arrays, in a non-blocking fashion, and zoomkat can't remember that.

Can you show where you actually post complete working code instead of stuff from your "snippets-R-us.com"? Those that can, do. Those that can't usually need some cheese with their whines. Will sharp cheddar do for you? 8)

zoomkat:
Sad, when you going to post something that is not broken and works?

In what way is that example code broken or non-working?

PeterH:

zoomkat:
Sad, when you going to post something that is not broken and works?

In what way is that example code broken or non-working?

Then why did you include the below in your code? You can't even test your own code before posting? Perhaps you copied somebody else's code? What you posted is PaulS's favorite "snippets-R-us.com" code that won't even compile. Where is PaulS when you need him to stop that "snippet" cancer before it spreads? 8)

// incomplete, untested

"snippet" from my website (link posted earlier) - compiles and tested and works, and is non-blocking.

int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;
  
  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  static char buffer[80];
  if (readline(Serial.read(), buffer, 80) > 0) {
    Serial.print("You entered: >");
    Serial.print(buffer);
    Serial.println("<");
  }
}

"snippet" from my website (link posted earlier) - compiles and tested and works, and is non-blocking.

But did you add an additional condition that the character string being sent must be delimited with cr/lf to work and be non blocking? If the end character string being sent is delimited, then that is a different set of initial conditions. Show your code that works without delimiters. 8)

A delimiter is required. How else will it know when it's reached the end?

zoomkat:
Show your code that works without delimiters. 8)

const unsigned long timeToWait = 3; // how long to wait between characters to decide if the string is finished
const byte BUFFER_SIZE = 20;  // how many characters we can store in the buffer

char buffer[BUFFER_SIZE + 1]; // plus 1 for the null-terminator
unsigned long lastCharReceived = 0; // keeps track of the last time we received a character
boolean stringStarted = false; // keeps track of whether we are in the process of receiving a string
byte index = 0; // keeps track of the next free spot in the buffer

void setup()
{
  Serial.begin(115200);
  Serial.println("begin");
}

void loop()
{
  if (Serial.available() > 0) // if there is an available character
  {
    char inByte = Serial.read(); // read it
    stringStarted = true;  // we've started a string
    lastCharReceived = millis(); // the last time we received a character is now
    if (index < BUFFER_SIZE) // only add to buffer if no overflow occurs
    {
      buffer[index++] = inByte; // add byte to buffer
    }
  }

  // if we've started a string and its been long enough since we received a character
  if ( stringStarted && millis() - lastCharReceived >= timeToWait)
  {
    // null terminate the string
    buffer[index] = '\0';
    // do something with the string
    Serial.print("Received > ");
    Serial.println(buffer);

    // reset our buffer and values
    index = 0;
    buffer[0] = '\0';
    stringStarted = false;
  }
}

Problem?

This is the better-than-blocking-but-not-as-good-as-using-a-deliminating-character method.

You still have a delimiter. True, that delimiter is time, not a character, but it's still a delimiter.

de·lim·it [dih-lim-it]
verb (used with object)
to fix or mark the limits or boundaries of; demarcate: A ravine delimited the property on the north.

Hence, delimiter - something which delimits.

Commonly used to denote a specific character or character sequence, but there is nothing that says a delimiter has to be a character. Time is the delimiting factor. It's still delimiting the text, hence it is a delimiter.

There, I fixed my semantics. I assume zoomkat was referring to a deliminating character, considering his/her code also contains " a deliminating time factor".

majenko:
A delimiter is required. How else will it know when it's reached the end?

Then you base your code on parameters that don't depend on a delimiter being sent. If a delimiter is included, then code like below using a comma as a delimiter is also simple.

//zoomkat 3-5-12 simple delimited ',' string parce 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial LED on/off test with , delimiter"); // so I can keep track
}

void loop() {

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //if (readString.length() >0) {
        Serial.println(readString); //prints string to serial port out
        //do stuff with the captured readString
        if(readString.indexOf("on") >=0)
        {
          digitalWrite(ledPin, HIGH);
          Serial.println("LED ON");
        }
        if(readString.indexOf("off") >=0)
        {
          digitalWrite(ledPin, LOW);
          Serial.println("LED OFF");
        }       
        readString=""; //clears variable for new input
      //}
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}