How to correctly add float to string?

void setup() {
  // put your setup code here, to run once:
float t = -12.34;
String tekst = "Nie dziala";
char Sum[20];
Serial.begin(115200);

Sum = tekst + dtostrf(tekst,3,3,10);

Serial.println(Sum);
Serial.println(tekst);

}

How can I add t to tekst variable, I spend on it almost 2h check many solusion form internet, what I do wrong? I want only add measured temperature to string how can I do that?

If you're only reason is to print it (or same it to sd or any other form of print) then don't, absolute no need to do so.

Just do

Serial.print(F("Nie dziala"));
Serial.println(-12.34);

I want only add measured temperature to string how can I do that?

Why do you (think you need to) use Strings?

char buffer[40] = "Nie dziala ";
char fbuff[10];

dtostrf(t, 8, 3, fbuff);

strcat(buffer, fbuff);

The first argument to dtostrf() is the float to convert to a string. The last argument is the array to write to. Your code completely mangles the function call, with 50% of the arguments wrong.

Is this ok? (looks like it's working)

float t = -12.34;
String tekst = "Nie dziala";
String Sum;
Sum = tekst + " " + String(t);
Serial.println(Sum);

But that's adding a String to a String.
(Strictly speaking, it's a concatenation)

But is still very useless/wasteful...

Why ignore answer #1?

septillion:
But is still very useless/wasteful...

Amen.

septillion:
But is still very useless/wasteful...

Why ignore answer #1?

because Serial.println() is there only for checking if all is ok.

But the thread title refers to "string", not "String"

Tell us what you want to do, not how you think it ought to be done.

You still ignore the most important part :wink: What DO you want to do with it?

It's still a big XY-problem but in 99% of the cases you don't NEED to "add" (concatenate) it.

XnIcRaM:
because Serial.println() is there only for checking if all is ok.

and what you did is perfectly fine, and you should learn about String Class and its great set of member functions and operators and their ease of use. Many languages use similar methods, so they are good skills to learn.

There will come a time (e.g. you start manipulating global String objects with your Arduino code) when you will then need to learn about C style strings... and thus be forced to learn the C string methods. This is also known as "learning the hard way."

AWOL:
But the thread title refers to "string", not "String"

Tell us what you want to do, not how you think it ought to be done.

I use ESP-12E to read temperature from DS18B20 and send it to my web server using POST request. It's first step in my big weather station project.

at this moment my sketch look like this (and it's works ok)

#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define USE_SERIAL Serial
#define ONE_WIRE_BUS 2 // PIN termometru DS18B20

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int opoznienie = 0;
boolean stan = 0;
unsigned long lastTemp = 0;

ESP8266WiFiMulti WiFiMulti;

void setup() {
  
  USE_SERIAL.begin(115200);
  USE_SERIAL.println("GO....");
  
  WiFiMulti.addAP("MyWiFi SSID", "MyWiFi PASSWORD");
  pinMode(2,OUTPUT);
  digitalWrite(2,HIGH);
  sensors.begin();
  sensors.setWaitForConversion(false); // ustawiamy aby sensor pobierał dane w tle
  sensors.setResolution(12); // Rozdzielczość pomiaru
  sensors.requestTemperatures(); // żądanie odczytu
  opoznienie = 750 / (1 << (12 - 12)); 
  lastTemp = millis();
  
  sensors.requestTemperatures();
  float temperatura = (sensors.getTempCByIndex(0));
  USE_SERIAL.println(temperatura);

}
void loop() {

// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {

  if (millis() - lastTemp >= opoznienie)
    {

    HTTPClient http;
    sensors.requestTemperatures();
    opoznienie = 15000 / (1 << (12 - 12));
    lastTemp = millis();
    float temperatura = (sensors.getTempCByIndex(0));
    
    USE_SERIAL.println(temperatura);
    
    http.begin("http://MyWebSerwer/add.php");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    http.POST("temp=" + String(temperatura));
    
    http.writeToStream(&Serial);
    http.end();

   }
 }
}

Never used the HTTPClient library so can't really say anything about it. But it indeed seems like you need a complete string at once. Then the way PaulS showed you is the nicest way to go :slight_smile:

septillion:
Never used the HTTPClient library so can't really say anything about it. But it indeed seems like you need a complete string at once. Then the way PaulS showed you is the nicest way to go :slight_smile:

really?
Why I should use this :

char buffer[40] = "Nie dziala ";
char fbuff[10];

dtostrf(t, 8, 3, fbuff);

strcat(buffer, fbuff);

instead of this:

float t = -12.34;
String tekst = "Nie dziala";
String Sum;
Sum = tekst + " " + String(t);
Serial.println(Sum);

Just have a quick search around this forum for String (with a capital).

In short:

  • Bulkier
  • takes more memory
  • easy to screw up you memory with it

Why I should use this :

instead of this:

Build a simple sketch, with empty loop() function. Put the two snippets in setup(), one at a time. Compile each, and note the sketch size and memory used. Draw your own conclusions. That is the only way you will learn.

void setup()
{
  Serial.begin(115200);
  float t = -12.34;
  String tekst = "Nie dziala";
  String Sum;
  Sum = tekst + " " + String(t);
  Serial.println(Sum);
}

void loop()
{
}

Sketch uses 5,290 bytes (17%) of program storage space. Maximum is 30,720 bytes.
Global variables use 222 bytes (10%) of dynamic memory, leaving 1,826 bytes for local variables. Maximum is 2,048 bytes.

void setup()
{
  Serial.begin(115200);
  float t = -12.34;
  char buffer[40] = "Nie dziala ";
  char fbuff[10];

  dtostrf(t, 8, 3, fbuff);

  strcat(buffer, fbuff);
  Serial.println(buffer);
}

void loop()
{
}

Sketch uses 3,472 bytes (11%) of program storage space. Maximum is 30,720 bytes.
Global variables use 240 bytes (11%) of dynamic memory, leaving 1,808 bytes for local variables. Maximum is 2,048 bytes.

The char array method saves 1,818 bytes of program memory, at the cost of 18 bytes of SRAM. That information about SRAM usage is misleading, though, because the compiler can not determine, at compile time, how much SRAM will be used to create the two String instances and the dynamically allocated memory that they use to wrap the strings. At run time, the char array code will use less SRAM.

septillion:
Just have a quick search around this forum for String (with a capital).

In short:

  • Bulkier
  • takes more memory
  • easy to screw up you memory with it

What's more important for beginners, making code easier to read and understand, or saving memory?
dtostrf() isn't exactly user-friendly.
The String class was designed for a purpose.
It's also very easy to 'screw up' memory using fixed length char arrays.
I have read that Arduino Strings can mess up the heap but can you provide a simple demo of this happening? I tried but failed - the code below , which creates many strings each loop, runs for 19000 loops and counting (Uno, 2kb SRAM).

String test = "test";
float f = 0.0;
int n = 0;
void setup() {
  Serial.begin(9600);
}

void printstrings(String str1, String str2) {
   Serial.println(String(n++) + " " + str1 + str2);
   
}
void loop() {
  String test1 = test + " " + f + " ";
  String test2 = test1 + test1 + " " + f + " ";
  String test3 = test2 + test2 + " " + f + " ";
  String test4 = test3 + test3 + " " + f + " ";
  String test5 = test2 +  " " + f + " ";
  String test6 = test1 +  " " + f + " ";
  f = f + 0.1;
  printstrings(test1,test2);
  printstrings(test3,test4);
  printstrings(test5,test6);

  delay(10);
}

As long as you delete all String instances that you create, as that code does, and the total size of the wrapped strings does not exceed the amount of memory available, then you will be fine using Strings unnecessarily.

On each iteration of loop(), try adding one character to 5 Strings, when the Strings are global. You will fail to do so sooner than you might think.

quilkin:
What's more important for beginners, making code easier to read and understand, or saving memory?

I do agree it's more readable. But two thing

  1. Beginners already tend to massivly overuse memory because they are used to having i7's with 32GB of RAM.
  2. My last point...

quilkin:
It's also very easy to 'screw up' memory using fixed length char arrays.

No it's not. It's easy to use a lot of memory but it's never going to Swiss cheese the memory like String can do.

quilkin:
I have read that Arduino Strings can mess up the heap but can you provide a simple demo of this happening?

Not that hard, simply start expanding Strings aka add things to them. That will force it to relocate and make Swiss cheese of the memory.

septillion:
I do agree it's more readable. But two thing

  1. Beginners already tend to massivly overuse memory because they are used to having i7's with 32GB of RAM.
  2. My last point...
    No it's not. It's easy to use a lot of memory but it's never going to Swiss cheese the memory like String can do.

Maybe not Swiss Cheese but possibly gorgonzola?

  char test1[10] = "test1";
  char test2[10] = "test2";
  char test3[10] = "test3";
  char test4[10] = "test4";
  char test5[10] = "test5";

int n = 0;

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

   
void loop() {
  strcat(test1,"+");
  strcat(test2,"+");
  strcat(test3,"+");
  strcat(test4,"+");
  strcat(test5,"+");

  Serial.print(n); Serial.print(" "); Serial.print(test1); Serial.print(" "); Serial.println(strlen(test1));
  Serial.print(n); Serial.print(" "); Serial.print(test2); Serial.print(" "); Serial.println(strlen(test2));
  Serial.print(n); Serial.print(" "); Serial.print(test3); Serial.print(" "); Serial.println(strlen(test3));
  Serial.print(n); Serial.print(" "); Serial.print(test4); Serial.print(" "); Serial.println(strlen(test4));
  Serial.print(n); Serial.print(" "); Serial.print(test5); Serial.print(" "); Serial.println(strlen(test5));

  delay(10);
  n++;
}

septillion:
Not that hard, simply start expanding Strings aka add things to them. That will force it to relocate and make Swiss cheese of the memory.

The 'String' version of the above (copied below) does just that. It manages 5 strings of length 159 before the holes appear. Is that such a big problem, for a typical small program that most people will be using? With the same 2k of SRAM,the char[] version would manage 5 strings of length 350 , if they were all declared to start with, so maybe we're 'wasting' half the SRAM by using String. I think it's worth it for readability, avoiding the sort of bug shown above, and not needing to work out exactly how long our strings are going to be.

  String test1 = "test1";
  String test2 = "test2";
  String test3 = "test3";
  String test4 = "test4";
  String test5 = "test5";
  int n = 0;

void setup() {
  Serial.begin(9600);
}
 
void loop() {
  test1 = test1 + "+";
  test2 = test2 + "+";
  test3 = test3 + "+";
  test4 = test4 + "+";
  test5 = test5 + "+";

  Serial.print(n); Serial.println(" " + test1 + " " + test1.length());
  Serial.print(n); Serial.println(" " + test2 + " " + test2.length());
  Serial.print(n); Serial.println(" " + test3 + " " + test3.length());
  Serial.print(n); Serial.println(" " + test4 + " " + test4.length());
  Serial.print(n); Serial.println(" " + test5 + " " + test5.length());
  delay(10);
  n++;
}