1

I have started learning about Arduino and am well versed in Java and Python. In an Arduino program, I need a character input via Serial to be stored in a String variable. From my previous programming experience, I knew that a code like the one below would give an error as char can't be converted into String like this.

void loop() {
  if(Serial.available()) {
     String s=(char)Serial.read();
  }
}

As expected, the above code gives an error on compiling. But when I first defined s and then assigned its value in a separate step in void loop(), I got no error.

void loop() {
  if(Serial.available()) {
     String s;
     s=(char)Serial.read();
  }
}

The above code yields no error despite the fact that it is almost similar to the first code. What I suspect is that it has something to do with String being a class. Can one tell what is going on?

1

You misunderstand Serial.read(): it does not return a String or sth. like a char array, but an integer, representing only the last byte in the input buffer that hasn't been read.

What you probably want to do is to interpret those incoming bytes as chars and accumulate those in a String.

E.g. like this:

String s="";
while(Serial.available()) {
  // as long as there are bytes in the buffer
  s+=(char)Serial.read(); // interpret int as char and append character to s
}

As using String can easily lead to crashes you should avoid dynamic memory allocation by using a fixed-size char arrays:

#define MAX_LEN 64
char s[MAX_LEN];
uint8_t i;
while (serial.available() && i<MAX_LEN) {
  s[i]=(char) Serial.read();
  i++;
}

Note: once you are that far you still have to handle, when you want the data to be ready to process (e.g. detecting a \n and setting a flag appropriately).

| improve this answer | |
  • I don't misunderstand Serial.read(). I know it returns an integer and that's why I have put (char) in front of it. Nor, in my program, do I want a character sequence to be stored in a String s, just a single character and that's why Serial.read(). I was just testing and figured out something unknown and want to know a reason for that only. – Big Brother Mar 26 at 19:18
1

this isn't an arduino specific error what you're trying to do is declare and initialize the variable in one statement which is causing the problem. As you've figured it out already. Declaring the variable first

String s;

and initializing it another statement does the job for you

s=blabla

Hope this helps. PS, try posting the error that you get during build process next time :)

EDIT: I think this needs more explanation. Basically why you cant declare and initialize at the same time in this case is because Serial.read is a synchronous request. Declaring an object requires acquiring the space for it, running any constructors and whatsoever, and doing while Serial.read() is an IO blocking operation. You could declare and initialize a String class variable given it was a string constant but not with anything like get_input or Serial.read

EDIT 2: Further here's what I've found for you.

http://www.cplusplus.com/reference/string/string/string/

Apparently the String class has a copy constructor which means when declaring the variable you initialize at the same time it uses the copy constructor, and which requires ADDRESS to a valid string(know that you can use a constant because C++ deals with all strings as the address to their first char). In your case the constructor raised an error because you pointed it to an undefined(Serial.read() ).

String mystring=Serial.read(); //error, uses copy constructor

However this would work

String mystring="hey juliet!" ; //uses the copy contructor which takes address to a char

Doing the same thing in two different lines works for the same reasons, it uses a different constructor

String mystring; //uses empty string constructor - okay so far
mystring=Serial.read(); // uses the overloaded = operator  --okay

| improve this answer | |
0

I don't have much experience with Arduino's String type, however, most people (including myself) don't advise to use it. Because the Arduino only has 1 KB of SRAM and the String type has its own hidden memory allocation, you might run out of memory without you know it, resulting in crashing/frozen programs without a clue what is happening.

Instead use character arrays (like char str[10]) where you know exactly what is reserved.

However, to answer your question, what I expect since String is a class, there is a (copy) constructor in that class that takes a char and converts it into a String.

| improve this answer | |
0

This will fix the problem: void loop() { if(Serial.available()) { String s=(char*)Serial.read(); } } This is because in C: Strings are defined as an array of characters. You cannot assign a primitive to an array...

I guess the casting into pointer can be implicit as in your second example..

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.