Temperatur messen mit Arduino Mega 2560

Hallo Forum.

Ich habe folgendes Problem. Ich habe einen Sketch zum Temeratur messen in mein Programm eingebunden:
// Analog input pin
#define analogInPin A0

// Referenzspannung A/D-Wandler
#define Vcc 5.0

int sensorValue = 0; // Sensorwert
float temp; // Temperaturwert

void setup()
{
// serielle Schnittstelle einschalten und auf 9600 bps setzen
Serial.begin(9600);
}

void loop()
{
// Analogwert lesen
sensorValue = analogRead(analogInPin);
// in Celsiusgrade umrechnen
temp = (Vcc * sensorValue / 10.24) - 273.15;

// Ausgabe auf dem seriellen Monitor
Serial.print("Sensor = " );
Serial.print(sensorValue);
Serial.print("\t Temperatur = ");
Serial.println(temp);

// 1/2 Sekunde warten
delay(500);
}
sowei so gut, es wird auch gemessen und auf dem Monitor ausgegeben, jedoch immer Zahlenwerte im 5 oder 6 Stelligem Bereich. Ich möchte aber die Temperatur angaben mit höchstens einer Stelle hinter dem Komma haben, also = z.B. 25,5 C und es müssten auch lediglich 5er Schritte ausgeführt werden. Laut Sketch Angaben werden die Ausgelesenen Daten in Grad Zahlen umgewandelt mit: temp = (Vcc * sensorValue / 10.24) - 273.15; jedoch bei mir werden immer 6 oder 5 Stellige Werte angegeben.

l.G.Jürgen

Zum Formatieren von float/double als strings gibt es dtostrf:

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42
http://www.mikrocontroller.net/topic/86391

Was für einen Sensor nutzt Du?

malerlein:
Ich möchte aber die Temperatur angaben mit höchstens einer Stelle hinter dem Komma haben, also = z.B. 25,5 C

Dann gibst Du eben an, dass Du nur eine Nachkommastelle möchtest:
Serial.println(temp,1);

Aber Deine Formel sieht mir irgendwie merkwürdig aus:
temp = (Vcc * sensorValue / 10.24) - 273.15;

Was ist denn das für ein Temperatursensor, für den diese Formel gilt?

Das ist der : Typ LM335 Ich gebe Dir einmal das Tutorial, so wie es Erklährt wird:
Temperaturerfassung
Als erstes Beispiel soll die Erfassung der Temperatur dienen. Halbleiter-Temperatursensoren geben ein Ausgangssignal ab, das proportional zur Umgebungstemperatur ist. Weit verbreitet sind die Typen LM35 bis LM335, die ein Ausgangssignal zur Verfügung stellen, das direkt proportional zur Celsius-Skala ist. Die Bausteine werden in verschiedenen Genauigkeitsklassen über verschiedene Temperaturbereiche bereits auf dem Wafer abgeglichen, sodass ein externer Abgleich nicht vorgesehen werden muss. Insofern soll nur der preiswerte Typ LM335 betrachtet werden, der sich auf den absoluten Nullpunkt (-273,15 °C) bezieht und eine Spannung von 10 mV/K am Ausgang liefert. Bei 25° Celsius sollte sich also eine Spannung von etwa 2,98 V am Ausgang messen lassen. Diese liegt etwa in der Mitte des Messbereichs des Arduino und daher kann der Sensor direkt angeschlossen werden. Zum Betrieb benötigt er nur noch einen Widerstand von 2 Kiloohm gegen +5 V.

Für die Umrechung des Spannungswertes in die Temperatur gilt

temp = Uein * 100 - 273,15

Da der A/D-Wandler jedoch nicht die Eingangsspannung, sondern einen Wert von 0 bis 1023 liefert, der den Spannungsbereich von 0 bis 5 V entspricht, muss der Arduino folgendermaßen rechnen:

temp = Vcc * Uein / 1024.0 * 100.0 - 273.15

Für die Gleitpunktarithmetik mit begrenzter Stellenzahl ist die Formel jedoch ungünstig, da erst durch 1024 geteilt und dann mit 100 multipliziert wird. Der bei der Division eventuell entstehende Rundungsfehler multipliziert sich anschließend auch mit dem Faktor 100. Also stellt man besser um:

temp = (Vcc * Uein * 100 / 1024.0) - 273.15 ' temp = (Vcc * Uein / 10.24) - 273.15

