PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bascom DCF77 und DS18B20 funktionieren nicht zusammen



Tido
15.01.2019, 17:00
Hallo,

ich habe ein Programm, dass einmal die Minute zwei Temp-Sensoren DS18B20 ausliest.
Funktioniert auch wunderbar.
Des Weiteren habe ich einen DCF77-Baustein angeschlossen, der auch wunderbar funktioniert,
wenn die Auswertung der Temp-Sensoren deaktiviert wird.
Ich habe hier einige Beiträge zu diesem Problem gefunden (Suchbegriff(e): dcf77, ds1820), aber in keinem wird der Grund dafür genannt,
warum die DCF-Zeitsynchro nicht funktioniert, wenn 1 Mal pro Minute die Temp-Sensoren ausgewertet werden.

Ich verwende einen Mega32 mit 8MHz, mein Testcode sieht folgendermaßen aus:




Config Dcf77 = Pind.3 , Timer = 1 , Inverted = 0 , Timer1sec = 1 , Update = 2 , Updatetime = 3
Config 1wire = Porta.5
Enable Interrupts
Config Date = Dmy , Separator = .

Do
Print Time$ , " " , Date$ , " " , Dummyword
If _sec = 2 Then Gosub Temperatur
Loop


Temperatur: 'Fehler 1-9
'Testweise nur 1 Sensor

Ds18b20(1) = 1wsearchfirst()

Messung:
1wverify Ds18b20(1) ' Gerät mit der SerienNr. aus Ar() auswählen
If Err = 0 Then
1wwrite &H44 ' Temperaturmessung anstoßen
Waitms 750 ' warten bis Messung fertig
1wverify Ds18b20(1) ' Gerät mit der SerienNr. aus Ar() auswählen
1wwrite &HBE ' Temperatur auslesen
Ds18b20(1) = 1wread(9) ' Daten in ein Array lesen
Dummyint = Makeint(ds18b20(1) , Ds18b20(2))
Temp = Dummyint / 16

Temp = Temp * 10
If Temp < 0 Then
Dummyword = Int(temp)
Temp = Temp - Dummyword
Dummyword = Dummyword + 1000
Else
Dummyword = Int(temp)
Temp = Temp - Dummyword
End If
Temp = Temp * 10
If Temp = 5 Or Temp > 5 Then Incr Dummyword
Else
Fehler = 1
End If



So wie abgebildet wird die Uhr nicht gestellt, Temperatur funktioniert.
Kommentiere ich "If _sec = 2 Then Gosub Temperatur" aus, so wird die Uhr nach ca.
3 Minuten gestellt.

Warum ist dies so? Ich habe gelesen, dass für 1Wire kein Timer verwendet wird.

EDIT: Gerade für 30 Minuten weggewesen, komme wieder: Uhr noch nicht gestellt. Schalte den Laptop ein, Programmer führt Reset aus und 5 Minuten später geht die Uhr richtig. Also funktioniert es "nur" unzuverlässig, wenn die Temp-Sensoren ausgewertet werden. Aber warum....??? Ohne die Sensorenauswertung wird die Zeit immer in 3 Minuten gesynct.
EDIT2: Das hat bisher nur einmal funktioniert.

wkrug
15.01.2019, 19:38
Ich könnte mir da ein paar mögliche Fehlerquellen denken.
1. Die Impulse beim Abfragen des 1wire Sensors stören den Empfang des DCF 77 Signals.
2. Die Antenne des DCF 77 Empfängers ist falsch ausgerichtet ( Muß in 90° Winkel Richtung Frankfurt stehen ).
Ich hab bei Mir ne LED Eingebaut und immer wenn ein High am DCF Empfänger anliegt, Leuchtet die an einem anderen Port angeschlossene LED.
3. Die 1wire Abfrage stört das Timing der DCF 77 Impulsauswertung und die Einsen und Nullen werden nicht mehr richtig erkannt.

Tido
15.01.2019, 19:50
Hallo wkrug,

danke für die Antwort.
2. scheidet aus, da die Zeitauswertung ohne Abfrage der Sensoren und ohne Änderung der Antennenausrichtung innerhalb von ca. 3 Minuten IMMER erfolgreich ist.
1. ist möglich, allerdings liegen die Pins (17 und 35) und Leiterbahnen sehr weit auseinander (quasi diagonal am Mega32).
3. ist mein Favorit, allerdings verstehe ich es nicht, da die DCF ja angeblich über einen Timerinterrupt läuft und den 1wire unterbrechen sollte; es sei denn, 1wire stoppt die Interruptausführung - dazu finde ich leider nix.

