Go Down

Topic: Serial.read() to string? (Read 2 times) previous topic - next topic

PaulS

Might I suggest that you print stuff intelligently?

Code: [Select]
Serial.print("reads: [");
Serial.print(reads);
Serial.println("]");


will convey a LOT more information than

Code: [Select]
Serial.println(reads);

It just might even provide a clue or two.

Nick Gammon

Insulting and irrelevant replies removed.

- moderator
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

pedroply

Sorry for not being able to reply earlier but I have made some improvements :

Quote
This is because the error is yours not the compiler's.

I already suspected that


Might I suggest that you print stuff intelligently?

Code: [Select]
Serial.print("reads: [");
Serial.print(reads);
Serial.println("]");


will convey a LOT more information than

Code: [Select]
Serial.println(reads);

It just might even provide a clue or two.


I already suspected that the problem was in the string, more precisely at the point of converting the char into the string and I made this little modification:

Code: [Select]

if(index < 19 && inChar!='\n') // One less than the size of the array -/ added the  "&& inChar!='\n'" so that it stops when it reages the last char.
       {
           inChar = Serial.read(); // Read a character
           inData[index] = inChar; // Store it
           index++; // Increment where to write next
           inData[index] = '\0'; // Null terminate the string
       }


But it wouldnt work becouse at the first time the code is running, the inChar is nothing so here is my last code:

Code: [Select]

char inData[50]; // Allocate some space for the string
char inChar = 'c'; // Where to store the character read
byte index = 0; // Index into array; where to store the character
String reads;
int words = LOW;


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


void loop()
{
   while(Serial.available() > 0)
   {
       if(index < 49 && inChar!='\n') // One less than the size of the array
       {
           inChar = Serial.read(); // Read a character
           inData[index] = inChar; // Store it
           index++; // Increment where to write next
           //inData[index] = '\0'; // Null terminate the string
       }
       words = HIGH;
   }
   
   for(int i=0; i<=index && inChar=='\n' && inData[i]!='\n'; i++)
       {
         reads += inData[i];
         inData[i] = 0;
       }
   
   delay(10);
   if(words && inChar=='\n')
   {
     Serial.print("reads: [");
     Serial.print(reads);
     Serial.println("]");
     words = LOW;
     reads = "";
   }
   
   
   index = 0;
   inChar = 'c'; // make it so that it is different from '\n'
}


It got some errors like you type "test" and it only returns "est" or "arduino" and it returns "duino" but it works.

Arrch

So the question then becomes, why are you testing the value of inChar before reading it?

pedroply

Because if I don't test its value when the word I send finishes, it continues to add blank spaces to the string.

Arrch

#20
Apr 19, 2013, 12:30 am Last Edit: Apr 19, 2013, 12:42 am by Arrch Reason: 1

Because if I don't test its value when the word I send finishes, it continues to add blank spaces to the string.


What does that have to do with testing the value of a char before reading it? I'm not saying don't test the value, I'm saying read the value before you test it.

You really should restructure your code. The whole deal you are doing with the words variable is predicated on all of the information arriving within a single iteration of the loop, and is a workaround to avoid writing non blocking code. Look at the psuedo code I posted earlier; no need for a delay(), and less coding.

zoomkat


I moved it into a String object because I want to use functions that only strings have like reads.indexOf() or things like that.


It is easy.

Code: [Select]

// zoomkat 8-6-10 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

int ledPin = 13;
String readString;

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

void loop() {

  while (Serial.available()) {
    delay(3); 
    char c = Serial.read();
    readString += c;
  }

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

    if(readString.indexOf("on") >=0)
    {
      digitalWrite(ledPin, HIGH);
    }

    if(readString.indexOf("off") >=0)
    {
      digitalWrite(ledPin, LOW);
    }

    readString="";
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

econjack

Actually, the X3J11 C Standard says each compiler vendor is free to define the null termination character however they wish, as the committee envisioned systems in the future where some value other than 0 may be more efficient or appropriate. While I don't know of any compiler that doesn't allow 0 to be used for null, the better form that everyone recognizes is:

inData[index] = '\0';

as adding a null terminator to the inData[] array. However, a more portable way is:

inData[index] = NULL;

The Arduino compiler does recognize NULL, plus I think it makes any code a tad more readable. (Any compiler that supports the C Standard should have NULL defined.) I know...picky...picky...picky, but read through some of the other software posts and see how many errors would jump from the page if they simply used good formatting style and symbolic constants.

pedroply

Thanks for the reply's, yes I am working on a much easier code to do this, this one is only a prototype.
And thanks for the null thing, it will be rely helpful.

pedroply

Here is, I think, the final version of this code:

Code: [Select]

char inChar = 'c'; // Where to store the character read
byte index = 0; // Index into array; where to store the character
String reads;


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


void loop()
{
 
   if(inChar=='\n')
   {
     Serial.print("reads: [");
     Serial.print(reads);
     Serial.println("]");
     reads = "";
   }
   
   
   inChar = 'c'; // make it so that it is different from '\n'
}

void serialEvent()
{
  while(Serial.available())
   {
       inChar = (char)Serial.read(); // Read a character
       if(index < 49 && inChar!='\n') // One less than the size of the array
       {
           reads += inChar;
       }
    } 
}


No delays, smaller and works better if you want to use it in other projects because it only reads when there is something coming thanks to the serialEvent().

UKHeliBob

Consider what happens if you receive more than 49 characters and don't get a newline character.  Where are the extra characters stored ?  Could they affect something else in the program ..............
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up