Eine float Zahl in eine Zahl mit einer Nachkommastelle umwadeln

Hallo zusammen
Für mein Projekt muss ich meine float Zahl in eine Zahl mit einer Nachkommastelle umwandeln.
Mein Problem ist, dass ich das noch nie machen musste. Ich weiss also nicht an welcher Stelle des Programms ich das machen muss. Kann mir das jemand sagen?
Dies ist der Sketch:

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
//7-Segment
#include <LedControl.h>
LedControl seg = LedControl (11, 13, 7, 1);

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

/*
   The setup function. We only start the sensors here
*/
void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
  seg.shutdown(0, false);
  /* Set the brightness to a medium values */
  seg.setIntensity(0, 8);
  /* and clear the display */
  seg.clearDisplay(0);
  // Start up the library
  sensors.begin();
}

/*
   Main function, get and show the temperature
*/
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  sensors.requestTemperatures(); // Send the command to get temperatures
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));
  byte tempOnes = sensors.getTempCByIndex(0);
  byte tempTens = 0;
  byte tempTenths = sensors.getTempCByIndex(0);
  while (tempOnes > 9) {
    tempOnes = tempOnes - 10;
    tempTens = tempTens + 1;
    tempTenths = (tempTenths - tempTens * 10 - tempOnes) * 10;
  }
  seg.setDigit (0, 3, tempTens, false);
  seg.setDigit (0, 2, tempOnes, false);
  seg.setDigit (0, 1, tempTenths, false);
}

In dem Projekt geht es darum die Temperatur auf einer 4digit 7-Segment-Anzeige darzustellen. Die Anzeige wird mit einem MAX7219 betrieben und deshalb verwende ich die LedControl Library. Der Temperatursensor ist ein DS18S20. Es zeigt mir bereits die Ganzzahl an. Auf den hinteren beiden Digits soll zum einen die erste Nachkommastelle erscheinen und zum anderen ein C. Das habe ich bis jetzt noch nicht geschafft.
Vielen Dank für eure Hilfe
techniclover

Google Tipp: "arduino float2str"

Das habe ich bereits gemacht. Aber ich weiss nicht an welcher Stelle ich das einbauen muss.
Und geht das nicht einfacher? Deshalb habe ich nämlich geschrieben. Ich habe nur sehr lange Funktionen gefunden. Aber dass sollte doch auch einfacher gehen.

Hmmm....

Einfacher?

Du könntest in der betreffenden platform.txt die float Verarbeitung für sprintf() und seine Brüder erlauben. ungetestet

Aber ich weiss nicht an welcher Stelle ich das einbauen muss.

Auch: Hmmm... Vielleicht vor der Ausgabe der Zahl?

Hallo,

dein auslesen verstehe ich noch nicht ganz. Du hast doch nirgends die ausgelesene Temp. in einer float gespeichert. Einmal gibt du die direkt auf serial aus. Dann liest du sie nochmal aus stopfst sie ein Byte. Dann liest du wieder aus und stopfst sie nochmal in ein Byte. 3x das selbe. Wobei die niemals in ein Byte paßt. Zusätzliches Problem wenn sich innerhalb des 3x auslesens die Temp. ändert, hantierst du mit 3x verschiedenen Werten.

Ich würde sie zuerst in ein float auslesen und speichern. Dann kannste mit der float Variablen machen was du möchtest. Sie zum Bsp. in alle Einzelziffern zerlegen. Ob du die Einzelziffern dann nochmal einzeln speicherst und am Ende alle gemeinsam an die Digitanzeige rausgibts oder ob du während der Zerlegung die neue Einzelziffer direkt zur Digitanzeige bringst und dann weiter zerlegst ist dir überlassen.

Falscher Ansatz. Wenn du die Auflösung deiner Sensoren richtig einstellst, dann bekommst du schon gar nicht mehr als eine Nachkommastelle (auch wenn der Arduino das vielleicht bei print() anders formatiert)! Die Anzahl der Nachkommastellen hängt direkt von der Auflösung des Sensors ab

Dafür ist diese Methode in der DallasTemperature Library da:

  // set global resolution to 9, 10, 11, or 12 bits
  void setResolution(uint8_t);

Wobei 9 Bit schon Standard sind (d.h. man muss das nicht extra einstellen) und das sind glaube ich 0.5° Auflösung. getTemperatureByIndex() wird so nie z.B. 25.56° liefern (das wären 10 Bit). Es sind nur 24.5°, 25.0° oder 25.5° möglich. Und falls der Arduino bei print() da 25.00 draus macht ist egal.

Das kannst du dann mit 10 multiplizieren und in einen int schreiben (nicht byte!! Das geht nur bis 255) um alles in einem Integer zu haben. Davon kann man dann die einzelnen Ziffern holen. Wie ich dir in dem anderen Thread gezeigt habe.

