Hey Leute,
ich habe folgendes Problem, ich habe an mein ATMega8 (16MHz Tackt über
Quarz) auf dem Pollinboard ein LC Display und einen Temperatursensor
DS18B20.
Wichtig es ist DS18B20 also nicht DS18S20 oder DS1820.
Den Sensor habe ich VDD und GND gegen GND und DQ auf Portc.0 und mit
einem 2,2k gegen Vcc. Hatte vorher ein 4,7k gegen Vcc gehabt, da war die
Anzeige aber um 2,5 Grad höher.
Das Problem ist, auf dem LCD werden mir Temperaturen zwischen 45 und 50
angezeigt (was im Raum eher unmöglich ist. Ein Fertigthermometer zeigt
gerade mal rund 20 Grad an.).
Hier der Code:
ein Byte einliest, liest Du nur das untere Byte ein, dass die
Wertigkeiten
8 4 2 1 1/2 1/4 1/8 1/16
enthält.
Das obere Byte mit den Wertigkeiten
<5 gleiche Sign Bits> 64 32 16
lässt Du dann entfallen.
20° -16 = 4 => LSB = 64 (1/16°)
64 / 2 = 32
Da meine DS18B20 gerne 1 bis 2°C mehr anzeigen, haut 40 - 50 hin.
Beim Code hatte ich das beim Compiler schon vorher geändert. Also habe
das erst noch nicht gemacht und das war Code Version 1.0 wenn mans so
nennen möchte.
Also in der Fertigen Version die auf dem µC (ATMega8) ist steht:
$crystal = 16000000
Und Sry Mitesser, kannst deins vielleicht auch mal ein wenig einfacher
Formiulieren. Das war mein erster Versuch mit einem 1 Wire Komponente.
Weil 100 Pro komme ich mit deiner Erklärung nicht ganz mit. Vielleicht
kannst mir helfen dies zu verstehen, bzw. beim anpassen helfen.
Vorallem komme ich nich ganz mit, dass 40-50 okay sein soll wenn im Raum
gerad mal 20 Grad ist.
Hoffe auf noch weitere Hilfe von euch. Danke schon mal im vorraus.
Michael
Was Mitesser und ich Dir versuchen zu sagen, ist, dass die Temperatur
richtig gemessen wurde, Du das Ergebnis aber noch einmal mit 0.0625 bzw.
0.625 multiplizieren solltest.
PS. Im Internet gibt es viele funktionierenden Beispiele, sind mit
"DS18B20 BASCOM" zu finden.
Michael N. schrieb:> Schiebt diese Codezeile also Rom1(1) = 1wread(9) gleich die Werte in den> Array Rom1()?
Jepp. Und die ersten beiden brauchst Du jetzt, die anderen vielleicht
noch später.
Karl schrieb:> Was Mitesser und ich Dir versuchen zu sagen, ist, dass die Temperatur> richtig gemessen wurde, Du das Ergebnis aber noch einmal mit 0.0625 bzw.> 0.625 multiplizieren solltest.>> PS. Im Internet gibt es viele funktionierenden Beispiele, sind mit> "DS18B20 BASCOM" zu finden.
Wenn ich aber z.B. die angezeigte 50 mit 0.625 Multipliziere erhalte ich
eine Temp. über 30 Grad. Und das wäre ja immer noch 10 Grad über
Realwert.
Michael
Ja, Du wertest auch nur ein einziges Byte aus. Du brauchst aber 2 Bytes.
Hier mal ein Beispiel aus dem Datenblatt:
http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf
Messung Byte 1: &B0000_0001
Messung Byte 2: &B1001_0001
Macht als Word (in HEX) = &H0191, da (256*Byte_1)+Byte2
macht als Integer = 401. So, da Du das Modell DS18B20 hast, musst du den
Wert mit 0.0625 multiplizieren oder durch 16 teilen. Dann kommt heraus:
25.0625. Das sind 25.0625 °C.
Danke werde den Code von Karl die Tage Testen. Aber jetzt hab ich an
sich was gefunden was läuft. Ist zwar eine Messdifferenz von noch 1°
aber das ist akzeptabel.
Karl geht den mit deiner möglichkeit auch mehrer Sensoren an zusprechen?
Und könntest die Zeilen bissel besser Komentieren? Also vorallem wofür
die einzelnen vermutlich Hexzahlen stehen oder sind das festdefinierte
Werte?
Michael
Hey Michael. Freut mich, dass Du etwas gefunden hast. So wirklich schwer
ist es nämlich nicht, einen DS18B20 anzusprechen (und Infos aus dem Netz
darüber zu bekommen).
Die Hexzahlen ergeben sich (fast) alle aus dem Datenblatt und sind fest.
Man kann auch mehrere DS18B20 ansprechen, muss dafür aber die
Seriennummer der einzelnen ICs kennen und den Code somit verändern.
Siehe dazu auch:
http://www.rn-wissen.de/index.php/Bascom_und_1-Wire
Und ich kann nur immer wieder das Datenblatt empfehlen. Da ist jede
Hexzahl ausgezeichnet dokumentiert. Viel ausführlicher als man es mit
einem Kommentar im Code machen könnte.
http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf
Der Rest ist hoffentlich logisch:
1
Call Init_ds18b20: IC initialisieren, sprich Messgenauigkeit einstellen.
2
Call Measure_ds18b20: Messung anwerfen
3
Call Read_ds18b20: Daten lesen
Der Rest macht aus den 2 Bytes ein Word. Das Ergebnis wird durch 16
geteilt und ausgegeben. Wie geschrieben, es fehlt noch die Position des
Kommas.
Ja sagen wir so, die Adressen der chips (Temp. Sensoren) hab ich raus
bekommen. Nur irgendwie hab ichs nicht richtig verstanden wie ich dann
die Seriennummer (wenn ich mich nich vertue waren es 9 x 2Stellen Hoffe
ich vertue mich da nicht) in den Array genau einfügen soll, damit es
Funst.
Karl kannst mir vielleicht ein Beispiel mal zeigen wie das aussehen
muss, bei einem x Beliebigen Temp. Sensor.?
Also Anhand des Beispielcodes 1-Wire erklärung aus Bestimmtes "Gerät
ansprechen" von der Seite
http://www.rn-wissen.de/index.php/Bascom_und_1-Wire
Das mit Alle Seriennummern hat geklappt und Putty gab mir die Adresse
des Temp. Sensors aus. Habt ihr eure irgendwie makiert welche Seriennr.
welcher Chip hat?
Also falls mal einer Kaputt geht im Bus oder sonst irgendwie ersetzt
wird und man dann weiß welche Seriennummer ersetzt werden muss?
Ich hoffe es ist verständlich was ich meine.
Michael
Naja, in meinem Beispiel sende ich immer &HCC. Das Datenblatt sagt dazu,
dass der nachfolgende Befehl von allen ICs im Bus ausgeführt werden
soll.
Will man einen einzelnen IC ansprechen, so sagt das Datenblatt sende
&H55 und danach die 64-Bit Adresse des ICs. In BASCOM würde das so
aussehen:
1
Dim DS18B20-ID(8) As Byte
2
3
1wreset
4
1wwrite &H55
5
1wwrite DS18B20-ID(1) , 8 'Sendet 64-Bit
6
....
Du kannst auch immer zum Programmstart oder im Programm die
Seriennummern der ICs ermitteln. Wenn es wichtig ist, sollte man sich
natürlich aufschreiben, wo welcher Sensor etwas misst.
Stimmt, so könnte ich mit dem Beispiel von der Website auch was machen.
Ich hätte die Seriennummern in Constanten bzw in den EEprom gepackt und
beim Start abgerufen. Also, dass nicht bei jedem Start der Bus
untersucht wird, welche Sensoren vorhanden sind.
Nur dann muss ich entweder alles nur DS18B20 Sensoren haben oder muss
einfach die Adresse des Sensors abfragen und die ersten beiden Stellen
seperat untersuchen, die bilden ja die Family Adresse.
Aber danke. Manchmal sieht man den Walt vor lauter Bäumen nicht grins
Werde es die Tage mal Testen. Also erst Bus durchsuchen lassen, welche
SN vorhanden sind und dann in der Do loop Schleife die Temp. messen
lassen und dann per Print ausgeben lassen. Evtl mit der Kombination von
Text, der den Ort des Sensors vermittelt.
Den gebe ich wie folgt aus, wenn ichs richtig verstanden habe.
Print "Sensor 1"; Temp(1); "°C"
Stimmts?
Michael
Michael N. schrieb:> Print "Sensor 1"; Temp(1); "°C"
Hängt davon ab, was in Temp(1) steht und "°" wird wahrscheinlich nicht
richtig angezeigt werden.
Du solltest beim Auslesen unbedingt das Timing beachten. Bei höchster
Genauigkeit dauert die Umrechnung um die 750ms.
So habe den Code von Karl getestet, nur leider ist in dem Fall die
Ausgabe wieder nicht passend. Also er zeigt ein Wert über 1000 an.
Aber naja ich werde mir das alles noch mal näher zu gemüte führen
müssen. Vorallem wenn alles ersma richtig läuft wie ich das bei meinem
Funktionstüchtigem Code hin bekomme verschiedene Sensoren seperat ab zu
fragen. Also müsste ich gucken wie ich den code modifiziert bekomme.
Hier ist der Code der Funktioniert mit etwa 2 Grad Messdifferenz.
1
Const Ds1920 = &H10
2
Const Skiprom = &HCC
3
Const Read_rom = &H33
4
Const Convertt = &H44
5
Const Read_ram = &HBE
6
Const Write_ram = &H4E
7
Const Copy_ram = &H48
8
Const Recall_ee = &HB8
9
Const Read_power = &HB4
10
11
Dim Family_code As Byte
12
Dim Serial_number(6) As Byte
13
Dim Crc As Byte
14
Dim Scratch(9) As Byte
15
16
Dim I As Byte
17
Dim Temp As Word
18
Dim Temp1 As Integer
19
Dim Stemp As Single
20
21
22
Do
23
1wreset
24
1wwrite Read_rom
25
Family_code = 1wread()
26
For I = 1 To 6
27
Serial_number(i) = 1wread()
28
Next
29
Crc = 1wread()
30
1wwrite Convertt
31
Do
32
Temp = 1wread()
33
Loop Until Temp = &HFF
34
35
1wreset
36
1wwrite Skiprom
37
1wwrite Read_ram
38
39
For I = 1 To 9
40
Scratch(i) = 1wread()
41
Next
42
43
44
Temp = Scratch(2)
45
Shift Temp , Left , 8
46
Temp = Temp + Scratch(1)
47
Stemp = Temp
48
Stemp = Stemp / 16
49
50
51
52
Locate 1 , 1
53
Lcd "Raumtemperatur"
54
Locate 2 , 1
55
Lcd "Temp: " ; Fusing(stemp , "#.##") ; " Grad C"
56
Cursor Off
57
Wait 1
58
59
Loop
60
61
End
Michael
PS: Ich hoffe ich habe den Code jetzt nicht vertauscht.
Em joa stimmt. Bei dem Gedanken, wo es sagst hab ich dies vergessen.
Kannst mir vielleicht den mal den Punkt sagen wo genau die Seriennummer
angegeben werden muss, wenn man mehere Sensoren nimmt? Dann müsste ich
ja den Abfragebereich in eine For - Schleife packen und die Seriennummer
als Array mit fortlaufenden I - Wert. Und dann am Ende den Array (mit
den Messwerten) wieder aus zu gebene.
Oder gibts da ne andere Lösung für?
Michael
Ok, Michael. Musste noch Geld verdienen, mich um die Familie kümmern....
Anbei der Code für bis zu 8 DS18B20. Viel Spaß damit.
Eine umfangreiche Fehlerbehandlung gibt es nicht. Ohne DS18B20 am Bus =
keine Funktion. Ebenso fehlt noch die Prüfsumme und das Verhalten bei T
< 0°C.
Tausend und 1 Dank Karl.
Das für < 0 Grad noch nicht enthalten ist, ist nicht schlimm. Soll
Primär Raumtemperatur Messen und wenn die unter 0 Grad ist wäre, ich
schon tief in Sibierien. Da wollte ich aber nicht hin. :-) also würde es
für mein Zweck reichen.
Wie gesagt vielen Danke und daraus das mit minusgraden werde ich mir
noch selber zu gemüt führen. Denke das kann ich hin bekommen mit
probieren. üben und so weiter.
Und wenn ich doch mehr Sensoren haben möchte sollte ich, hin bekommen.
Da müsste ich ja nur mehr ran packen, aber wenn es nicht funktionieren
würde, wäre es nicht sonderlich schlimm. 8 Sind ja schon eine Menge.
Das hier Begrenzt doch die Anzahl auf 8 oder?
Michael N. schrieb:> Das hier Begrenzt doch die Anzahl auf 8 oder?> Ds18b20_id(8)
Ja. Ich weiß allerdings nicht, wie viele "Double" Variablen Dein AVR
verkraftet.
Hoffe, Du lernst auch ein wenig dabei. Es ist nicht viel kommentiert, da
alle 1wire Funktionen in der BASCOM-Hilfe erklärt sind und der Rest im
mehrfach erwähnten Datenblatt steht.
Klar, ich bin eher weniger der viel liest grins eher Lernen beim üben
und nachmachen und bastel aus dadraus dann meins was ich benötige.
Und an sich habe ich vor den ATMega8 zu nehmen, aber notfalls kann ich
auch auf ein mega32 zurück greifen.
Und würde ich jeden verfügbaren Speicherplatz für Adressen nehmen,
könnte ich 128 Sensoren nehmen. Aber denke ich fange mal mit bis zu 8 an
und werde höchstens auf 16 erweitern. Ist bei einem 1Wire Bus nicht die
Anzahl sowieso auf 16 begrenzt? Gut man könnte mehrere 1Wire Bus auf
machen aber okay.
Und 1 Sensor werde ich im Kühlschrank nutzen (original Termostat is
Kaputt werde mir da was nachbauen. Es ist nur ein Party Kühlschrank, da
lohnt reperatur nicht, is schon älter und läuft nur wenige Tage im Jahr.
Würde das normale Termostat überbrücken mit einem Relais, welches vom µC
geschalten wird. Und ein Temp. Sensor überwacht die Temperatur. :-)
Danke nochmal.
Michael