I've got this quite basic code running on an Arduino Mega 2560, and the output is looking like I have the serial settings wrong, though I can't work out what to change.
void setup()
{
Serial.begin(9600);
Serial.println("test123");
}
void loop()
{
Serial.println("test" + millis());
}
The output looks like this:
×ばつ¤¿ïßûÏûýoÏ¿îãõI
õfwi÷`p¬1⁄2Ïa»QáÀa»¦·ð¦·Z©÷
test123
D
4ñjü ̄÷~μÞMz1Ý~1⁄4
Ûþ}iû}Ò֦ǿ÷ÿÂï1⁄2Õ3⁄4;îö
I'm using the inbuilt "Serial Monitor" in the Arduino suite with settings 9600 baud and no line endings.
I see that the first println in setup()
is sending the data as expected but all other comms are coming through as nonsense.
Any suggestions of what to do?
2 Answers 2
This is unfortunately not valid in C++:
"test" + millis()
Rather than concatenating two strings, it's actually doing pointer arithmetic. It's taking the memory address where "test"
is stored, and offsetting by the value retrieved from millis()
. The result is a totally arbitrary memory location which gets treated like a string.
Generally speaking, it's arguably best to avoid string concatenation on Arduino anyway unless absolutely necessary. The reason is that it can use more memory than you might expect.
A simpler approach would simply be to do the serial output as a sequence of individual operations, e.g.:
Serial.print( "test" );
Serial.println( millis() );
Note the difference between print()
and println()
. The first one doesn't add a line break at the end, but the second one does.
-
Great, thank you. Can you also explain why string concatenation per arduino.cc/en/Tutorial/StringAdditionOperator isn't working how I expected it would in this instance, when one of their examples on the page is specifically
stringThree = stringOne + millis();
?bdx– bdx12/25/2014 10:38:46Commented Dec 25, 2014 at 10:38 -
2@bdx You can concatenate
String
objects like that because they overload the plus (+) operator. String literals in C/C++ (anything in double quotation marks"like this"
) work differently. You can read more about the difference here: arduino.cc/en/Reference/StringPeter Bloomfield– Peter Bloomfield12/25/2014 17:33:55Commented Dec 25, 2014 at 17:33 -
I see. My assumption that a string literal would create a
String
object was false, it creates a null-terminated character array, and theString
type also has an overload on the=
operator to coerce achar[]
to aString
.bdx– bdx12/25/2014 20:34:17Commented Dec 25, 2014 at 20:34 -
You can explicitly construct a
String
object by doing this:String("test")
. It uses more memory than a string literal alone though, so it's important to be careful how you use it.Peter Bloomfield– Peter Bloomfield12/25/2014 22:49:50Commented Dec 25, 2014 at 22:49
Just as a minor addition to Peter's excellent answer and comments on concatenation and implicit typecasting with String
objects:
Alternatives to construct the message (as a char[]
) to be send might be:
- use
sprintf()
char buffer[80]; // for the complete output
char value[4]; // for millis(), which returns an unsigned long
sprintf(buffer, "I'm running for %u ms now", millis());
Serial.println(buffer);
Note that sprintf()
uses quite some memory!
- build the message 'manually':
char buffer[80] = "I'm running for ";
itoa(millis(), value, 10);
strcat(buffer, value);
strcat(buffer, " ms");
Serial.println(buffer);