Forum: Mikrocontroller und Digitale Elektronik Auslesen eines DS18B20: stets 85°C


von Luca K. (lukim)


Lesenswert?

Hallo zusammen,
ich bin gerade erst vor kurzem in die AVR-Programmierung eingestiegen 
und stehe sogleich vor einem Problem:

Ich versuche mir den DS18B20 im nicht parasitären Modus auszulesen. Dies 
habe ich nach folgender Anleitung, da sie die Thematik gut erklärt, 
versucht:
http://www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf
Alles scheint mir soweit logisch. Doch in der Praxis funktioniert es 
nicht. Das Problem scheint in der Konvertierung der Temperatur ins 
Scratchpad zu liegen. Laut dem Datenblatt sendet der DS18B20 solange 
eine 0 bis die Konvertierung beendet ist, dann eine 1 (was ja nach etwa 
750ms der Fall sein sollte). Bei mir scheint aber direkt nach dem Befehl 
nur ein einziges Mal eine 0 gesendet zu werden danach folgt bereits die 
1. Ich weiss nicht, woran das liegen könnte. Anschliessend wird 
natürlich nur der Default-Wert, also 85°C, gelesen.

Ich benutze das STK500 mit dem Atmega8515 im Zusammenhang mit AVR Studio 
4. Da kein 4,7kOhm Widerstand für den DS18B20 vorhanden war, verwendete 
ich - bitte korrigiert mich falls die Überlegung kreuzfalsch ist - einen 
3,3kOhm und einen 1kOhm Widerstand in Reihenschaltung um immerhin auf 
4,3kOhm zu kommen. Die Ergebnisse lasse ich mir schlussendlich über 
einen LCD-Display anzeigen.

Danke schon mal im voraus!

von mui (Gast)


Lesenswert?

4,3 kOhm sind okay - bei mir funktionierts sogar mit 2,2K. das würde ich 
als fehler erstmal ausschliessen...bekommst du denn eine richtige 
temperatur, wenn du > 1s wartest? wie sieht denn dein quellcode aus?

von Karl H. (kbuchegg)


Lesenswert?

Funktionierenden Code findest du hier

Beitrag "DS1820, DS18B20 in C"

von Luca K. (lukim)


Angehängte Dateien:

Lesenswert?

@mui: Hier der Quelltext (ohne der LCD-Ansteuerung)

@Karl: Hmm, es klappt. Danke für die Hinweis! Werde jetzt dann mal wohl 
die beiden Quellcode vergleich und versuchen den groben Unterschied bzw. 
den Fehler zu finden.

von mui (Gast)


Lesenswert?

du liest in therm_read_temperature nachdem du das kommando zum 
tempereatur messen geschickt hast nur EIN BIT aus, um zu schauen, ob der 
Sensor fertig ist...du musst aber abwarten bis ein ganzes BYTE aus 
Einsen besteht (also 0xff) - wenn du den sensor vorher ausliest kommt 
mist raus...

von Luca K. (lukim)


Lesenswert?

Ich habe jetzt:
1
while(!therm_read_bit());
durch
1
while(therm_read_byte() != 0xff);
ersetzt. Es klappt leider immer noch nicht (Ich hoffe ich habe dich 
richtig verstanden). Aber danke für deine Mühe.

von mui (Gast)


Lesenswert?

hast du es schonmal geschafft etwas ins scratchpad zu schreiben und dann 
wieder auszulesen? hatte da mal ein problem mit der bitreihenfolge - hat 
ewig gedauert, bis ich das rausgefunden hatte, da 85°C im Scratcpad 0x55 
entspricht...das ist aber eine wunderbar symmetrische Zahl und deswegen 
lies sich das nicht gleich erkennen...

ansonsten, probier mal aus zu warten, statt den status abzufragen - 
klappt das denn? wenn nicht ist noch was anderes vermurkst

von Luca K. (lukim)


Lesenswert?

1. Ins Scratchpad zu schreiben habe ich noch nicht versucht.
2. Nur warten klappt leider auch nicht, d.h. es wird immer noch 85°C 
angezeigt

von mui (Gast)


Lesenswert?

85°C bedeutet auf jeden Fall, das irgendwas noch nicht stimmt...es sei 
denn du hast wirklich 85°C in deinem Zimmer :-)

versuch erstmal was ins scratchpad zu schreiben und wieder zu lesen - 
dann kannst du schon mal sicher sein, dass deine schreib/lese routinen 
funktionieren - wenn das dann funktioniert versuchen den sensor zum 
messen zu überreden. wenn du ein oszi hast, guck dir mal die timings auf 
dem bus an - die sind recht kritisch.

