Help with reading string from serial

I need to read a string sent from processing to the arduino. Seems simple enough. I have a processing program that justs write "abc123" to the arduino via serial and a arduino program that trys to read it and send it back. The problem I am getting is that the arduino serial monitor is showing stuff like this:
abc123
ab23
ab23
ab23
ab23
ab23
bcac123
a123
a1
a1
1

Weird. Here is my arduino code:

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pin as an output:
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    
    //float foo = readFloatSerial();
    //Serial.println(foo, DEC);
    delay(5);
    String foo = readStringUntil('\n');

    Serial.println(foo);
  }    
}


String readStringUntil(char terminator) {
  byte index=0;
  byte timeout=0;
  char data[18] = "";
  
  while((data[index] != terminator) && index<18 && timeout<5)  {

    if(Serial.available() == 0) {
      delay(8);
      timeout++;
    }
    else {
      data[index] = Serial.read();
      timeout=0;
      //Serial.println(data[index]);
      index++;
    }
    //Serial.println(index,DEC);
  }
  //Serial.println(data);
  return (String)data;
}

and processing code:

import processing.serial.*;

Serial arduinoPort;

void setup() {
  size(100,100);
  arduinoPort = new Serial(this,Serial.list()[0],9600);
}

void draw() {
  background(50);
  //arduinoPort.write(composePitch(0.1));
  String str = "abc123";
  arduinoPort.write(str);
  delay(1000);
}

Could the problem be that my readStringUntil method is not getting the correct terminator character? As a side question, are there any library methods like readString() or readStringUntiL(char)? I know there are both of those in processing. Anyways, I hope someone can help me out here. Over 9000 kudos to someone who can! :slight_smile: Thanks.

Simple test code that looks for a delimiter.

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

String readString;

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

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
  while (Serial.available()) {
    delay(1);  //small delay to allow input buffer to fill
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      break; //breaks out of capture loop to print readstring
    }  
    readString += c; //makes the string readString
  }

  if (readString.length() >0) {
    Serial.println(readString); //prints string to serial port out

    readString=""; //clears variable for new input
  }
}

Thanks zoomcat. I had seen the code earlier and tested it, but I get the same problem, jumbled serial messages. The code seems fine so maybe the issue has something do with the processing side, fastish seral messages or the interference of serial messages crossing. Thanks.

First, default line ending with the Arduino Serial Monitor adds nothing. You have to set it up to add \r or \n. Once you do that you can tell when the real EOL (end of line) is reached.

Second just because Serial.available() is true doesn't mean there's more than 1 byte available right then. The Arduino is much faster than serial data, you shouldn't code serial on the Arduino like you're reading file text on a PC or have an OS between you and the world.

Code like you might see 1 character in many loop() passes (unless of course you write cycle-wasting delays) and don't code like the end of a line will be there until you see EOL. Code for 1 byte at a time and you won't need delays(). Your code will run fastest that way.
Even then make sure to check for transmission errors and bad data errors even if you 'know' it will be perfect.

Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL. I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.
Truth is that unless you're saving strings you can probably get away without buffering any (not counting const strings... char arrays... used to compare against) serial data. This is especially true when the serial data is control codes and numeric parameters.

Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL. I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.

So show some woking code. :slight_smile:

This doesn't look for control codes but I can add that. It does what it's supposed to do.

//  Decimal Long Int to HEX & BIN Converter 
//  It -only- expects integers, space delimits, negative values allowed
//  make sure the serial monitor ends lines with newline or carriage return.

char  B; // bytebuffer -- allocated only once
long  V; // for storing number while reading
byte  charCount = 0; // how many digits or bytes of garbage 
byte  stateBits = 0; // bit 0 is sign, bit 1 is reading garbage

void setup() {
  Serial.begin(9600);
  Serial.println("Convert dec to hex and bin");
  Serial.println("Enter digits, - or space through terminal.");
}

void loop(void) { // read one or no character each pass
  if (Serial.available()) {
    charCount += 1;
    B = Serial.read();
    Serial.print(B, BYTE); // echo each character as read
    //    Serial.print(" "); // debuggy informy stuff
    //    Serial.print(B, HEX);
    //    Serial.print(" : ");
    if ( !(stateBits & 2)) { // do if 'garbage in' is NOT set 
      if ((B >= '0') && (B <= '9')) { //// is B a digit?
        if ( charCount > 10 ) { // 
          //        print_value();
          print_error(" overflow ");
          return;
        }
        if (V >= 300000000) { // will adding a digit overflow value?
          //        print_value();
          print_error( " overflow " );
          return;
        }
        // updating V, one digit at a time 
        V *= 10; // shift the previous vale up a decimal place
        V += (B - '0'); // add the new ones
        return;
      } 
      else if ((B == '-') && (charCount == 1))  { // leading minus only
        stateBits |= 1; // V will be made negative at end of read
        charCount = 0; // sign is not a digit
        return;
      }
      else if ((B == ' ') || (B == '\t') || (B == '\r') || (B == '\n'))  { // space & tab delimit
        if (charCount > 1)    { // slice off leading spaces
          print_value();
        }
        else set_zero(); // eat spaces & tabs
        return;
      }
      else {  // whatever gets this far is not a valid character
        //      print_value();
        stateBits |= 2; // garbage-in state set ON
        //      print_error(" long integers please ");
        return;
      }
    }
    else { // garbage-in mode, check for delimiters if so then print error
      if ((B == ' ') || (B == '\t') || (B == '\r') || (B == '\n'))  { 
        //        Serial.println(" decimal integers please!");
        if (charCount > 1)  { // don't println just for a delimiter
          Serial.println(); // just let the garbage echo be the message
          set_zero(); 
        }
        else  charCount = 0; // eat the spaces
      }
      return;
    }
  }
}

