DS18B20 mit 2 Nachkommastellen? (Bascom)

Gast #1651962
Lesenswert?

Ich möchte in einem programm mit dem DS18b20 mit der 2. Nachkommastelle 
rechnen, egal, ob der Wert bei diesem Sensor Sinn macht oder nicht, ich 
bräuchte diese 4. Stelle im Temperaturwert.
Ich rechne bisher mit dem Wert als Integer, 32.3 °C sind also 323, da 
ich nun die 4. Stelle benötige, steh ich vor einem Problem. (32.34 °C 
sollen als 3234 im Programm übergeben werden)

Hier der entsprechende Code: für xx.x °C


' DS18B20
Config 1wire = Portc.0                                      ' DS18S20 
port
Dim B As Byte
Dim Wirect As Word
Dim Dg As Integer
Dim Dsid1(8) As Byte                                        ' Dallas ID 
64 bits incl CRC
Dim Sc(9) As Byte                                           ' Scratchpad 
0-8 72 bits incl CRC, explanations for DS18b20
Declare Sub Ds18b20() As Integer
Declare Function Decigrades(byval Sc(9) As Byte) As Integer
' DS18B20

Sub Ds18b20()
   Wirect = 1wirecount()
   Dsid1(1) = 1wsearchfirst()

   Letzter_isttemp = Isttemp                                ' letzten 
Messwert merken

   1wreset                                                  ' reset the 
bus
   1wwrite &HCC                                             ' skip rom
   1wwrite &H44                                             ' Convert T
   Waitus 1200
   1wverify Dsid1(1)                                        'Issues the 
"Match ROM "
   1wwrite &HBE
   Sc(1) = 1wread(9)                                        'read bytes 
into array
   Waitms 250
   If Sc(9) = Crc8(sc(1) , 8) Then
   Dg = Decigrades(sc(9))
   Isttempt = Dg
   End If
End Sub

Function Decigrades(byval Sc(9) As Byte)
 Decigrades = 0
 Decigrades = Makeint(sc(1) , Sc(2))
 Decigrades = Decigrades * 10
 Decigrades = Decigrades / 16
End Function


isttemp soll dann der Integerwert der Temperatur xx,xx *100 sein, also 
xxxx
ich habe auch schon Dg als single deklariert (fand ich mit google in 
'nem anderen forum), das ergab allerdings einen compiling-fehler
außerdem habe ich decigrades  10 in decigrades  100 geändert, das 
hatte eine negative Temperatur auf dem LCD zur Folge ...

danke für eine kurze Hilfe, ich seh hier gerade nicht mehr durch ...
Persönliche Seite #1652108
Lesenswert?

Hannes Lux schrieb:
>> warum da durch 16 steht, keine Ahnung ... :o
>
> Weil zum Interpolieren (Erhöhung der Anzeige-Auflösung) 16 Messungen
> herangezogen werden und demnach der Nachkommateil durch 16 geteilt
> werden muss. Siehe Formel im Datenblatt (ist zumindest beim DS18S20 so).

Beim DS18B20 kann ich das in der BASCOM Appnote nicht nachvollziehen. 
mal 10 durch 16 gibt eine verkorkste durch 2 Rechnung. Die durch 2 
Rechnung, die ich laut DS18B20 Datenblatt erwarte, fehlt. Ich traue der 
BASCOM Appnote nicht.

Ich sehe auch im DS18B20 Datenblatt keinen Weg an die Nachkommastellen 
des ADC ranzukommen so wie es im DS18S20 Datenblatt zur Erhöhung der 
Auflösung beschrieben ist.
Gast #1652255
Lesenswert?

Hannes Lux schrieb:
> Das 18B20-Datenblatt habe ich mir nicht angesehen, ich habe und will die
> Dinger nicht.

Warum? Ich finde die Dinger nur geil. Ich habe 10 Stck bei mir im 
Einsatz. 0.5°C Genauigkeit ohne den analogen Schnickschack.
#1652273
Lesenswert?

Nik schrieb:
> den code habe ich so gefunden und schon in anderen Programmen
> eingesetzt, bei dem ich nur 1 Stelle nach dem Komma brauch
> warum da durch 16 steht, keine Ahnung ... :o

Oooch Nööö, in Mathe ne 6 gehabt?

Steht doch alles im Datenblatt, der DS18B20 gibt 1/16°C aus.
also für 0,01°: x * 100 / 16, aber in 32 Bit rechnen, sonst gibts nen 
Überlauf. Oder in float rechnen.
Keine Angst vor float, der AVR rechnet >1000-mal schneller als ein 
Mensch ablesen kann.


Peter
#1652296
Lesenswert?

ich traue bascom schrieb:
> Hannes Lux schrieb:
>> Das 18B20-Datenblatt habe ich mir nicht angesehen, ich habe und will die
>> Dinger nicht.
>
> Warum? Ich finde die Dinger nur geil. Ich habe 10 Stck bei mir im
> Einsatz. 0.5°C Genauigkeit ohne den analogen Schnickschack.

Sorry, ich bin da vom 1822 (+/- 2°C) ausgegangen. Habe inzwischen das 
Datenblatt heruntergeladen und bin betreffs "Teilen durch 16" zu 
demmselben Schluss wie Peter gekommen (da ist die Interpolation bereits 
drin, die man beim 18S20 noch selbst machen müsste/könnte).

Nachdem ich auch die Verfügbarkeit (wo gibt es den zu welchem Preis) 
geprüft habe, nehme ich das "und will die Dinger nicht" natürlich 
zurück.

Danke für den Hinweis, ich hatte den DS18B20 aufgrund der Verwechslung 
mit dem DS1822 total übersehen.

...
Gast #1652328
Lesenswert?

lol nein, ich hatte keine 6 in mathe ^^
ich hab mir das datenblatt zwar angesehen, das ist für mich aber 
normalerweise fachchinesisch ^^
ich bin hobbybastler und programmiere so gesehen sehr selten.
ich suche mir oft fertigen code im www und ändere den nach meinen 
bedürfnissen ab, meist verstehe ich, was passiert, aber halt nicht 
komplett alles davon.

also, wenn ich *100 /16 rechne und am ende eine negative temperatur 
herauskommt, liegt das daran, dass ich nicht mit 32 bit rechne bzw mit 
float?

jetzt muss ich nur noch mal sehen, was ich am code ändern muss, mit dem 
von Rolf geposteten code kann ich nix anfangen ^^

also die sensoren find ich auch nicht übel, die vorteile überzeugen mich 
eigentlich, keinen lm35 zu nehmen etc, vorallem kann man quasi eine 
unmenge an eine leitung hängen und nach wunsch abfragen.
was mir allerdings erst mal nicht so gefällt, die messen vielleicht auf 
0.5 °C genau, aber die abweichung zum (auch digitalen) raumthermometer 
beträgt 2-6 °C ...
Persönliche Seite #1653398
Lesenswert?

Wenn du rechnest

 Decigrades = 0
 Decigrades = Makeint(sc(1) , Sc(2))
 Decigrades = Decigrades * 100
 Decigrades = Decigrades / 16

ist die max. Temperatur ohne signed 16-Bit Überlauf 22 °C

wenn du so rechnest

 Decigrades = 0
 Decigrades = Makeint(sc(1) , Sc(2))
 Decigrades = Decigrades * 25
 Decigrades = Decigrades / 4

ist die max. Temperatur ohne Überlauf "355" °C, also mehr als der Sensor 
jemals liefert.

Beide Rechnungen sind mathematisch gleich, es wurde nur durch 4/4 
gekürzt.

x * 100/16 = x `* 25/4
Gast #1653434
Lesenswert?

Hallo!

Wissend mich hier auf Glatteis zu begeben:

Nik schrieb:
> Function Decigrades(byval Sc(9) As Byte)
>  Decigrades = 0
>  Decigrades = Makeint(sc(1) , Sc(2))
>  Decigrades = Decigrades * 10
>  Decigrades = Decigrades / 16
> End Function

Du deklariest Decigrades als Byte. Dann versuchst Du daraus ein Integer
zu machen. Lies mal in der Hilfe zu "MAKEINT"

Kannst Du die Quelle zu dem Code angeben?

Noch was: Die 1200µs sind auch arg kurz.

Mfg
Gerhard
Gast #1654200
Lesenswert?

@kg: die Quelle steht oben (die URL, die zu MCS führt)

die von Dir angesprochene Zeit kommt erst nach dem read, bei mir mit 
waitms 250. Die >400 sind bei höherer Genauigkeit notwendig, bei 9 bit 
sind's glaub ich nur etwa 120 ms, die der chip benötigt, bei 12 bit etwa 
750 ms
ich hatte bisher die 250 ms sogar ganz weggelassen und es funktioniert 
problemlos, jedenfalls seh ich keinen auftretenden Fehler

Mir ist auch der Zusammenhang nicht klar, warum *25 /4 etwas anderes 
ergibt als *100 /16, da fehlt mir das Fachwissen :)
Ich nehme aber an, die 100 sind 3 byte und somit nicht mehr 16 bits 
sondern 24 und deswegen gibt's das Rechenproblem?

Nachdem ich auf *25 /4 geändert hab, geht alles, wie es soll :o

Vielen Dank dafür!
Persönliche Seite #1654286
Lesenswert?

Angenommen du hast sommerliche 30 °C im Zimmer.

Der Sensor arbeitet mit 12-Bit, d.h. 0,0625 °C pro Bit.

Der Sensorwert in Bits ist dann 30 °C / (0,0625 °C/Bit) = 480_dez oder 
0x01E0_hex Bit

Um auf zwei Nachkommastellen zu kommen multiplizierst du mit 100:

480 * 100 = 48000

ABER der größte positive Integer ist 32767 (0x7FFF_hex).

48000 ist 0xBB80_hex und das wird als negativer Integer (-17536) 
interpretiert.

http://de.wikipedia.org/wiki/Zweierkomplement#Darstellung_und_Umwandlung_aus_dem_Dezimalsystem

0xBB80_hex = 0b1011101110000000_bin
              /  \
        -32768  + 0b0011101110000000 = -32768 + 15232 = -17536

-17536 / 16 = -1096 => -10.96 °C

Statt mal 100 durch 16 wird mal 25 durch 4 gerechnet. Das ist 
mathematisch gleichwertig, ABER

480 * 25 = 12000, d.h. gut innerhalb 0..32767 und KEIN Überlauf!
Gast #1654319
Lesenswert?

ahhh danke, jetzt wird's mir klar
Irgendwann vor ein paar Jahren hab ich schonmal davon gehört :)

Ich bin gerade dran, mir eine Lüftersteuerung zu bauen, die etwas mehr 
nach meiner Vorstellung funktioniert (auf einer amateurfunkwebsite 
gibt's schon eine Steuerung, allerdings scheint die für große 
Temperaturunterschiede gedacht zu sein) meine Toleranz hab ich hier mit 
t-0.2 ... temp ... t+0.2°C
jetzt hab ich den Lüfter mit verschiedenen PWM-Werten laufen lassen und 
geguckt, bei welchen Werten der welche lautstärke hat.
dann hab ich mir Bereiche gesetzt (unter unterem limit, von unterem 
limit bis untere toleranz, von unterer toleranz bis sollwert, von 
sollwert bis obere toleranz, von oberer toleranz bis oberes limit, über 
oberem limit)

dann die änderung des pwm-wertes um jeweils 5, beginnend ab pwm = 90
den pwmwert berechne ich dann z.b.
pwmfaktor = isttemp - limit_unten
pwmfaktor = pwmfaktor * 5
pwmert = 90 + pwmfaktor

Natürlich bin ich davon ausgegangen, dass sich die 2. Nachkommastelle 
nicht in 6(.25)er-Schritten ändert ^^
sodass ich dann eine art gleitende Änderung des Wertes bekomme
aber bei einer temp-änderung mit faktor 6  muss ich mir das noch mal 
überdenken ...

das programm funktioniert bereits, wie ich es mir vorstelle, aber der 
Sprünge sind noch zu groß

mein erster gedanke wäre, die /4 erst später zu machen und mit dem 
größeren wert zu rechnen, aber wie gesagt, ist bisher erst noch theorie 
und nicht weiter durchdacht ...

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