dtostrf() alternative for concatenating a float and a string

I'm trying to concatenate a string and a floating point number to send to the serial monitor and the only way I can find to do it is using dtostrf(), but that seems a little clumsy. For example (this works):

  int potValue = analogRead(pinSensor);
  float volts = 5*(float)potValue/1023;
  String strLab = "Pot Voltage = ";
  char tmp[10];
  dtostrf(volts,1,2,tmp);
  String strOut = strLab + tmp;

  Serial.println(strOut);

This doesn't work:

  int potValue = analogRead(pinSensor);
  float volts = 5*(float)potValue/1023;
  char tmp[10];
  dtostrf(volts,1,2,tmp);

  Serial.println("Pot Voltage = " + tmp);
  
  BlinkLED(pinLED,potValue,potValue);

nor does:

  int potValue = analogRead(pinSensor);
  float volts = 5*(float)potValue/1023;
  char tmp[10];
  dtostrf(volts,1,2,tmp);
  String strOut = "Pot Voltage = " + tmp;

  Serial.println(strOut);

both give the error: invalid operands of types 'const char [15]' and 'char [10]' to binary 'operator+'

What I'd really like to do is somthing like:

  int potValue = analogRead(pinSensor);
  float volts = 5*(float)potValue/1023;

  Serial.println("Pot Voltage = " + String(Volts));

but String doesn't work with floating point numbers.

I've looked at the String constructor tutorial, the String Addition Examples and googled this as well to no avail. Any suggestions? Thanks, Jason

StrikeEagleIII: Any suggestions?

Use null terminated character arrays instead of Strings and use sprintf to "concatenate"

char voltageMsg[25];
sprintf(voltageMsg, "Pot Voltage = %f", volts);
Serial.println(voltageMsg);

try this,

int potValue = analogRead(pinSensor);
float volts = 5*(float)potValue/1023;

char tmp[25] = "Pot Voltage = ";

dtostrf(volts,1,2, &tmp[12]);

Serial.println(tmp);

The char array is declared big enough to hold the fixed string and the float. (25) The whole trick is to let the dtostrf add to the tmp array at the right position. (you might need to change 12 in 13 or so)

give it a try.

use sprintf to "concatenate"

Great idea, except that sprintf() on the Arduino does not deal with floating point values.

OP: Why do you feel it is necessary to concatenate the data before sending it?

Serial.print("Pot Voltage = ");
Serial.print(volts);

The device on the other end of the serial port will not know that two Serial calls were made to send the data.

The device on the other end of the serial port will not know that two Serial calls were made to send the data.

For Serial you are 100% right. however if you use the print on a TCP socket, multiple calls might cause fragmentation of IP packets.

PaulS:

use sprintf to "concatenate"

Great idea, except that sprintf() on the Arduino does not deal with floating point values.

Didn't realize that, thanks.

robtillaart: try this,

int potValue = analogRead(pinSensor);
float volts = 5*(float)potValue/1023;

char tmp[25] = "Pot Voltage = ";

dtostrf(volts,1,2, &tmp[12]);

Serial.println(tmp);



The char array is declared big enough to hold the fixed string and the float. (25)
The whole trick is to let the dtostrf add to the tmp array at the right position. (you might need to change 12 in 13 or so)

give it a try.

I'll give this a shot--I wonder if it'd be possible to write a wrapper function for dtostrf so that you could just use it in-line. Is there a reason that adding the string literal and variable (see my first post for code) doesn't work? seems like it should from the string constructor tutorial.

String strOut = "Pot Voltage = " + tmp;

does not work as the addition of two char[] is not defined..

String strOut = String("Pot Voltage = ") + String(tmp);

might work. String("not tried"); ;)

StrikeEagleIII: I'm trying to concatenate a string and a floating point number to send to the serial monitor ...

robtillaart: ... however if you use the print on a TCP socket ...

Which, fortunately, we don't have to worry about. :)

Dear,

I tried all the tips posted above, but none of them worked for me. I put my code below to see if anyone has a suggestion. The problem just seems damn 'float'. Since I can not turn it into string, it does not work my insertion into the database using the library mysql.h.

#include "SPI.h"
#include "Ethernet.h"
#include "sha1.h"
#include "mysql.h"

// Network conf. 
byte mac_addr[] = { 0x54, 0x55, 0x4F, 0x11, 0x0F, 0x2C };
EthernetClient client;
//Server address
IPAddress server_addr(1, 1, 1, 1);

//Data variables
int pinosensor = 0;
int valorlido = 0; 
float temperatura = 0; 
int porta = 8;

//Configuracao da conexao com o arduino
Connector my_conn; // The Connector/Arduino reference

char user[] = "arduino";
char password[] = "arduino";

void read_dados(){
  pinMode(porta, INPUT); 
  //Medidor de Temperatura
  valorlido = analogRead(pinosensor);
  temperatura = (valorlido * 0.00488); 
  temperatura = temperatura * 100; 
  Serial.print("Temperatura atual: ");
  Serial.println(temperatura);
  Serial.print("\n");
}

char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
  char fmt[20];
  sprintf(fmt, "%%%d.%df", width, prec);
  sprintf(sout, fmt, val);
  return sout;
}