void  print_value( void )  { // print dec hex bin
  if (stateBits & 1)    V = -V;
  Serial.print(" > ");
  Serial.print(V, DEC);
  Serial.print(" : 0x");
  Serial.print(V, HEX);
  Serial.print(" : 0b");
  Serial.println(V, BIN);
  set_zero();
}

void print_error(char *errmsg)  {
  /*  if (Serial.available())  {
   while (Serial.available())  {
   B = Serial.read();
   Serial.print(B, BYTE);
   }
   }
   */
  Serial.print(" *error* " );
  Serial.println(errmsg);
  set_zero();
  stateBits = 2; // garbage-in, look for a delimiter then start over
}

void  set_zero( void )  {
  V = 0;      // init, start looking for the next value
  charCount = 0;
  stateBits = 0;
}

This doesn't look for control codes but I can add that.

Ok, just looking for the "Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL." Not intersted in the other conversion stuff.

I didn't need to save the bytes so I didn't. It's not-making a practice of doing something I don't need.

Do you need an example of packing bytes into an array for text use? I'll even put a 0 on the end.

I'm looking for what you said: "Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL." The rest of what you said below seems to indicate more complex and combersome code.

I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.
Truth is that unless you're saving strings you can probably get away without buffering any (not counting const strings... char arrays... used to compare against) serial data. This is especially true when the serial data is control codes and numeric parameters.

Dealing with control codes, you have to evaluate and act on them anyway don't you? Do you think that buffering input strings will eliminate the need? Or that using a library function like atoi() will make error handling unnecessary?

Dealing with control codes, you have to evaluate and act on them anyway don't you? Do you think that buffering input strings will eliminate the need? Or that using a library function like atoi() will make error handling unnecessary?

Hmmm..., no working code. Oh well! :slight_smile:

You only need an example of serial data going into an array?
You want that printed back to terminal?
Anything else or will this be moving-target code?

You only need an example of serial data going into an array?
You want that printed back to terminal?
Anything else or will this be moving-target code?

Moving target??? I just requested working code for the mumbo-jumbo you were previously touting:

Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL. I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.

Trying to translate your post, I would expect the data sent from the serial monitor to be "packed" into an array on the arduino, the "EOL" detected, and to provide verification that it is working, the captured data sent back to the serial monitor. Should be simple. I want to see why it is such a waste to use Strings (that is probably going to the the next question) in arduino programming. :wink:

Gentlemen;

I did also try to send data to an Arduino. I try to monitor the serial using the Arduino IDE, but that did not work because my processing program was running. Here the link of my posts. ---> http://arduino.cc/forum/index.php/topic,76586.0.html

I did a small program to receive the data from my computer using the Arduino IDE , and the Processing to received it. As Grumpy_Mike says, you can not have 2 program using the same port on a PC. That may be a cause of the problem. My Arduino program is simply a byte variable and write that byte to a LCD Display to show the message ---> This is a test <--- The Processing send the string --> myport.write("This is a test"); <-- the data will be send in ASCII format, so the receive data will be in ASCII data. So that is why I use a byte variable and the line --> incom=Serial.read(); The buffer idea is a good one, that will take care of some of the timing issue.

