Conversione float to string

Ciao ragazzi, devo concatenare un dato acquisito da un sensore con una stringa, quindi devo convertire il dato float in string. La guida arduino mi rimanda ad un thread del forum e ad una guida che mi dice di usare dtostrf, ma non ho capito proprio come si fa.
Qualcuno sa come si fa questa conversione?

questa funzione dovrebbe fare al caso tuo: http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

Bonjour,

I'm using the following function to convert a float to a string:

String ftoa(float number, uint8_t precision, uint8_t size) {
  // Based on mem,  16.07.2008
  // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num = 1207226548/6#6

  // prints val with number of decimal places determine by precision
  // precision is a number from 0 to 6 indicating the desired decimial places
  // example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)

  // Added rounding, size and overflow #
  // ftoa(343.1453, 2, 10) -> "    343.15"
  // ftoa(343.1453, 4,  7) -> "#      "
  // avenue33, April 10th, 2010

  String s = "";

  // Negative 
  if (number < 0.0)  {
    s = "-";
    number = -number;
  }

  double rounding = 0.5;
  for (uint8_t i = 0; i < precision; ++i)    rounding /= 10.0;

  number += rounding;
  s += String(uint16_t(number));  // prints the integer part

  if(precision > 0) {
    s += ".";                // prints the decimal point
    uint32_t frac;
    uint32_t mult = 1;
    uint8_t padding = precision -1;
    while(precision--)     mult *= 10;

    frac = (number - uint16_t(number)) * mult;

    uint32_t frac1 = frac;
    while(frac1 /= 10)    padding--;
    while(padding--)      s += "0";

    s += String(frac,DEC) ;  // prints the fractional part
  }

  if (size>0)                // checks size
    if (s.length()>size)        return("#");
    else while(s.length()<size) s = " "+s;

  return s;
}

Enjoy!

ypkdani:
questa funzione dovrebbe fare al caso tuo: http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

Purtroppo no perché in wiring non supporta i float, inoltre la printf e sprintf sono lentissime in esecuzione e occupano da sole quasi 2k byte di memoria flash.
La soluzione è convertire il flot in due interi, uno per la parte intera tramite cast, e uno per la parte decimale moltiplicata per una idonea potenza di dieci, poi si applica la itoa() ai due interi e si concatenano le due stringhe in una sola, quest'ultima operazione è fattibile tramite la sprintf se non ci sono problemi di occupazione memoria e velocità di esecuzione.

astrobeed:
La soluzione è convertire il flot in due interi, uno per la parte intera tramite cast, e uno per la parte decimale moltiplicata per una idonea potenza di dieci,

L' esponente nei float non alla potenza di 2?

Ciao Uwe

un'alternativa a sprintf() c'è nella libreria standard di avr-libc: queste due funzioni convertono un double in una stringa, funziona anche con i float, si chiamano dtostre() e dtostrf()

Qui una discussione tra spintf e dtostrf: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=96339

uwefed:
L' esponente nei float non alla potenza di 2?

Si moltiplica per potenza di dieci perché devi passare da una cosa del tipo 1.2345 a due interi che contengono 1 e 2345, ovviamente esistono vari modi per fare questo passaggio, si va da quello semplice, ma dispendioso in termini di cicli macchina, a quello complicato, ma molto efficiente e veloce.

La dtostrf converte in un array di char, che alla fine è più C-compatibile dell'oggetto String (che è del C++). Ecco un esempio:

[code]
int x;
float i;
char risultato[6]; //scegli la dimensione adeguata

    x = analogRead(PIN_TEMP);
    i =  (((x / 1023.0) * 5.00) - 2.7315) * 100.0;
    dtostrf(i, 5, 1, risultato); //5 cifre, di cui 1 decimale, segno + o -

[/code]

Wiring supporta la conversione float con sprintf, l'unica magagna è che non c'è differenza tra float e double.
Purtroppo come già detto sprintf occupa molto spazio e anche le sue invocazioni sono abbastanza pesanti, ma lo sketch prevede conversioni molto complesse e frequenti è l'unica soluzione.
Ciao

MGuruDC:
Wiring supporta la conversione float con sprintf, l'unica magagna è che non c'è differenza tra float e double.

Provato adesso, la stringa risultante è sempre ?, che sprintf del C supporta i float non ci sono dubbi, il problema, e c'è una discussione in merito sul forum in inglese, è che wiring non passa i float alla sprintf().

molto semplice:

String converti(float val){
  String ris;
  if (val==0){
    ris="0";
    return ris;
  }

  if (val < 0){
     ris="-";
     val=-val;
  }

  int decimalNumber = 0;
  while (val-(int)val > 0){
    decimalNumber++;
    val*=10;
  }

  if (decimalNumber==0){
    ris += atoi(val); //+= because the sign
    return ris;
  }

  while (val>0){
    ris += val%10;
    val /= 10;
    if (decimalNumber==0){
      ris += ".";
    }
    decimalNumber--;
  }

  return ris;
}

astrobeed:

MGuruDC:
Wiring supporta la conversione float con sprintf, l'unica magagna è che non c'è differenza tra float e double.

Provato adesso, la stringa risultante è sempre ?, che sprintf del C supporta i float non ci sono dubbi, il problema, è c'è una discussione in merito sul forum in inglese, è che wiring non passa i float alla sprintf().

Hai ragione, ricordavo male...
L'unica è dtostrf, con adeguato buffer...
Ciao

leo72:

La dtostrf converte in un array di char, che alla fine è più C-compatibile dell'oggetto String (che è del C++). Ecco un esempio:
int x;
float i;
char risultato[6]; //scegli la dimensione adeguata

    x = analogRead(PIN_TEMP);
    i =  (((x / 1023.0) * 5.00) - 2.7315) * 100.0;
    dtostrf(i, 5, 1, risultato); //5 cifre, di cui 1 decimale, segno + o -
> ```

> La guida arduino mi rimanda ad un thread del forum e ad una guida che mi dice di usare dtostrf, ma non ho capito proprio come si fa.
> Qualcuno sa come si fa questa conversione?

Ho risolto seguendo il metodo di avenue33. Grazie a tutti