Arduino sprintf float formatteert niet

Ik heb deze Arduino-schets,

char temperature[10];
float temp = 10.55;
sprintf(temperature,"%f F", temp);
Serial.println(temperature);

temperatuur wordt afgedrukt als

? F

Enige gedachten over hoe deze float te formatteren? Ik wil dat het een tekenreeks is.


Antwoord 1, autoriteit 100%

Vanwege prestatieredenen is %fniet opgenomen in de Arduino-implementatie van sprintf(). Een betere optie zou zijn om dtostrf()te gebruiken – u converteert de drijvende-kommawaarde naar een tekenreeks in C-stijl, de handtekening van de methode ziet er als volgt uit:

char *dtostrf(double val, signed char width, unsigned char prec, char *s)

Gebruik deze methode om het te converteren naar een C-Style string en gebruik dan sprintf, bijvoorbeeld:

char str_temp[6];
/* 4 is mininum width, 2 is precision; float value is copied onto str_temp*/
dtostrf(temp, 4, 2, str_temp);
sprintf(temperature,"%s F", str_temp);

Je kunt de minimale breedte en precisie aanpassen aan de float die je aan het converteren bent.


Antwoord 2, autoriteit 7%

Zoals eerder vermeld is Float-ondersteuning niet inbegrepen in sprintfop Arduino.

Tekenreeksklasse

Arduino heeft zijn eigen Stringklasse .

String value = String(3.14);

dan,

char *result = value.c_str();

Referentie tekenreeksklasse, link hierboven

Construeert een instantie van de klasse String. Er zijn meerdere versies die strings construeren uit verschillende datatypes (d.w.z. ze opmaken als reeksen tekens), waaronder:

  • een constante reeks tekens, tussen dubbele aanhalingstekens (d.w.z. een char-array)
  • een enkel constant teken, tussen enkele aanhalingstekens
  • een ander exemplaar van het String-object
  • een constant geheel getal of lang geheel getal
  • een constant geheel getal of lang geheel getal, met een gespecificeerd grondtal
  • een integer of long integer variabele
  • een integer of long integer variabele, met een gespecificeerd grondtal
  • een float of double, met gespecificeerde decimalen

Antwoord 3, autoriteit 2%

Ik heb een paar uur geworsteld om dit goed te krijgen, maar het is me uiteindelijk gelukt. En dit maakt gebruik van moderne Espressif C++ geleverd door Platformio, en mijn doel-MCU is een ESP32.

Ik wilde een prefix-label weergeven, de waarde float/int en vervolgens de eenheid, allemaal inline.

Ik kan geen afzonderlijke Serial.print()-instructies doorgeven, omdat ik een OLED-scherm gebruik.

Hier is mijn codevoorbeeld:

 int strLenLight = sizeof("Light ADC: 0000");
  int strLenTemp = sizeof("Temp: 000.0 °C");
  int strLenHumd = sizeof("Humd: 00.0 %");
  char displayLight[strLenLight] = "Light ADC: ";
  char displayTemp[strLenTemp] = "Temp: ";
  char displayHumd[strLenHumd] = "Humd: ";
  snprintf(strchr(displayLight, '\0'), sizeof(displayLight), "%d", light_value);
  snprintf(strchr(displayTemp, '\0'), sizeof(displayTemp), "%.1f °C", temperature); 
  snprintf(strchr(displayHumd, '\0'), sizeof(displayHumd), "%.1f %%", humidity); 
  Serial.println(displayLight);
  Serial.println(displayTemp);
  Serial.println(displayHumd);

Wat wordt weergegeven:

Light ADC: 1777
Temp: 25.4 °C
Humd: 55.0 %

Antwoord 4

dtostrf()is verouderd en bestaat niet op alle kernplatforms van het bord.
Aan de andere kant formatteert sprintf()geen floats op AVR-platforms!

Other episodes