PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Temperaturmessung mit DS1820 spinnt manchmal



Pöler
08.11.2008, 21:25
Hallo zusammen,

ich habe mir mit dem Mega 8 eine kleine Temperaturmessstation aufgebaut. Im Grunde werden 4 DS1820 Temperatur Sensoren (je einer an einem I/O Pin) und 2 Schalter sowie 4 Taster per Analog Port abgefragt und die Betriebszustände und Temperaturen auf einem 2*16 LCD Display angezeigt.
Das ganze klappt auch hervorragend. Bascom sagt mir, der Speicher sei zu 99% belegt ;-). Das liegt wohl daran, das per Menu eine Menge Parameter voreingestellt und auf Wunsch im EEPROM abgelegt werden können. Nach der Inbetriebnahme habe ich 2 Dinge festgestellt, die ich nicht nachvollziehen kann:

1. Die 1. Temperaturmessung nach dem Reset zeigt immer 85 Grad an.

2. Gelegentlich (selten und unregelmäßig) wird ein falscher Temperaturwert (meistens -0,5 Grad) angezeigt. Die nächste Messung ist wieder OK.

Vermutlich handelt es sich um ein Timing Problem. Allerdings kann ich es nicht identifizieren. Die Messzyklen habe ich bereits von 1 Sekunde auf 2 Sekunden ohne Erfolg verdoppelt.

Die relevanten Teile des Codes füge ich mal an. Erwähnenswert ist wohl noch, das der Timer offensichtlich korrekt arbeitet, da sämtliche aus der Timer ISR abgeleitete Funktionen wie Blinkfrequenzen, Anzeigedauer von Warnmeldungen etc. nachmessbar stimmen.

Da das mein erstes Projekt mit den DS1820 ist, weiss ich nicht mehr weiter. Vielleicht kann sich jemand mal den Code ansehen?

Gruß

Horst



$regfile = "m8def.dat"
$crystal = 3686400

'Timer 0 auf 50 Hz setzen (20 ms)
Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer_irq 'ISR für Timer 0 festlegen
Enable Timer0

Dim Timervorgabe As Byte
Timervorgabe = 185

'Hauptprogramm

Do
Gosub Betriebsmodus
Gosub Temperaturmessung 'Alle 4 Sensoren messen
Gosub Analogtaster 'Taster betätigt?
If Wert < 900 Then 'Ein Taster betätigt
Gosub Auswertung 'welcher Taster?
End If
If Bmodus = 1 Or Bmodus = 4 Then 'Nur in Modus 1 + 4
If Taster = 4 Then 'Einstellungen ändern
Gosub Hauptmenu
Taster = 0
End If
End If
If Taster = 3 Or Taster = 2 Then 'Auswahl des Sensors
Gosub Sensorwahl
End If
Gosub Tempanzeige 'Anzeige des ausgewählten Sensors in Zeile 2
Taster = 0 'Tasterwert auf definierten Wert zurücksetzen
Loop
End

'Auslesen der DS1820 Temperatursensoren

Temperaturmessung:
If Tempmess >= 96 And Verriegelung = 0 Then '1920 ms (96*20) seit dem Reset vergangen
Gosub Messen 'Also Temperaturmessung
Tempmess = 0
Verriegelung = 1 'Und Merker zurücksetzen
End If
If Tempmess >= 4 And Verriegelung = 1 Then '80ms (4*20) nach Reset auslesen der Temp. Sensoren
Gosub Auslesen
Tempmess = 0
Verriegelung = 0
End If
Return

Messen:
For I = 1 To 4
1wreset Pinc , I 'Reset DS1820
1wwrite &HCC , 1 , Pinc , I 'überspringe ROM
1wwrite &H44 , 1 , Pinc , I 'starte Konvertierung
Next I
Return

Auslesen:
For I = 1 To 4
1wreset Pinc , I 'Reset DS1821
1wwrite &HCC , 1 , Pinc , I 'Überspringe ROM
1wwrite &HBE , 1 , Pinc , I 'sende T-Register 60h und 61h an Atmel
Ds1820 = 1wread(2 , Pinc , I) 'lese die empfangenen Daten 2 Byte
Ds1820a(i) = Ds1820 'Zum Anzeigen des ausgelesenen Wertes (Sensortest)
1wreset Pinc , I 'Reset DS1821
Halb = Ds1820 And 1 'prüfen auf letztes Bit (x.5 Grad)
Shift Ds1820 , Right 'entferne letztes Bit (Rechtsschieben)
Ds1820 = Ds1820 And 255 'Nur die unteren 8 Bit werden benötigt
If I = 1 Then
Tesp = Ds1820 'Ganzzahlige Temperatur der ESP (1 Byte) '
End If
If Ds1820 > 127 Then 'wenn Temperatur negativ ist
Vorzeichen = "-"
Ds1820 = 256 - Ds1820 'und negative Temperatur berechnen
If Halb = 1 Then Ds1820 = Ds1820 - 1 'wenn Wert x.5 dann um 1 korrigieren
Else 'wenn Temperatur Positiv
Vorzeichen = " "
End If
If Halb = 1 Then
Nachkomma = "5" 'wenn x.5
Else 'wenn x.0
Nachkomma = "0"
End If
Temperatur = " " + Vorzeichen + Str(ds1820) '"-_-xxx"
Temperatur = Right(temperatur , 4) '"-xxx"
Temperatur = Temperatur + "." + Nachkomma + Chr(223) + "C" '"-xxx.y°C" 8 Zeichen
Sensor(i) = Temperatur
Next I
Return



'Timer 0 ISR