wkrug
15.01.2019, 20:29
2. scheidet aus, da die Zeitauswertung ohne Abfrage der Sensoren (http://www.rn-wissen.de/index.php/Sensorarten) und ohne Änderung der Antennenausrichtung innerhalb von ca. 3 Minuten IMMER erfolgreich ist.
Mein Verdacht war, das Du beim Anschließen des 1wire die Platine in eine ungünstige Richtung verdreht hast.


1. ist möglich, allerdings liegen die Pins (17 und 35) und Leiterbahnen sehr weit auseinander (quasi diagonal am Mega32).
Ich meine auch eher eine Einstreuung über die Antenne des DCF Empfängers, oder über die Stromversorgung - Nimm doch mal zum 1wire sensor ein abgeschirmtes Kabel und verpass dem DCF Modul beim Spannungseingang einen Widerstand und eine größeren Kondensator.


3. ist mein Favorit, allerdings verstehe ich es nicht, da die DCF ja angeblich über einen Timerinterrupt läuft und den 1wire unterbrechen sollte; es sei denn, 1wire stoppt die Interruptausführung - dazu finde ich leider nix.
Es wäre theoretisch möglich, das in bestimmten Phasen bei der 1wire Abfrage die Interrupts gesperrt werden.
Das würd Ich mal nachgucken.
Wie das DCF im Timer Interrupt implementiert ist weiß Ich natürlich nicht.
Ich würde es vermutlich mit einem Input Capture Interrupt mit wechselndem Sensing machen.
INT0 bzw. INT1 mit wechselndem Sensing und Auslesen eines frei laufenden Timers sollte aber auch funktionieren.

Eine weitere Möglichkeit wäre Timer Interrupts laufen zu lassen und dann jeweils im Interrupt den DCF Pin abzufragen.
Das würde Ich nicht machen, weil dann der Timer mit relativ hoher Frequenz laufen müsste um die Flanken der DCF Impulse einigermassen zeitnah zu treffen.


Die Routine für die DCF Abspeicherung und Auswertung könnte man beibehalten.
Der Impulsauswerteteil kann ja umgeschrieben werden, falls der "ungünstig" ist ( Hab Ich bei meinem C Beispielcode gemacht ).
Wenn dein Controller dann gerade 1wire macht, wird der Pin nicht abgefragt und dann u.U. zu spät abgefragt = Fehlinterpretation des DCF Signals.

Um da das richtige zu sagen müsste man die DCF 77 Routine kennen.

fredred
02.02.2019, 12:14
Hallo Tido;
Config Dcf77 läuft grundsätzlich im Hintergrund und sollte Keinerlei Probleme mit ein aktivierten Bus bekommen.

Versuches mal so.
Config Dcf77 = Pind.3 , Timer = 1 Inverted = 0, Debug = 1 , Check = 1

'Datumsformat festlegen
Config Date = Dmy , Separator = .

'Interrupts müssen aktiviert werden
Enable Interrupts

'++++++ Starteistellungen ++++++
' ........
' Dcf_status.7 = 1 'nicht auf DCF77 OK warten
'+++++++++++++++++++++++++++++++++++
' Auf die Synchronisierung der Uhrzeit mit dem DCF77 Zeitsignal warten
While Dcf_status.7 = 0
' solange die Zeit nicht stimmt
Print
Print "demodu " ; Bin(dcf_bits)
Print “Dcf_status.7 = “;“Dcf_status.7
Print " " ; "time " ; " " ; "date "
Print "DCF: " ; ; " " ; Time(dcf_sec) ; " " ; Date(dcf_day)
Print "Clock:" ; ; " " ; Time$ ; " " ; Date$

Waitms 100 'nur für Test
Wend
Cls
Print "Uhrzeit erfolgreich synchronisiert! " ; Time$ ; " " ; Date$

'*** nach Neustart immer etwas Zeit geben *****
Wait 1
Ab hier mach dein Ding.
Do Print Time$ , " " , Date$ , " " , Dummyword If _sec = 2 Then Gosub Temperatur Loop ………………..
MfG