What about use a null string ? in your sending data like ---> myport.write("This is a test\0"); <-- a null ASCII code is 0x00 ... so the Arduino code simply "watch" for that null string a simple --> if (incom_==0) { // do somethings } or if (incom*<>0) {// do something to } or a while() loop. Just an idea.*_

zoomkat:

You only need an example of serial data going into an array?
You want that printed back to terminal?
Anything else or will this be moving-target code?

Moving target??? I just requested working code for the mumbo-jumbo you were previously touting:

Moving target is spec that keep changing. 1st I write this and then you say it must do that.

Mumbo-jumbo meaning -you- don't understand, therefore it must be nonsense?

Just pack the bytes into a char[] array if you have to save them and look for, in your case, EOL. I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.

Trying to translate your post, I would expect the data sent from the serial monitor to be "packed" into an array on the arduino, the "EOL" detected, and to provide verification that it is working, the captured data sent back to the serial monitor. Should be simple. I want to see why it is such a waste to use Strings (that is probably going to the the next question) in arduino programming. :wink:
[/quote]

EOL is standard for End Of Line. I even spelled it out in the first sentence of that post. Did you bother to read?

I want to see why it is such a waste to use Strings

You even QUOTE ME on that: they take 2 bytes per character

I don't say that C++ Strings are completely useless, just that for most Arduino applications they are wasteful. Explanation? When you only have 2K or less RAM, using 2 bytes per character is wasteful.

Here is serial input to buffer sketch. If you don't follow directions then it won't work as it should so BE SURE and set your terminal to add carriage-return or new-line or line-feed at the end of line.

//  Serial input line delimited by cr or lf to buffer then print back out.
//  make sure the serial monitor ends lines with newline or carriage return or both.

char  B, buff[41]; // character and character string buffer
byte  buffCount = 0; // how many characters in the buffer
byte  buffCharLimit = 40; // maximum characters allowed

void setup() {
  Serial.begin(9600);
  Serial.print("Serial input to buffer then print back out, " );
  Serial.print(buffCharLimit, DEC);
  Serial.println(" characters max.");
  Serial.println("Make sure the serial monitor ends lines with newline or carriage return or both.");
}

void end_line_and_print(void)  { // note that if you want to DO anything with your buffered input
  // this is the place where I print it out and say goodbye data
  buff[buffCount++] = 0; // C strings end with a terminating zero.
  Serial.println(buff);
  buffCount = 0; // start the next line 
}

void loop(void) { // read one or no character each pass

  if (Serial.available()) {
    B = Serial.read();
    if ((B == '\r') || (B == '\n'))  { // EOL detected
      if (buffCount)  { // line may end in carriage return and line feed, this filters the lf out
        end_line_and_print();
      }
    }
    else {  
      buff[buffCount++] = B; // packing a byte into the MUMBO JUMBO buffer 

      if (buffCount >= buffCharLimit) { // prevent buffer overflow
        end_line_and_print();
      }
    }
  }
}

Techone:
As Grumpy_Mike says, you can not have 2 program using the same port on a PC. That may be a cause of the problem.

Grumpy_Mike is right.

I don't know any way to make the USB connected serial use different pins so perhaps if you use SoftwareSerial to connect the LCD to some other pins then your whole problem will be solved.

Moving target is spec that keep changing. 1st I write this and then you say it must do that. Mumbo-jumbo meaning -you- don't understand, therefore it must be nonsense?

I repeatedly (even using direct quoating of your statement) requested you to post the code you were talking about, and apparently you had a "brain freeze" and didn't understand what you previously posted.

EOL is standard for End Of Line. I even spelled it out in the first sentence of that post. Did you bother to read?

I know what EOL is (cr and/or lf), you just kept asking pointless questions instead of posting code.

You even QUOTE ME on that: they take 2 bytes per character

Interesting, so when C++ Strings are used in an IDE when writing code, the final machine code compiled for the processor will cause the processor to use two bytes per character as opposed to one byte per character when your method is used?

zoomkat:
apparently you had a "brain freeze" and didn't understand what you previously posted.

or I felt that what you asked must be too simple to be believed.

you just kept asking pointless questions instead of posting code.

and you kept requesting pointless code

You even QUOTE ME on that: they take 2 bytes per character

Interesting, so when C++ Strings are used in an IDE when writing code, the final machine code compiled for the processor will cause the processor to use two bytes per character as opposed to one byte per character when your method is used?

I haven't torn into them on the Arduino. On my PC they do. And BTW, "my" method of dealing with strings is standard C. There's even a library I use called string.h. That's strings as opposed to Strings.

Nice to be told in a left-handed way that Arduino-IDE code doesn't use 2 bytes per character, if that's true.

And you've got your code example now so when you're ready, let's hear why you don't like that.

[/quote]

And you've got your code example now so when you're ready, let's hear why you don't like that.

Where did I say that I didn't like it? :wink: You said,

I dunno why anyone would use C++ Strings on an Arduino, they take 2 bytes per character to do things that you might use on a PC. What a waste.

which seems to indicate that you are saying that using the string functions in the arduino environment some how translates to final machine code loaded in the arduino chip that waste bytes. I'm not familiar how the arduino string librarys interact with the arduino C compiler compared to using the usual C language. I've read post concerning possible issues with using the string librarys, but they were high level and did not provide a technical basis. So what is your technical basis for your statement concerning the string functions using two bytes in the arduino environment vs. the standard C language?

zoomkat:
So what is your technical basis for your statement concerning the string functions using two bytes in the arduino environment vs. the standard C language?

Actually it doesn't, I'm trying to recall, but a C++ String object does contain overhead and really needs to be accessed through member functions. Still when I look where the data function points I do get single bytes.

The 2 byte characters are the wide-character format.

Still why would I want to include String object support unless I really need it? Why bring in a bunch of baggage just out of habit or not knowing how to get along without it? I don't include string.h unless I need it either.

It wouldn't be such an issue for me if these chips had a lot more flash and SRAM.