Hot answers tagged

72

Contrarily to other answers, I'd rather stay away from String for the following reasons: dynamic memory usage (that may quickly lead to heap fragmentation and memory exhaustion) quite slow due to construction/destruction/assignment operators In an embedded environment like Arduino (even for a Mega that has more SRAM), I'd rather use standard C functions: ...


37

ardprintf is a function that I hacked together which simulates printf over the serial connection. This function (given at the bottom) can be pasted in the beginning of the files where the function is needed. It should not create any conflicts. It can be called similar to printf. See it in action in this example: void setup() { Serial.begin(9600); } void ...


22

This function can be used to seperate a string into pieces based on what the separating character is. String xval = getValue(myString, ':', 0); String yval = getValue(myString, ':', 1); Serial.println("Y:" + yval); Serial.print("X:" + xval); Convert String to int int xvalue = stringToNumber(xval); int yvalue = stringToNumber(yval); This Chunk of code ...


13

I wouldn't normally put two answers to a question, but I only just found this today, where you can use printf without any buffer. // Function that printf and related will use to print int serial_putchar(char c, FILE* f) { if (c == '\n') serial_putchar('\r', f); return Serial.write(c) == 1? 0 : 1; } FILE serial_stdout; void setup(){ Serial....


11

You could do something like the following, but please take into account several things: If you use readStringUntil(), it will wait until it receives the character or timeouts. Thus, with your current string, the last position will last a little longer, as it has to wait. You can add a trailing & to avoid this timout. You can easily check this behavior ...


9

data is a String. "test" is a char*. Wire.write() has no prototype that takes a String. Wire.write(data.c_str());


8

char *res = "up_cmd0_res:"; In principle, res should be a const char *. Const because it is pointing to a literal string, and you cannot (ar at least, you are not supposed to) change a literal string. The compiler should warn you on that... if you enable compiler warnings. strcat(res ,num); This is very wrong. strcat() expects as its first argument an ...


7

You can use Stream.readStringUntil(terminator) passing a different terminator for each part. On each part you then call String.toInt


7

Is there any other way to send more than 100 values in one message? Yes. Don't use String. Don't use concat(). Just print each bit as a separate Serial.print() function call.


7

If you have a C string containing ASCII numbers with a common delimiter (comma in this case) you can use the strtok() function to split it into individual strings. Then you can use atoi() to convert those individual strings into integers: char array[] = "10,11,12,1,0,1,0"; int intArray[7]; // or more if you want some extra room? int ipos = 0; // Get the ...


7