Beim preiswerten LM335 kann es vorkommen, dass das Sensorausgangssignal von der tatsächlichen Temperatur etwas abweicht. Hier kann entweder per Hardware am Eingang adj des LM335 die Ausgangsspannung korrigiert werden oder man verwendet im Programm einem Korrekturfaktor. Beim Einlesen von Sensordaten stellen sich auch immer leichte Schwankungen der gelesenen Werte ein, die beispielsweise durch elektromagnetische Störeinflüssen oder leichte Schwankungen der Messgröße hervorgerufen werden. Um den Eingangswert zu stabilisieren, kann man gegebenenfalls mehrmals den Wert erfassen und dann einen Mittelwert bilden. Das erste Testprogramm liest den Temperaturwert und gibt ihn auf der seriellen Schnittstelle aus.

// Analog input pin
#define analogInPin A0

// Referenzspannung A/D-Wandler
#define Vcc 5.0

int sensorValue = 0; // Sensorwert
float temp; // Temperaturwert

void setup()
{
// serielle Schnittstelle einschalten und auf 9600 bps setzen
Serial.begin(9600);
}

void loop()
{
// Analogwert lesen
sensorValue = analogRead(analogInPin);
// in Celsiusgrade umrechnen
temp = (Vcc * sensorValue / 10.24) - 273.15;

// Ausgabe auf dem seriellen Monitor
Serial.print("Sensor = " );
Serial.print(sensorValue);
Serial.print("\t Temperatur = ");
Serial.println(temp);

// 1/2 Sekunde warten
delay(500);
}

Also meine Ausgabe sieht so aus:

// Temperatur Beleuchtung Anzeige berechnen in Arbeit
sensorValue = analogRead(analogInPin); // Analogwert lesen
temp = (Vcc * sensorValue / 10.24) - 273.15; // in Celsiusgrade umrechnen
settext(ESC_FG_BLACK, ESC_BG_YELLOW, ESC_CURSOR_POS(35, 77),"");
s(tempbuffer);

und wenn ich bei der Umwandlung zum String mit sprintf(tempbuffer,"C %02d",temp); Temp,1 eingebe , bewirkt das gar nichts, die Zahlen werden trotzdem als 5 oder 6 stelligem Wert auf dem Monitor ausgegeben.

l.G.Jürgen

Wie gesagt für Serial.print kannst du einfach Serial.println(temp, 1) machen:

Ansonsten ist die korrekte Funktion dtostrf. Da musst du ein char array erstellen das groß genug ist. Dann die Zahl, das Array, die Breite des Strings ingesamt und die Anzahl der Nachkomma-Stellen übergeben.

Danke Serenifly

dtostrf war genau das was ich gesucht habe, jetzt ist es Super.

l.G.Jürgen

malerlein:
Das ist der : Typ LM335

Du scheinst die Temperatur nicht besonders genau zu benötigen.

malerlein:
Die Bausteine werden in verschiedenen Genauigkeitsklassen über verschiedene Temperaturbereiche bereits auf dem Wafer abgeglichen, sodass ein externer Abgleich nicht vorgesehen werden muss. Insofern soll nur der preiswerte Typ LM335 betrachtet werden, der sich auf den absoluten Nullpunkt (-273,15 °C) bezieht und eine Spannung von 10 mV/K am Ausgang liefert. Bei 25° Celsius sollte sich also eine Spannung von etwa 2,98 V am Ausgang messen lassen. Diese liegt etwa in der Mitte des Messbereichs des Arduino und daher kann der Sensor direkt angeschlossen werden. Zum Betrieb benötigt er nur noch einen Widerstand von 2 Kiloohm gegen +5 V.

Klar, "zum Betrieb" reicht ein Widerstand.

Wenn Du tatsächlich nur den ungenauen LM335 hast, kannst Du allerdings mit einem Trimmerpoti und einem Abgleich noch ein bisschen Genauigkeit mehr herausholen, siehe Datenblatt unter "Figure 16. Calibrated Sensor":

Ich hätte ja lieber gleich einen digitalen Sensor genommen. Der ADC des Arduino hat nur 10-bit Auflösung, während selbst billige Digitalsensoren intern mit 12-Bit Wandlern messen und so genauere Ergebnisse zurückliefern.

sprintf() würde auf dem PC übrigens funktionieren, aber auf dem Arduino oder AVR generell ist die Funktion für floats anscheinend nicht implementiert.

Das mit der Ausgabe ist schon OK, das habe ich mittlerweile hinbekommen und die Genauigkeit bei der Beleuchtungstemperatur sollte so eine Große Rolle nicht spielen. Da in 5er Schritten angezeigt wird und die If Abfrage lediglich den Lüfter anh schmeisst bei Grad Zahlen über 35 Grad und unter 35 Grad den Lüfter ausschaltet, da ist es eigentlich egal ob der Lüfter nun genau bei 35 oder b3i 35,5 anspringt oder Umgekehrt . Aber Danke für Eure Hielfen .

l,G.Jürgen