Auslesen eines DS18B20: stets 85°C

OP #1447846
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!
Gast #1447860
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?
Gast #1447970
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...
Gast #1448020
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
Gast #1448127
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.
OP #1452392
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!
Persönliche Seite #1457073
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
Persönliche Seite #1457168
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
OP #1457906
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.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren