Hallo Forum,
ich programmiere gerade ein Thermometer mit 7 Segmentanzeigen mit einem
DS18S20. Nun bin ich soweit, dass alles funktioniert ich die Temperatur
nur ganzzahlig bekomm. Jedoch möchte ich gerne eine Nachkommastelle mit
Auflösung von 0,1°C.
Mein bisheriger Code sieht so aus:
1
1wreset 'Initialisierung
2
1wwrite Skip_rom 'Skip ROM
3
1wwrite Convert_t 'Convert_T
4
5
Do 'warten bis Messung fertig
6
Temp = 1wread()
7
Loop Until Temp = &HFF
8
9
1wreset 'Initialisierung
10
1wwrite Skip_rom 'Skip ROM
11
1wwrite Read_scratch 'Read RAM
12
13
For I = 1 To 9 'Scratch auslesen
14
Scratch(i) = 1wread()
15
Next
16
17
Temp = Scratch(2)
18
Shift Temp , Left , 8
19
20
Temp = Temp + Scratch(1)
21
Temp1 = Temp
22
Temp1 = Temp1 / 2
Was muss ich ändern, dass ich die Nachkommastelle bekomme? Diese hätte
ich jedoch in einer zusätlichen Variable, wenn das geht.
Danke schonmal für eure Hilfe.
DS18S20 schrieb im Beitrag #2483715:
> Jedoch möchte ich gerne eine Nachkommastelle mit> Auflösung von 0,1°C.
Der Sensor hat aber nur eine Auflösung von 0,5Grad.
Düsendieb schrieb:> DS18S20 schrieb im Beitrag #2483715:>> Jedoch möchte ich gerne eine Nachkommastelle mit>> Auflösung von 0,1°C.>> Der Sensor hat aber nur eine Auflösung von 0,5Grad.
Guckst du Datenblatt --> berechnen für 1/16°C Auflösung
Jedoch möchte ich ja nur die Kommastelle berechen.
85 Grad entspricht einem Wert von 170 (00AA in Hex)
25 Grad entspricht einem Wert von 50 (0032 in Hex)
0,5 Grad entspricht einem Wert von 1 (0001 in Hex)
So steht es im Datenblatt
DS18S20 hat Recht !!!
Man kann weitere 4 Bit auslesen und diese dann ebenfalls umrechnen.
Steht im Datenblatt.
Mein Code Programm sah so aus. Dabei sind noch andere Funktionen
möglich.
Viel Erfolg
Joe
'=======================================================================
========
'
' Auslesen von zwei DS18S20 oder DS18B20
'
'
http://www.mcselec.com/index.php?option=com_content&task=view&id=75&Itemid=57
'
' Anpassung von LCD , Texte reduziert (siehe Version 0.2)
' V0.3 ohne Parameterübergabe, mit Wertrückgabe bei Funktionen
' Min- und Max-Ausgabe geändert
'
'=======================================================================
========
$regfile = "m8def.dat"
$crystal = 14318180 'Mini-Atmega 4-Platine (mit
LCD)
Declare Function Dg_ds18s20() As Integer 'Umrechnung in Grad
Declare Function Dg_ds18b20() As Integer 'Umrechnung in Grad
Config 1wire = Portc.0 '1wire-Port festlegen
Config Lcd = 16 * 2 'Lcd Initialisieren
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 ,
Db7 = Portb.3 , E = Portb.5 , Rs = Portb.4
Dim B As Byte , W As Word , Dg As Integer , Dg_s As Single , Tg As Byte
Dim Min1 As Single , Min2 As Single , Max1 As Single , Max2 As Single
Dim Dsid1(8) As Byte , Dsid2(8) As Byte 'Dallas ID 64 bits incl CRC
Dim T As Integer , T1 As Integer , Ts As Single
Dim Sc(9) As Byte 'Scratchpad 0-8 72 bits
incl CRC, explanations for DS18b20
Cls : Lcd "DS1820 Thermometer"
Locate 2 , 1 : Lcd "* V0.3 *"
Wait 1 : Cls
W = 1wirecount() : Lcd "Sensoren:" ; W 'Anzahl der Sensoren
augeben
Wait 1 : Cls
Dsid1(1) = 1wsearchfirst() '1. Device-ID suchen
Do
Dsid2(1) = 1wsearchnext() 'weitere ID's suchen
Loop Until Err = 1
' First sensor identified and stored in variable
If Dsid1(8) = Crc8(dsid1(1) , 7) Then ' Control that the received
CRC match the calculated
Locate 1 , 1
Lcd "CRC OK Sensor 1 ID"
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid1(b))
Next
End If
Wait 1
' Second sensor
If Dsid2(8) = Crc8(dsid2(1) , 7) Then
Locate 1 , 1
Lcd "CRC OK Sensor 2 ID"
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid2(b))
Next
End If
Wait 1 : Cls
'Min/Max vorbesetzen
Min1 = 999 : Min2 = 999
Max1 = -999 : Max2 = -999
'Hauptschleife
Do
Tg = 1 - Tg 'für wechselnde
Min-Max-Anzeige
1wreset ' reset the bus
1wwrite &HCC ' skip rom
1wwrite &H44 ' Convert T anstoßen
Waitms 750 'Wandlungszeit abwarten
1wverify Dsid1(1) 'Prüft das "Match ROM"
If Err = 1 Then
Lcd "DsId2 not on bus " 'Err = 1 Fehler
Elseif Err = 0 Then 'lcd " Sensor found"
1wwrite &HBE
Sc(1) = 1wread(9) 'read bytes into array
If Sc(9) = Crc8(sc(1) , 8) Then
If Dsid1(1) = 16 Then Dg = Dg_ds18s20() '=10h
If Dsid1(1) = 40 Then Dg = Dg_ds18b20() '=28h
Dg_s = Dg / 10 'In Dezimalgrad umwandeln
If Min1 > Dg_s Then Min1 = Dg_s
If Max1 < Dg_s Then Max1 = Dg_s
Locate 1 , 1 : Lcd "Tmp" ; Fusing(dg_s , "#.#")
If Tg = 1 Then : Locate 1 , 9 : Lcd "Min" ; Fusing(min1 ,
"#.#") : End If
If Tg = 0 Then : Locate 1 , 9 : Lcd "Max" ; Fusing(max1 ,
"#.#") : End If
End If
End If
1wverify Dsid2(1)
If Err = 1 Then
Lcd "DsId2 not on bus "
Elseif Err = 0 Then ' lcd " Sensor found "
1wwrite &HBE
Sc(1) = 1wread(9)
If Sc(9) = Crc8(sc(1) , 8) Then
If Dsid2(1) = 16 Then Dg = Dg_ds18s20() '=10h
If Dsid2(1) = 40 Then Dg = Dg_ds18b20() '=28h
Dg_s = Dg / 10 'In Dezimalgrad umwandeln
If Min2 > Dg_s Then Min2 = Dg_s
If Max2 < Dg_s Then Max2 = Dg_s
Locate 2 , 1 : Lcd "Tmp" ; Fusing(dg_s , "#.#")
If Tg = 1 Then : Locate 2 , 9 : Lcd "Min" ; Fusing(min2 , "#.#")
: End If
If Tg = 0 Then : Locate 2 , 9 : Lcd "Max" ; Fusing(max2 , "#.#")
: End If
End If
End If
Waitms 200 'Gesamtwartezeit ca.1s
Loop
End 'end program
'=======================================================================
========
Function Dg_ds18s20() 'keine Parameter notwendig!
' Tmp = Sc(1) And 1 ' für 0.1C
precision das 0,5°-Bit löschen
' If Tmp = 1 Then Decr Sc(1)
Sc(1) = Sc(1) And &B11111110 ' alternativ 0,5°-Bit
löschen
T = Makeint(sc(1) , Sc(2)) 'in 1/2°
T = T * 50 'in 1/100°
T = T - 25 'DS18S20 data sheet
T1 = Sc(8) - Sc(7)
T1 = T1 * 100
T1 = T1 / Sc(8)
T = T + T1 'Temperatur in 1/100°
Dg_ds18s20 = T / 10 'Ergebnis in 1/10°
End Function
'=======================================================================
========
Function Dg_ds18b20() 'mit Fehlerkorrektur
T = Makeint(sc(1) , Sc(2)) 'in 1/16°
Ts = T 'in Single umwandeln
Ts = Ts * 6.25 'in 1/100° umrechnen
T = Ts 'in 1/100° als Integer
merken
'in Integer
Dg_ds18b20 = T / 10 'Ergebnis in 1/10°
End Function
In Maschinensprache macht man die Umrechnung bzw. Rundung per
lookup-Tabelle.
Man ordnet den 16 Werten in binär die 10 Werte in dezimal per Tabelle
zu.
In Basic?? if a =0 then b = 0, if a = 1 then b = 1 if a= 2 then b = 1
if a = 3 then b= 2.... usw, bis if a = 15 then b = 9
(Ich hab schon zwanzig Jahre kein basic mehr geschrieben, daher nur als
Andeutung zu nehmen.)
a, die letzten vier bit des Messergebnisses, muss man halt entsprechend
aus dem ausgelesenen Wert isolieren.
b sind halt die Zehntel ,0 bis ,9 der Grad-Ausgabe
Joe schrieb:> DS18S20 hat Recht !!!>> Man kann weitere 4 Bit auslesen und diese dann ebenfalls umrechnen.>> Steht im Datenblatt.
Du meinst das hier
1
<Zitat>
2
Resolutions greater than 9 bits can be calculated using the data from the
3
temperature, COUNT REMAIN and COUNT PER °C registers in the scratchpad.
4
Note that the COUNT PER °C register is hard-wired to 16 (10h). After
5
reading the scratchpad, the TEMP_READ value is obtained by truncating
6
the 0.5°C bit (bit 0) from the temperature data (see Figure 2).
7
The extended resolution temperature can then be calculated using the
8
following equation:
9
10
COUNT_PER_C - COUNT_REMAIN
11
TEMPERATURE = TEMP_READ - 0.25 + ----------------------------
12
COUNT PER C
13
</Zitat>
Und? Wo ist jetzt da das Problem. Hol dir die Werte aus dem Scratchpad,
TEMP_READ hast du ja schon, COUNT_PER_C ist Byte 6 und COUNT_PER_C ist
Byte 7, und rechne das aus. Addieren, Dividieren und ein wenig
Subtrahieren wirst du ja wohl können.
Wie sinnvoll der Wert sein wird, steht auf einem anderen Blatt. Offenbar
nicht besonders, sonst hätte Maxim die 4 Bits gleich in die Scratchpad
Byte 0 und 1 mit eingearbeitet.
So nachdem ich mir den Wert jetzt noch zusätzlich per RS232 ausgeben
lasse, habe ich gemerkt, dass der Wert manchmal > 9 ist und somit meine
Anzeige nicht passt.
Was mache ich falsch?
Welchen Sinn hat der Beitrag von Karl Heinz Buchegger ??
Außer einen Zweifel zu äußern und andere zu verunsichern, das kann
jeder.
Wenn man im Datenblatt die angegebenen Fehlerparameter bewertet, dann
ist eine relative Auflösung von 1/16°C machbar.
Joe
Hier mal ein Ausschnitt aus einem Programm, dass schon lief:
' Genauere Temperaturberechnung auf 0,1 °C
I = Sc(1) And 1
If I = 1 Then Decr Sc(1)
T = Makeint(sc(1) , Sc(2))
T = T * 50
T = T - 25
T1 = Sc(8) - Sc(7)
T1 = T1 * 100
T1 = T1 / Sc(8)
T = T + T1
T = T / 10 'z.B. 273
Ta = T / 10 'z.B. 27
T1 = Ta * 10 'z.B. 270
Tb = T - T1 'z.B.
273-270=3
' Temperatur in 0,1 Grad Schritten ausgeben
Locate 1 , 12
Lcd Ta ; "." ; Tb ;
Lcd Chr(&Hdf)
'Else
' Wenn Fehler Scratchpad zur Kontrolle Hexadezimal ausgeben
Locate 2 , 1
' Es passen nur 8 Byte auf das Display
For I = 1 To 8
Lcd Hex(sc(i))
Next
End If
' Ausgabe alle 3 Sekunden
Waitms 3000
Joe schrieb:> Wenn man im Datenblatt die angegebenen Fehlerparameter bewertet, dann> ist eine relative Auflösung von 1/16°C machbar.
Auflösung ist nicht gleich Genauigkeit.
Welchen Sinn hat es 25 Kommastellen auszugeben, wenn die Einerstelle
schon falsch ist?
Joe schrieb:> Wenn man im Datenblatt die angegebenen Fehlerparameter bewertet, dann> ist eine relative Auflösung von 1/16°C machbar.
Es ist auch machbar, auf den Mond zu fliegen.
Wie sieht denn eine "Bewertung der Fehlerparameter" aus?
Ich habe doch nur von relativer Auflösung gesprochen!
Wenn @Karl Heinz Buchegger dir der Unterschied klar ist, dann müsstest
du hier doch alles verstanden haben.
Ebenso solltest du dann auch das Machbare und die Grenzen des DS18S20
besser kennen.
Hast du schon mal damit gearbeitet?
Joe
Joe schrieb:> Ich habe doch nur von relativer Auflösung gesprochen!
Und ich spreche von Genauigkeit.
Welchen Sinn hat es eine Temperatur auf 0.1°C anzuzeigen, wenn die
Temperatur alleine durch die Eigenerwärmung des Chips schon nicht mit
der Umgebungstemperatur übereinstimmt? Welchen Sinn hat es eine
Temperatur auf 0.1°C anzugeben, wenn du in einem Raum 10 Zentimeter
daneben schon eine ganz andere Anzeige in den Nachkommastellen hast?
Etwas auf 2 Nachkommastellen ausrechnen und anzeigen zu können ist eine
Sache. Aber eine ganz andere Sache ist es, ob das auch sinnvoll, weil
genau ist.
Das eine ist die Auflösung, das andere die Genauigkeit. Eine uhr die 8
Minuten falsch geht, geht 8 Minuten falsch. Egal ob sie diese Uhrzeit
dann auch noch auf die Hunderstelsekunde anzeigt oder nicht.
Aber leider leben wir in einer Zeit, in der man gerne durch möglichst
viele Kommastellen Genauigkeit vortäuscht. Völlig egal ob die Uhr falsch
geht oder nicht, Hauptsache sie zeigt auch noch Tausendstel an.
> Hast du schon mal damit gearbeitet?
Hab ich.
Hast du schon mal beobachtet, wie die Temperatur gar nicht mal so
langsam davon driftet, wenn man die Abtastzyklen zu kurz wählt?
Vorweg, mir ist schon klar, dass die Genauigkeit dadurch nicht besser
wird, aber ein Trend wird eher sichtbar.
Noch eine Möglichkeit:
Dim Array_1wire(10) As Byte
Dim Temperatur As Integer At Array_1wire(2) Overlay
Dim Count_remain As Byte At Array_1wire(8) Overlay
Dim Count_per_c As Byte At Array_1wire(9) Overlay
Dim Teilgrad As Integer
Shift Temperatur , Right
' Temperatur in 1 Grad-Schritten bleibt übrig
Temperatur = Temperatur * 100
'Temperatur * 0,01 in Grad-Schritten für Berechnung
Temperatur = Temperatur - 25
' - 25/100 Grad nach DS18S20 Datenblatt
Teilgrad = Count_per_c - Count_remain
Teilgrad = Teilgrad * 100
Teilgrad = Teilgrad / Count_per_c
Temperatur = Temperatur + Teilgrad
Temperatur = Temperatur / 10
'In Temperatur steht jetzt der Wert (integer) in 0,1 Grad Schritten.
Gruss allu
allu schrieb:> Vorweg, mir ist schon klar, dass die Genauigkeit dadurch nicht besser> wird, aber ein Trend wird eher sichtbar.
Dann, aber nur dann, wenn der Messfehler stetig und halbwegs linear
verläuft. Es gibt Messanordnungen, die durchaus eine zufällige
Komponente aufweisen.
Solange man nichts über die Systematik des Messfehlers in einer
definierten Anordnung aussagen kann, ist das mit dem Trend auch nur eine
Behauptung.
allu schrieb:> Vorweg, mir ist schon klar, dass die Genauigkeit dadurch nicht besser> wird, aber ein Trend wird eher sichtbar.
Dann, aber nur dann, wenn der Messfehler stetig und halbwegs linear
verläuft. Es gibt Messanordnungen, die durchaus eine zufällige
Komponente aufweisen.
Solange man nichts über die Systematik des Messfehlers aussagen kann,
ist das Mit dem Trend auch nur eine Behauptung.
Ich will auch mal Recht haben.
Hurra, es schneit (auch wenn mir das bei diesem Winter keiner so recht
glauben will).
Hurra, es sind gerade 30,2°C im Schatten (auch wenn mir das zu dieser
Tageszeit keiner so recht glauben will).
Aber trotzdem sind beide Aussagen wahr.
Irgendwo !
Fazit: ich kann behaupten was ich will, ich habe immer Recht!
Sensorium schrieb:> Solange man nichts über die Systematik des Messfehlers aussagen kann,> ist das Mit dem Trend auch nur eine Behauptung.
Die Praxis, es funktioniert !
Jonas schrieb:> Ich will auch mal Recht haben.
Danke, erklärt vieles.