Wo bekommst du also mehr als eine Nachkommastelle her? Hast du mal die Test Sketche in der Library ausprobiert?

Und wie gesagt, lies pro Durchgang die Temperatur nur einmal aus!

Hallo,

hab mal was gebastelt zum zerlegen einer Fließkommazahl bis 99,9 Das C schickste als Buchstaben raus und das ° bastelste dir aus 4 Segmenten selber wenn Platz ist. Sensorwert in float auslesen und los gehts.

float DallasTemp = 25.8;

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

}

void loop() {

  Serial.print(DallasTemp); Serial.print('\t');  
  Temp_to_Digit(DallasTemp);
  DallasTemp = DallasTemp + 0.1;
  delay(1000);
}

void Temp_to_Digit (float temp)
{
  int TempInt = 0;
  int Sicherung = 0;
  byte Zehner = 0;
  byte Einer = 0;
  byte Komma = 0;
  
  TempInt = temp*10;            // 25,8 > 258
  Zehner = TempInt / 100;       // Zehner = 2
  Sicherung = Zehner * 100;     // 200
  TempInt = TempInt-Sicherung;  // 258-200 = 58
  Einer = TempInt / 10;         // Einer = 5
  Sicherung = Einer * 10;       // 50
  Komma = TempInt-Sicherung;    // 58-50 = 8

  Serial.print(Zehner); Serial.print('\t');  
  Serial.print(Einer);  Serial.print('\t');  
  Serial.println(Komma);  
}

Ich habe es gerade mal getestet!

Die betreffende platform.txt ändern. Dann sind solche Dinge auch ohne Fragezeichen möglich:

/*
 * 
 * platform.txt
 * compiler.c.elf.extra_flags=-Wl-u,vfprintf -lprintf_flt 
 * 
 */

char buffer[100]="";



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

void loop() 
{
  double zufall = rand()/17.0;
  sprintf(buffer,"Zufallszahl: %0.3f",zufall);
  Serial.println(buffer);
  delay(1000);
  
}

Mit UNO getestet Ca 1K mehr Flash Verbrauch

Doc_Arduino: Ich würde sie zuerst in ein float auslesen und speichern. Dann kannste mit der float Variablen machen was du möchtest. Sie zum Bsp. in alle Einzelziffern zerlegen.

float temp = 12.5;  // float temp = sensors.getTempCByIndex(0);
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(temp);
  byte tempTens = temp / 10;
  byte tempOnes = int(temp) % 10;
  byte tempTenths = int(temp * 10) % 10;

@serenifly: Dies sind die Temperaturen, welche mir der Sensor mit dem Simple Programm aus den Beispielen auf dem Seriellen Monitor ausgibt: https://www.dropbox.com/s/nf5h4ui5261djv6/2016-08-14%2013_04_21-COM4%20%28Arduino_Genuino%20Uno%29.png?dl=0

@Doc_Arduino: Mein Ziel ist es ja die Zahl auf einem 4digit 7Segment-Display darzustellen. Die Zerlegung habe ich verstanden. Aber wie kann ich meine konkrete Zahl als float speichern? Einfach float davor schreiben?

Danke für eure Hilfe techniclover

techniclover:
Aber wie kann ich meine konkrete Zahl als float speichern? Einfach float davor schreiben?

float temp = sensors.getTempCByIndex(0);

Hallo,

okay agmue, deins ist kürzer. :)

@ techni: ja, einer float Variablen zuweisen. Wie es geht wurde schon gezeigt.

@ combie: er benötigt die Ziffern einzeln, nicht als formatierten String

Habe ich auch in dem anderen Thread schon gezeigt. Leider ist das jetzt zweimal hier :/

Der Sensor hat 9 Bit und liefert immer eine Nachkommastelle (ist die S Version nicht B. Also kann man es gar nicht ändern). Daher kann man einfach * 10 machen um einen Integer zu bekommen.

Doc_Arduino: @ combie: er benötigt die Ziffern einzeln, nicht als formatierten String

Öhm... Wenn man es streng sieht, sind die Ziffern doch schon einzeln in einem formatierten String drin.

Die Frage war nach "einfach". Und irgendwie ist es doch "einfach" die Arbeit sprintf() zu überlassen....

Auch, bleibt es natürlich jedem überlassen, wie es erledigt wird. Immerhin kann mein Arduino Zeugs jetzt sprintf mit Fließkommazahlen (wenn ich will)

Doc_Arduino: okay agmue, deins ist kürzer. :)

Garnicht meine Absicht. Die Reihenfolge der Beiträge wird durch verschiedene Parameter beeinflußt. "Schatz, könntest Du mal bitte ..." ist dabei wie ein Interrupt. Oder ich muß mir erstmal einen Arduino freischaufeln, damit ich testen kann. Ein "kürzer" war nicht meine Absicht, ich habe einfach das probiert, was mir einfiel und was ich hoffe, der TO versteht es :)