Forum: Mikrocontroller und Digitale Elektronik DS18B20 mit 2 Nachkommastellen? (Bascom)


von Nik (Gast)


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 ...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Da fehlen Codeteile! Wie ist Isttempt dimensioniert und wie wird es im 
Hauptprogramm verwendet? Oder verwendest du Dg weiter, wenn ja, wie?

>  Decigrades = Makeint(sc(1) , Sc(2))
>  Decigrades = Decigrades * 100

Verstehe ich.

> Decigrades = Decigrades / 16

Verstehe ich nicht. Warum teilst du durch 16?

von Nik (Gast)


Lesenswert?

Hallo Stefan :)

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

hier ist der Quellcode, den ich ursprünglich als Basis angenommen hab:
http://www.mcselec.com/index.php?option=com_content&task=view&id=75&Itemid=57

Isttemp => Single

von Hannes L. (hannes)


Lesenswert?

> 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).

...

von Stefan B. (stefan) Benutzerseite


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.

von Hannes L. (hannes)


Lesenswert?

Bascom traue ich sowiso nicht.
Das 18B20-Datenblatt habe ich mir nicht angesehen, ich habe und will die 
Dinger nicht. Ich habe vom 18S20 darauf geschlossen. Ich vermute auch, 
dass die Bascom-Routine für den 18S20 ist.

...

von ich traue bascom (Gast)


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.

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Hier ist die Formel für den DS1620 mit zwei Nachkommastellen
1
{int16_t temp_read= (ds1820_msb * 256 + ds1820_lsb) ;
2
ds1820_temperatur=(temp_read & 0xFFFE)*50 - 25 + ((ds1820_countperc-ds1820_countremain)*100)/ds1820_countperc;}

Mehr Informationen gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=49710#post49710

Gruß Rolf

von Peter D. (peda)


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

von Rolf D. (rolfdegen)


Lesenswert?

Ups..

Ist natürlich der DS1820 und nicht DS1620. Sorry..

von Hannes L. (hannes)


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.

...

von Nik (Gast)


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 ...

von Nik (Gast)


Lesenswert?

also ich nehme mal an, ich deklariere alles als Single, wandle Dg (wenn 
es 4-stellig ist) dann mit round in Integer?

von Nik (Gast)


Lesenswert?

also das ging schon mal nicht ... :)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Was steht in sc(1) und Sc(2)?

von Stefan B. (stefan) Benutzerseite


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

von kg (Gast)


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

von Rene K. (draconix)


Lesenswert?

kg schrieb:
> Noch was: Die 1200µs sind auch arg kurz

Dito, war da nicht was von ~400ms berechnungszeit des DS18B20?!

von Nik (Gast)


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!

von Stefan B. (stefan) Benutzerseite


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!

von Nik (Gast)


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 ...

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
Noch kein Account? Hier anmelden.