Timer_irq:
Timer0 = Timervorgabe 'Timer vorladen für 20ms
Zaehlerwert = Zaehlerwert + 1 '20 ms
Tempmess = Tempmess + 1 '20ms Sekunden für Tempmessung sind rum
If Zaehlerwert >= 5 Then '5*20 ms = 100ms
Zaehlerwert = 0
Zehntel = Zehntel + 1
End If
Return

linux_80
08.11.2008, 22:22
Hi,

schon mal ins Wiki geschaut, da hab ich etwas zu Bascom und 1-Wire aufgeschrieben.

zu 1.:
Wenn man ins DB des DS1820 schaut, sieht man, dass der nach einem Reset als erstes 85° ausgibt, wenn man ihn vor einer Messung, bzw. zu schnell nach dem starten der Messung abfrägt.
Also Zeit lassen nach dem Starten der Messung !

Zu 2.:
Man sollte immer alle Bytes lesen die der DS1820 sendet, und dann per CRC überprüfen ob das gesendet überhaupt stimmt, dann kommen solche Fehler gleich viel seltener vor !

Pöler
08.11.2008, 22:51
Hallo linux_80,

danke für die schnelle Antwort,

gerade habe ich mir das Datenblatt noch einmal vorgenommen und

1. auch gefunden. Damit steht die Lösung fest: Die erste Messung verwerfen.

2. Laut Datenblatt soll die Konvertierungszeit 750 ms betragen. Zwischen dem Reset und dem Auslesen lasse ich eine wesentlich längere Zeit verstreichen. Kann das wirklich sein, das der ausgegebene Wert auf Korrektheit überprüft werden muss? So etwas habe ich noch nirgendwo gelesen. Die Anregung zu meiner Auswertung stammt von hier:

http://www.qslnet.de/member/dg1xpz/elektronik/avr/ds1820.html

Mein Verständnis ist, das der Sensor einen korrekten Wert ausgibt, wenn die Rahmenbedingungen wie Timing, Versorgung etc. eingehalten werden.

Gruß

Horst

linux_80
08.11.2008, 23:04
Wie hast Du den DS1820 angeschlossen, mit eigener Stromversorgung, oder parasitär ?
Denn wenn seine Power per Datenleitung kommt, dauerts nochmal länger.

Das mit dem CRC ist halt so eine Sache, es gibt keine Garantie, das es stimmt, wenn man nicht gegencheckt.
Der 1820 kann die Daten korrekt ausgeben, aber auf der Leitung kann sich ja ein flasches Bit einfangen und schon stimmts nicht mehr, -> Antenne !
Muss man selber wissen wie mans gerne hätte ;-)

Pöler
09.11.2008, 17:47
Hallo Linux_80,

meine 4 Sensoren sind 3-Adrig angeschlossen, also mit externem Power. Was die Antennenwirkung der Leitung bzw. das Kippen sines Bits angeht, kann man das im Auto natürlich nicht ausschließen. Allerdings zeigt die Schaltung auch bei Laborbedingungen (Wohnzimmertisch) mit "guter" Stromversorgung das gleiche Verhalten.

Bei nochmaliger Durchsicht meines Codes fällt mir auf, das die Senssoren im Laufe einer Messung insgesamt dreimal resettet werden. Ich muss zugeben, das ich den Sensor noch nicht komplett durchschaue, sollten aber nicht 2 Resets pro Zyklus reichen? Der 1. um die Messung einzuleiten, dann 750ms warten und dann der 2. Reset um die beiden Bytes auszulesen, danach ein paar us warten und das ganze von vorne?

Gruß

Horst

for_ro
09.11.2008, 21:13
Anfangs hatte ich auch keine Probleme mit den Daten der DS1820. Aber umso komplexer das Programm wurde, umso häufiger traten fehlerhafte Werte auf. Irgendein Interrupt, der dir dazwischen haut und schon ist das ganze Timing dahin. du könntest mal versuchen, um die 1wwrite Befehle ein Disable-Enable Interrupt zu legen.
Ansonsten hast du ja bei Verwendung der 1wwrite Befehle keinen Einfluss auf das Timing. Wenn deine Wartezeit nicht zu kurz ist, sollte es eigentlich immer gehen.
Aber dankenswerter Weise haben die von Dallas ja den CRC implementiert, sodass du die Fehlmessungen leicht rausfiltern kannst. Das ist auch keine große Kunst und hier im Forum schon oft gepostet worden. Mit einer Lookup Tabelle auch ziemlich effizient zu lösen.
Seit ich das eingebaut habe, gibt es keine Probleme mehr.

Gruß

Rolf

Pöler
10.11.2008, 21:31
Hallo Rolf,

danke für Deine Antwort.
Interruptmäßig wird eigentlich nur der Zähler hochgezählt. Wobei mir gerade auffällt, das das doch der Grund sein könnte:

Je nachdem, was der Controller gerade macht, können die Zeitabstände zwischen Messung initiieren und Auslesen natürlich größer werden als errechnet, da der Controller natürlich nicht sofort die Unterprogramme anspringt. Das muss ich mir noch einmal durch den Kopf gehen lassen.

Kannst Du mir zu der CRC Auswertung mal einen Codeschnipsel oder einen Link zur Verfügung stellen, in dem das gut erklärt wird?

Danke und Gruß

Horst

linux_80
10.11.2008, 21:42
Wegen dem CRC,
wie weiter oben schon mal angedeutet, im Wiki ist eine Seite "Bascom und 1-Wire", da ist auch das mit dem CRC dabei.

Pöler
10.11.2008, 22:15
Hallo linux_80,

danke, das ist mir bisher durchgegangen. Wirklich gut erklärt.
So wird das was ;-)

Gruß

Horst