von Luca K. (lukim)


Lesenswert?

So, ich konnte das Problem nach langem Vergleichen mit dem empfohlenen 
Code lösen: die Befehle THERM_HIGH(); und THERM_OUTPUT_MODE(); nach dem 
Convert_t Befehl und danach einfach 750ms warten. Endgültiger Quelltext 
wird noch folgen. Vielen Dank für die entgegengebrachte Hilfe!

von Christoph S. (mixer) Benutzerseite


Lesenswert?

Hallo,

benutze ebenfalls den gleichen Code + LCD.

Ich messe im Zimmer momentan 2.625°C. Der Wert verändert sich auch wenn 
ich den DS18B20 anhauche bzw. zwischen zwei Finger nehme um ihn zu 
erwärmen.

Allerdings herrschen hier ca. 20°C!

Was hast du genau verändert um den richtigen Wert zu bekommen??

von (prx) A. K. (prx)


Lesenswert?

2,625°C * 8 = 21,0°C. Passt also.

Du verwendest Code für den DS18B20 mit dem DS18S20. Der eine liefert die 
Temperatur in 1/16 Grad, der andere in 1/2 Grad.

NB: 85°C ist der Wert, den der Sensor liefert, wenn seit Einschalten 
keine Messung vorgenommen wurde.

von Christoph S. (mixer) Benutzerseite


Lesenswert?

Also muss ich das Array temperatur nur noch mal 8 nehmen oder?
1
          temperature[0]=therm_read_byte();
2
          temperature[1]=therm_read_byte();
3
          therm_reset();
4
          //Store temperature integer digits and decimal digits
5
          digit=temperature[0]>>4;
6
          digit|=(temperature[1]&0x7)<<4;
7
          //Store decimal digits
8
          decimal=temperature[0]&0xf;
9
          decimal*=THERM_DECIMAL_STEPS_12BIT;
10
          //Format temperature into a string [+XXX.XXXX C]
11
          sprintf(buffer, "%+d.%04u", digit, decimal);

hmm wie mach ich das am besten? Bin bei sowas noch nicht so ganz fit in 
c!

MFG Mixer

von Christoph S. (mixer) Benutzerseite


Lesenswert?

Hallo,

hat sich mittlerweile erledigt - Hab nen DS1820 und der gibt die 
Temperatur anderst aus als der DS18B20 wofür der Code bestimmt war!
1
          temperature[0]=therm_read_byte();
2
          temperature[1]=therm_read_byte();
3
          therm_reset();
4
          //check if positive or negative
5
          sign = (temperature[1]<0x0F) ?'+' :'-';
6
          //Store temperature integer digits and decimal digits
7
          digit=temperature[0]>>1;
8
          //Store decimal digits
9
          decimal=(temperature[0]&1<<0)?5 :0;
10
          //Format temperature into a string [?XXX.X °C]
11
          sprintf(buffer, "%c%d.%01u %cC      ", sign, digit, decimal, 0xDF);
12
}


Wie effizient bzw. uneffizient ist eig. das sprintf??

Werd ich mit dem Timing probleme bekommen wenn ich noch Interrupts 
einsetze??

MFG Mixer

von Luca K. (lukim)


Angehängte Dateien:

Lesenswert?

Hier nun die endgültige Version der Dateien zur Ansteuerung eines 
DS18B20. Ich habe einiges geändert. So habe ich beispielsweise die 
Funktionen, zu lesen und zu schreiben in der gleichen Funktion sowie die 
"delay"-Funktion aus dem Ansteuerungsvorschlag übernommen. Zudem habe 
ich noch die Funktionen: 1. die Temperatur als Zahl (d.h. als float) und 
2. die Zahl gerundet auszugeben hinzugefügt.

Ich hoffe hiermit anderen eine Hilfe sein zu können. Korrektur und 
Verbesserung ist stets erwünscht.

@mixer:
1. Bezüglich der Effizienz von "sprintf()" kann ich dir nicht viel 
sagen, da kenne ich mich nicht aus. In meiner neuen Version habe ich 
aber darauf verzichtet und durch "dtostrf()" ersetzt. Über dessen 
Effizienz weiss ich aber ehrlich gesagt auch nicht viel mehr. :-)
2. Ich denke Interrupts könnten durchaus Timingprobleme verursachen. 
Deshalb sollte man - korrigt mich - die gefährlichen Stellen durch 
Verwendung von "cli()" am Anfang bzw. "sei()" am Ende entschärfen.

PS: Ich konnte leider nicht früher die Dateien hochladen bzw. antworten, 
da mir zeitenweise das Internet nicht zur Verfügung stand.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.