snprintf() will not write more than <size> (snprintf's 2d argument) characters to your buffer, but it does count (and discard the extra) characters it would have written, had there been space enough, and that is the number it returns. Yeah, it can be confusing! See this snprintf() reference.


6

char clat[10+11+1] = "Latitude: "; dtostrf(gps.location.lat(), 11, 6, clat+10); Since you've named the buffer 'clat' I'm assuming it will always be used for latitude, so we've pre-initialized its size and contents, and we know where to begin the latitude value. By the way, don't forget to size string buffers one more byte than the length of the maximum ...


6

If you only need the string for printing you can store value in an integer and then use the Serial.print(number,BIN) function to format the output as a binary value. Appending integers to strings is a potentially costly operation both in performance and memory usage. int Number = 0; int tmp; for (int i=9;i>=0;i--) { tmp = analogRead (A0); Number += ...


6

Here's the first line of your code: #define dw 8; //buttons down Here's the first error line: pinMode(dw, INPUT); Let's put them together and see what we get: pinMode(8; //buttons down, INPUT); That's not valid C++. Using the output I've shown you, modify the input until it looks correct. And then keep doing it until the code compiles.


6

You're adding the ASCII value of each char to your string, hence you get numbers. See the various String constructors at: https://www.arduino.cc/en/Tutorial/StringConstructors Either cast the read byte to a char: stringOne = String(stringOne + String((char)incomingByte)); or consider receiving characters as chars, instead of ints: char incomingByte; ...


6

PubSubClient::setServer(const char * domain, uint16_t port) just saves the pointer, it doesn't copy the string (probably because it expects a static string literal). (Source) In your case, when ip goes out of scope, the pointer is no longer valid, so it won't work. Just use the PubSubClient::setServer(IPAddress ip, uint16_t port) function instead. (Source) ...


6

Only the pointer, *res, is a local variable. The string "up_cmd0_res:" itself is elsewhere in RAM, stored as a literal and not meant to be modified. Your strcat() call overwrites (extends) the literal each time you call it - which, by the way means that the growing string will be overwriting something else - whatever was following the string literal in ...


6

The String object created as return from IPAddress.toString() as parameter to constructor of NtpClient is temporary. It contains the char array returned by c_str(). NTPClient doesn't copy the string, only stores a reference to it. And the referenced string (char array) doesn't exist at the time the NTPClient wants to use it. class TestClass { public: ...


6

You are almost there: Use a char* instead of char, a char can only contain one character Use " instead of ' (Thanks Juraj) Then you get: const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};


5

Simplest solution is to use sscanf(). int id1, id2, id3; int pos1, pos2, pos3; char* buf = "1:90&2:80&3:180"; int n = sscanf(buf, "%d:%d&%d:%d&%d:%d", &id1, &pos1, &id2, &pos2, &id3, &pos3); Serial.print(F("n=")); Serial.println(n); Serial.print(F("id1=")); Serial.print(id1); Serial.print(F(", pos1=")...


5

The simplest way to get more decimal places to print is this: Serial.println(val,NUMBER_OF_DECMIAL_PLACES); This will print out any number of digits after the decimal place. Regular print without the number of digits specified will default to 2 decimal places. for example, here is some code and the result that gets printed: float val = 23.459; Serial....


5

What would be the best-practice in this kind of situation? To not use String. I also want to allow the end user to use the String functions (like indexOf) to search for particular content in emails. There's nothing wrong with providing an indexOf function in your API. But you don't have to use String to implement that function when called. You can ...


5

It seems I needed to add a parser to SerialPort nodejs module, in order to specify how the input should be treated. I changed my code to this: var SerialPort = require('serialport') var Readline = SerialPort.parsers.Readline var serialPort = new SerialPort('/dev/ttyACM0', { baudrate: 9600 }) var parser = new Readline() serialPort.pipe(parser) parser....


5

itoa is the best route: int num = 1234; char cstr[16]; itoa(num, cstr, 10); -> "1234" You can read more about using it here. If you want more control over the format of the number (and don't mind the increased PROGMEM usage) you can use sprintf (or the more secure snprintf) to format it: sprintf(cstr, "%05d", num); -> "01234" Or with PROGMEM ...


5

The remove method was added to the String class in 1.0.6. Installing Arduino IDE from the Ubuntu repository gets you a really old package (1.0.5). You should download and install the newest version from the official Arduino page.


5

String is not a simple type like an int or a char. It is a class with many member functions and, more importantly, operators. When you create the object it allocates room for that object either on the stack (for a local variable) or in the global data area if it's a global variable. However that object doesn't contain the memory used to store the actual ...


4

This is probably not better, just different. You can use the String object for output. These objects allow concatenation and support automatic typecasting. Serial.begin(9600); String label = "Var"; const byte nValues = 3; int var[nValues] = {36, 72, 49}; for (int i = 0; i < nValues; i++) { String stuff = label + i + ": "; Serial.println(stuff + ...


4

I usually used Tabs to make things line up better in the Serial. Having things line up like I do allow the arduino to fire as fast as possible while being able to notice certain changes in the variables. Try something like this: Serial.println("Var 1:\tVar 2tVar 3:"); Serial.print("\t"); Serial.print(var1); Serial.print("\t"); Serial.print(var2); Serial....


4

I only use this for debugging but: int a = 10; int b = 20; Serial.println("a = " + String(a) + " and b = " + String(b));


4

See example at: https://github.com/BenTommyE/Arduino_getStringPartByNr // splitting a string and return the part nr index split by separator String getStringPartByNr(String data, char separator, int index) { int stringData = 0; //variable to count data part nr String dataPart = ""; //variable to hole the return text for(int i = 0; ...


Only top voted, non community-wiki answers of a minimum length are eligible