Problem mit snprintf

Ich möchte die Ausgabe einer Temperatur mit Hilfe von snprintf formatieren.
Da snprintf mit float nicht klar kommt, nehme ich int und multipliziere den Temperaturwert mit 10.
Nun gibt es das Problem, dass alle Werte zwischen -0.1 und -0.9 als Pluswerte angezeigt werden.
Mir ist schon klar, warum das so ist (z.B. -5 geteilt durch 10 ergibt Null bei Integerzahlen).
Die Frage ist, wie kann ich das umgehen?

Hier mal als Testcode:

int TempC;

void setup() {
  Serial.begin(115200);
  TempC = 23.5 * 10; // "23.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = 0.5 * 10; // "0.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = -1.5 * 10; // "-1.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = -0.5 * 10; // "-0.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);  // <- diese Ausgabe wird als +0.5 angezeigt
}

void loop() {
}

void PrintTemp(int TempC) {
  char PrintBuf[6];
  snprintf(PrintBuf, 6, "%+d.%1d", TempC / 10, abs(TempC % 10));
  Serial.print(F("Temperatur: "));
  Serial.print(PrintBuf);
  Serial.println(F(" Grad C."));
}

Was hältst du davon?

void PrintTemp(int TempC) {
  char PrintBuf[6] = "+";
  if (TempC < 0) {
    TempC = -TempC;
    PrintBuf[0] =  '-';
  }
  snprintf(PrintBuf + 1, 5, "%d.%d", TempC / 10, abs(TempC % 10));
  Serial.print(F("Temperatur: "));
  Serial.print(PrintBuf);
  Serial.println(F(" Grad C."));
}
Temperatur: +23.5 Grad C.
Temperatur: +0.5 Grad C.
Temperatur: -1.5 Grad C.
Temperatur: -0.5 Grad C.

Ah! Das ist fast zu einfach! :slight_smile:
Danke!
Das hat mich aber noch auf eine andere Idee gebracht:

int TempC;

void setup() {
  Serial.begin(115200);
  TempC = 23.5 * 10; // "23.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = 0.5 * 10; // "0.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = -1.5 * 10; // "-1.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);
  TempC = -0.5 * 10; // "-0.5" ist die Rueckgabe vom Temp-Sensor "* 10" damit ich kein float benutzen muss
  PrintTemp(TempC);  // <- diese Ausgabe wird als +0.5 angezeigt
}

void loop() {
}

void PrintTemp(int TempC) {
  char PrintBuf[6];
  PrintBuf[0] = (TempC < 0) ? '-' : '+';
  snprintf(PrintBuf + 1, 5, "%d.%d", abs(TempC / 10), abs(TempC % 10));
  Serial.print(F("Temperatur: "));
  Serial.print(PrintBuf);
  Serial.println(F(" Grad C."));
}

Die Variante ohne abs ist etwas kleiner

Der Sketch verwendet 3.562 Bytes (1%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 194 Bytes (2%) des dynamischen Speichers, 7.998 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.
Der Sketch verwendet 3.578 Bytes (1%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 194 Bytes (2%) des dynamischen Speichers, 7.998 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.

Eine Variante ohne s(n)printf ist deutlich kleiner, wenn auch komplizierter.

void PrintTemp(int TempC) {
  char PrintBuf[6] = "+";
  if (TempC < 0) {
    TempC = -TempC;
    *PrintBuf = '-';
  }
  byte pos = 1;
  if (TempC < 10) {
    PrintBuf[pos++] = '0';
  }
  itoa(TempC, PrintBuf + pos, 10);
  pos = strlen(PrintBuf);
  PrintBuf[pos] = PrintBuf[pos - 1];
  PrintBuf[pos - 1] = '.';
  PrintBuf[pos + 1] = 0;
  Serial.print(F("Temperatur: "));
  Serial.print(PrintBuf);
  Serial.println(F(" Grad C."));
}
Der Sketch verwendet 2.164 Bytes (0%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 188 Bytes (2%) des dynamischen Speichers, 8.004 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.

Auf Speicherplatz brauche ich momentan nicht zu achten. Das ist für einen Mega2560. Aber trotzdem danke für Deine Mühe! :)