void insert_data(){

  //Don't work - this is a test from toppic 103935.0
  String strLab = "Temperatura = ";
  char tmp[10];
  dtostrf(temperatura,1,2,tmp);
  String strOut = strLab + tmp;
  Serial.println(strOut);
  //the result of this serial.println is Temperatura = ?
  
  //Don't work - this is a test from toppic 103935.0
  char voltageMsg[25];
  sprintf(voltageMsg, "Temperatura : %f", temperatura);
  Serial.println(voltageMsg);
  //the result of this serial.println is Temperatura : ?

    
  //Just function 'now()' is inputed correctly in Database
  char buf[256];
  sprintf(buf, "INSERT INTO datacenter.tb_teste (data, temp) VALUES (now(), %d)", temperatura);
  my_conn.cmd_query(buf);

}

void setup() {
  
  // start the serial library:
  Serial.begin(9600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac_addr) == 0) {
    Serial.println("DHCP Failed");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  
  // print your local IP address:
  Serial.println(Ethernet.localIP());
  delay(1000);
  //database connection 
  Serial.println("Connecting...");
  if (my_conn.mysql_connect(server_addr, 3306, user, password)){
  delay(500);
      Serial.println("Connected!"); 
    }else{
      Serial.println("Connection failed!");
    }
      
}

void loop() {
  
 read_dados();
 insert_data();
 delay(10000);
  
}//end

please use code tags when you post code - it is the # button above the smileys - You can modify your post, select the code part and press #

Thank you,

Or,

Use streaming, Example:

Serial << "Answer: " << _FLOAT(sqrt(a*a + b*b), decimals);

http://playground.arduino.cc/Main/StreamingOutput

There’s a FormatDouble library:

http://forum.arduino.cc/index.php/topic,148214.0.html

I’m having a issue, I’m getting data from a sensor that is in double format. I thought I could format it into String and post it on the LCD.

#include <FormatDouble.h>

dTemp=fmtDouble(dTTempF, 6, buf, sizeof buf);
  1. I thought LCD’s could display Strings or Chars (guess menu system (MenWiz) or LCD doesn’t like inputs)
  2. Does anyone know how to convert a double to a char?

MenWiz doesn’t play nice with Sprintf…to make this more difficult!

Which sensor? Is it a 64 bit double that is returned? Can you give a link to the datasheet?

DHT 11 http://www.arduinoeverything.com/wp-content/uploads/2011/12/DHT11.pdf lm35 http://www.electroschematics.com/wp-content/uploads/2011/04/lm35.pdf DS18B20 http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf

Is it a 64 bit double that is returned? ????? Don't know how to determine this

  1. Does anyone know how to convert a double to a char?

You can't. A char holds ONE character. A float converted to an array of chars requires at least 4 characters.

The dtostrf() function mentioned in this post title IS how you convert a float to an array of chars.

The snippet you posted is useless. Take it to http://snippets-r-us.com if that is all you plan to share. If you plan to share more, you need to tell us EXACTLY what the problem is. "MenWiz doesn't play nice with Sprintf.....to make this more difficult!" is a load of crap.

JAnwyl: DHT 11 http://www.arduinoeverything.com/wp-content/uploads/2011/12/DHT11.pdf lm35 http://www.electroschematics.com/wp-content/uploads/2011/04/lm35.pdf DS18B20 http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf

Is it a 64 bit double that is returned? ????? Don't know how to determine this

Read the datasheets and compare that to the IEEE754 specification of a 64 bit double (wikipedia helps here), but as I am familiar with all 3 sensors here a brief note:

  • DHT11 returns 2 bytes to be interpreted as an integer (one is always zero in fact for the DHT11. The DHT21 and 22 also return 2 bytes but these must be interpreted as a 1 decimal floating point number. Fits easily in a IEEE754 32 bit float like the Arduino has.

  • LM35 returns an analog voltage and depending on the accuracy of the ADC you will have more bits. INternal Arduino ADC is 10 bits, external ADC's go up to 24 bits (need very stable power supplies). In practice the value sampled/converted fits easily in a 32bit float.

  • The DS18B20 retuns 4 bytes which represents max a 12 bit float number so it easily fits into a 32bit float.

In short non of these sensors return doubles or need a 64 bit double to hold the accuracy/precision sampled.

personal note: I prefer the DS18B20 for accuracy, or the LM35 (or other analog/thermistor) for speed. The DHT11 is only interesting because it does humidity, but I prefer the DHT22 over the 11 as it support negative temperatures and 1 decimal.

I've wrote some code in the past to allow the Arduino send/receive a 64 bit double to a PC over Serial (in my case there was Python on the other end). Internally the Arduino mapped the 64 bit double on a 32 bit float so it looses bits but it is the best one could do other than implementing a 64 bit double library. Check - http://playground.arduino.cc/Main/IEEE754tools -

the lm35 is Celsius - Linear + 10.0 mV/?C scale factor The lm34 is Fahrenheit - Linear + 10.0 mV/?F scale factor - http://www.ti.com/lit/ds/symlink/lm34.pdf -

as 1 degree C is 1.8 degree F the lm34 is 1.8 times more accurate than the lm35. Given that the Arduino uno has a resolution of about 5mV this implies that the lm35 can detect 0.5C where the lm34 can detect ~0.28C .