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!
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?
@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.
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...
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.
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
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
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.
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!
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??
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.