PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : dcf77 und ds1820 vertragen sich nicht...



Mosi
26.06.2007, 14:51
Jedenfalls bei mir nicht,
nach einigen Stunden, manchmal auch nur Minuten hängt sich das Programm auf.
(Kann es im Moment nicht posten, bin auf Arbeit)
Programm ist mittlerweile abgespeckt auf
Anzeige der Uhrzeit und Routine für auslesen des Sensors.
egal ob ich den Sensor innerhalb der sectic routine laufen lasse, oder aber mit Hilfe "if _sec=xx then ds1820" nur einmal pro minute aufrufe,
das Programm bleibt früher oder später hängen und zwar exakt zur Uhrzeit des Aufrufes, (die Uhr bleibt stehen).
verwende neueste Bascom mit dcf-lib, mega8 mit 16MHz Takt.
Kennt jemand das Problem?
Gruß, Rene

Dirk
26.06.2007, 19:32
Hallo Rene,

... manchmal auch nur Minuten hängt sich das Programm auf.
(Kann es im Moment nicht posten, bin auf Arbeit)


"Das Programm hängt sich auf, aber ich kann es nicht posten"
Mann, wie soll man denn da irgend etwas dazu sagen? #-o

Wenn du antworten solltest,- könntest du bei einer solchen Frage helfen?
So ein Post ist sinnlos. Stell dein Programm ein.

Gruß Dirk

Mosi
26.06.2007, 20:05
hier die relevanten Teile:



Do
Gosub Temperatur_ds1820

Locate 1 , 1
Lcd Time$ ; " " ; Date$ ;

Locate 2 , 1
Lcd "t=" ; Fusing(stemp , "#.#")
Loop

sectic:
nop
return

Temperatur_ds1820:

1wreset
1wwrite Skiprom
1wwrite Convertt

Do
Temp = 1wread()
Loop Until Temp = &HFF


1wreset

1wwrite Skiprom
1wwrite Read_ram

For I = 1 To 9
Scratch(i) = 1wread()
Next

Temp = Scratch(2)
Shift Temp , Left , 8
Temp = Temp + Scratch(1)
Temp1 = Temp

Temp1 = Temp1 / 2

Stemp = Scratch(8) - Scratch(7)
Stemp = Stemp / Scratch(8)
Stemp = Stemp + Temp1
Stemp = Stemp - 0.25

Return


egal wohin ich "Gosub Temperatur_ds1820" verschiebe(z.B. ins "sectic")
das Programm hängt sich auf,

Gruß, Rene

Mosi
26.06.2007, 20:33
Wenn du antworten solltest,- könntest du bei einer solchen Frage helfen?


Gruß Dirk

Ja! könnte ich! z.B. wären mögliche Antworten:
-die ds1820Auslesung dauert zu lang (länger als eine Sekunde)
-1wire und dcf77 benutzen gleiche Timer,
-beide Routinen können im ungünstigen Fall zeitgleich aufgerufen werden,
-irgendwelche interruptprobleme,
mir würden noch mehr Dinge einfallen, die definitiv nichts mit dem code zu tun haben, ich hab aber vom Bascom-Hintergrund keine Ahnung.
Das was ich allerdings verschwiegen habe, ist der nicht-parasitäre Modus der ds1820.
Ach und nochwas: der jetzt von mir gepostete code entspricht meiner Beschreibung, dürfte nicht überraschend sein, also auch nicht unbedingt nötig
Gruß, Rene

peterfido
26.06.2007, 21:28
Vielleicht rennt er sich in der do...loop until Schleife fest.

icg selbst nutze eine Variable, welche in der sectic um 1 erhöht wird, und bei einem bestimmten Wert (z.B. 5 ) Rufe ich ein Sub auf, welches die Werte einliest und die Variable wieder auf 0 Stellt.

Mosi
26.06.2007, 22:25
hallo peterfido,

daraus entnehme ich dass es bei dir geht,
exakt dasselbe hab ich auch schon probiert, ebenso in dem ich die ds1820-Auslesung durch das Kommando:
if _sec=5 then gosub ds1820
auf eine bestimmte Sekunde gelegt habe, in der Hoffnung, dass es sekunden gibt, wo die dcf-routine nicht so viel zu tun hat (z.B. die ersten10, oder die 59.)
trotzdem ist die ganze Sache irgendwann mal stehengeblieben, und immer in der Sekunde, in der die ds1820-routine aufgerufen wurde.
Übrigens, das Programm hängt richtig fest, auch ein Reset nutzt nichts, nur Spannung abschalten.
kannst du mir dein Sub mal posten? Vielleicht geht das besser als meines...
Gruß, Rene

peterfido
26.06.2007, 23:03
Wenn der Reset nicht geht, solltest du mal testen, ob nicht der DS1820 irgendwas blockiert.

Mosi
27.06.2007, 09:56
das vermute ich auch, wie teste ich das? Und warum läuft alles stundenlang ohne Probleme wenn ich config dcf... und die Anzeige der Uhrzeit weglasse? Das kann doch meiner Meinung nach nur daran liegen, dass da irgendeine Unverträglichkeit vorliegt.
Ich versteh das nicht...
Gruß, Rene

peterfido
27.06.2007, 20:27
Das kann einige Ursachen haben. Es wäre möglich, dass beide Routinen die selben Register nutzen, der Stack überläuft, usw. Du kannst mit der Temperatur warten, bis die Uhr nach DCF gestellt wurde. Dann den Empfang abschalten und die Temperatur abfragen. Wenn die Zeit korrigiert werden soll, die Temperatur vorübergehend nicht abfragen. Bei mir geht aber beides Zeitgleich. Ich habe bloß die Stacks erhöht und die Lese- und Schreibzugriffe auf TWI gegenseitig verriegelt, sodass ein begonnener Vorgang sauber durchgelaufen wird.

Mosi
28.06.2007, 10:45
Danke erstmal, das scheinen mir gute Lösungsansätze zu sein, da hab ich schon mal was zum probieren,
Gruß, Rene

Mosi
30.06.2007, 22:18
Es ist mir beinahe peinlich zu berichten, das eine kräftige Erhöhung der Stacks die Lösung war,
danke, Rene

mat-sche
21.09.2007, 16:42
Hallo und @all,

sitze nun schon seit Stunden daran, DCF77 und einen ds 1820 zum laufen zu bekommen.
Ich benutze die ConfigDCF77 Funktion aus Bascom heraus und einen DS1820 mit einem Mega32.

nun habe ich schon die obrigen Beiträge mir durchgelesen, aber noch keine Lösung gefunden.
Hat jemand nen Codeschnipsel für mich? Oder mir näher erklären wie ich zum ergebnis kommen kann?

Danke MAT

peterfido
21.09.2007, 21:04
Wie weit bist du, was für Fehler treten auf? Bekommt du DCF ohne den DS1820 und umgekehrt zum laufen?

mat-sche
22.09.2007, 09:28
Hallo peterfido,

wie schon in hier alles beschrieben wurde, ist es auch bei mir.
Meine DCF77 Zeit wird korrekt angezeigt, aber es wird nicht die Temperatur
ausgelesen.
Mein DS ist ganz, das Auslesen ohne Uhrzeit funzt. Dabei habe ich mir mal mit nem Oszi den 1Wirebus angeschaut und sehe den "Verkehr" an Daten.
Mit Uhrzeit sieht es so aus, dass Daten zum/vom? gesendet werden, aber wie schon angenommen wird, nicht genügend Zeit zum auslesen besteht.

Was nun?

MAT

peterfido
22.09.2007, 10:09
Ich poste mal ein paar Ausschnitte.
Evtl fehlen ein paar Variablen und Sub Declarationen, oder sind zuviel...




$regfile = "m644def.dat"

$crystal = 16000000


Config Graphlcd = 240 * 64 , Dataport = Porta , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Mode = 6 ', Fs = 5 , Mode = 6


Config Dcf77 = Pind.7 , Timer = 1 , Inverted = 0 , Check = 1 , Update = 0 , Debug = 0 , Gosub = Sectic ', Timer1sec = 1

'Port A0-7: Display Dataport
'Port B0: +5V für DCF Empfänger
'Port B1:
'Port B2-3: I2C für DS1307
'Port B4-7: Externe Tasten
'Port C0-4: Display Kontrollport
'Port C5: High, wenn Uhrzeit gesendet wird. an 2313 D.2
'Port C6: Anforderung Beleuchtung
'Port C7: Ansteuerung Beleuchtung
'Port D0: Seriell Empfangen an 2313 B.1
'Port D1: Seriell Senden an 2313 B.0
'Port D2-4: Tasten für Funkuhrbedienung
'Port D5-6: Relais 1-2
'Port D7: Eingang DCF Empfänger

$baud = 38400 ' use baud rate
$hwstack = 128 ' default use 32 for the hardware stack
$swstack = 128 ' default use 10 for the SW stack
$framesize = 128 ' default use 40 for the frame space

Declare Sub Sekuendlich()
Declare Sub Sbtimers()


Dim Zeit_d As String * 8
Dim Datum_d As String * 8
Dim Suhrzeit As String * 1
Dim Zahl As String * 5
Dim Szeile(8) As String * 40
Dim Szeile5 As String * 5

Dim Stoppds As Byte
Dim Stoppdcf As Byte
Dim Stream As Byte
Dim Timers As Byte
Dim Takt As Integer
Dim Rprozalt As Byte

Dim Zeile As Byte
Dim Buhrzeit As Byte
Dim Ii As String * 5
Dim Belzeit As Byte
Dim Infozeit As Byte
Dim Sekalt As Byte
Dim Sekaltd As Byte
Dim Sein As String * 50
Dim Iein As Integer
Dim Pcmodus As Bit

Dim Bolinfo As Bit

Dim Modus As Byte

Dim Hh As Byte
Dim H As String * 2
Dim Mm As Byte
Dim M As String * 2
Dim Ss As Byte
Dim S As String * 2

Dim Wachhund As Byte
Dim Wachsek As Byte
Dim Wdatum As String * 8
Dim Wzeit As String * 8
Dim Wdatum1 As String * 8
Dim Wzeit1 As String * 8
Dim Wdatum2 As String * 8
Dim Wzeit2 As String * 8
Dim Empfangszeit As Integer ' Minutenzähler für den DCF Power

Dim Pcproz As Integer

Dim I As Byte
Dim X As Byte , Y As Byte
Dim Secalt As Byte


Dim A As Byte
Config Date = Dmy , Separator = . ' Deutsches-Format
Dim Zaehler As Byte

Dim Strzif As String * 1
Dim Zgross1 As Byte
Dim Zgross2 As Byte
Dim Zgross3 As Byte
Dim Zgross4 As Byte
Dim Zgross5 As Byte
Dim Zgross6 As Byte
Dim Zgross7 As Byte

Dim _dsday As Byte
Dim _dsmonth As Byte
Dim _dsyear As Byte
Dim _dssec As Byte
Dim _dsmin As Byte
Dim _dshour As Byte

Dim Wochentag As String * 11
Dim Eingang As String * 1
Dim B As Byte
Dim Nm As String * 8
Dim Uhrzeit As String * 8
Dim Mybaud As Long
Dim Einmod As Byte
Dim _dayofweek As Byte
Dim Bdatum As Bit
Dim Punkt As String * 1
Dim Byzif As Byte
Dim Zuletztgestellt As String * 17

Dcfpower Alias Portb.0

Taste1 Alias Pind.2
Taste2 Alias Pind.3
Taste3 Alias Pind.4
Relais1 Alias Portd.5
Relais2 Alias Portd.6
Sendezeit Alias Portc.5
Belan Alias Pinc.6
Beleuchtung Alias Portc.7

Set Dcfpower
Portb.1 = 1
Portb.4 = 1
Portb.5 = 1
Portb.6 = 1
Portb.7 = 1

Portc.6 = 1

Portd.2 = 1
Portd.3 = 1
Portd.4 = 1






Dim _dsday As Byte
Dim _dsmonth As Byte
Dim _dsyear As Byte
Dim _dssec As Byte
Dim _dsmin As Byte
Dim _dshour As Byte




'configure the scl and sda pins
Config Sda = Portb.3
Config Scl = Portb.2

'address of ds1307
Const Ds1307w = &HD0 ' Addresses of Ds1307 clock
Const Ds1307r = &HD1


Dim Weekday As Byte

Stoppds = 0
Stoppdcf = 0
Takt = 0

Mybaud = 19200

Zeile = 0

Enable Interrupts
Start Watchdog

Do
Reset Watchdog

Call Anzeigen

If Secalt = 1 Then
Secalt = 2
Call Sekuendlich
Call Sbtimers
Call Schalten
Secalt = 0
End If


Loop
End




Sectic:
Secalt = 1
Return

Sub Sekuendlich
If Stoppds = 0 Then
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' start address in 1307

I2cstart ' Generate start code
I2cwbyte Ds1307r ' send address
I2crbyte _dssec , Ack
I2crbyte _dsmin , Ack ' MINUTES
I2crbyte _dshour , Ack ' Hours
I2crbyte Weekday , Ack ' Day of Week
I2crbyte _dsday , Ack ' Day of Month
I2crbyte _dsmonth , Ack ' Month of Year
I2crbyte _dsyear , Nack ' Year
I2cstop
'_dayofweek = Makedec(weekday)
_sec = Makedec(_dssec) : _min = Makedec(_dsmin) : _hour = Makedec(_dshour)
_day = Makedec(_dsday) : _month = Makedec(_dsmonth) : _year = Makedec(_dsyear)

End If


If Dcfpower = 0 Then

If Wachhund = 5 Then
Time$ = Wzeit
Date$ = Wdatum
Gosub Settime
Set Dcfpower
Dcf_status.7 = 0
Empfangszeit = 0
Wachhund = 0

End If

If Wachsek = _sec Then
Wachhund = Wachhund + 1
Else
Wzeit = Wzeit1
Wdatum = Wdatum1
Wzeit1 = Wzeit2
Wdatum1 = Wdatum2
Wzeit2 = Time$
Wdatum2 = Date$
Wachsek = _sec
Wachhund = 0
End If
End If
End Sub



Sub Sbtimers()
If _min = 57 Then
If _sec > 30 Then
Set Dcfpower
Dcf_status.7 = 0
Empfangszeit = 0
End If
End If


If _min = 27 Then
Set Dcfpower
Dcf_status.7 = 0
Empfangszeit = 0
End If


If Empfangszeit < 634 Then
Empfangszeit = Empfangszeit + 1
End If
If Empfangszeit = 634 Then
Empfangszeit = 635
Wachhund = 0
Reset Dcfpower
End If
If Empfangszeit > 635 Then
Empfangszeit = 635
End If

End Sub




Pause:

Waitms 1

Return


Getdatetime:


Return

Setdate:
Stoppds = 1
If _day < 32 Then
If _month < 13 Then
If _year < 100 Then

_dsday = Makebcd(_day) : _dsmonth = Makebcd(_month) : _dsyear = Makebcd(_year)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 4 ' starting address in 1307
I2cwbyte _dsday ' Send Data to SECONDS
I2cwbyte _dsmonth ' MINUTES
I2cwbyte _dsyear ' Hours
I2cstop
End If
End If
End If
Stoppds = 0
Return

Settime:
Dim Gestellt As Bit
Gestellt = 0
Stoppds = 1
Waitms 125
If _sec < 60 Then
If _min < 60 Then
If _hour < 24 Then
If _day < 32 Then
If _month < 13 Then
If _year < 100 Then
Gestellt = 1
_dssec = Makebcd(_sec ) : _dsmin = Makebcd(_min) : _dshour = Makebcd(_hour)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 0 ' starting address in 1307
I2cwbyte _dssec ' Send Data to SECONDS
I2cwbyte _dsmin ' MINUTES
I2cwbyte _dshour ' Hours
I2cstop

_dsday = Makebcd(_day) : _dsmonth = Makebcd(_month) : _dsyear = Makebcd(_year)
I2cstart ' Generate start code
I2cwbyte Ds1307w ' send address
I2cwbyte 4 ' starting address in 1307
I2cwbyte _dsday ' Send Data to SECONDS
I2cwbyte _dsmonth ' MINUTES
I2cwbyte _dsyear ' Hours
I2cstop

Zuletztgestellt = Date$ + "," + Time$
Reset Dcfpower
Wachhund = 0

End If
End If
End If
End If
End If
End If

If Gestellt = 0 Then
Dcf_status.7 = 0
Empfangszeit = 0
End If
Stoppds = 0


Return

In der DCF77.lib


Getdatetime:
Setdate:
Settime:
Ret

auskommentieren.


;Getdatetime:
;Setdate:
;Settime:
;Ret


ansonsten mal deinen Code hier posten.

mat-sche
22.09.2007, 17:29
Hi!

Recht umfangreich sind Deine Codes.....

Also ich habe nur folgendes drin und es funst:

Config Dcf77 = Pinb.0 , Timer = 1 , Inverted = 1 , Timer1sec = 1 , Update = 1 , Updatetime = 1 , Check = 1 , Debug = 1 , 'Switchpower = 1 , Powerlevel = 1 , Powerpin = Pina.2
Enable Interrupts
Config Date = Dmy , Separator = . 'deutsches Datumsformat
'CONFIG CLOCK = SOFT .

Dim I As Integer
Dim Sec_old As Byte , Dcfsec_old As Byte
'Dim Dcf77_signal As Word 'String * 20
Sec_old = 99 : Dcfsec_old = 99 ': DCF_Debug_Timer
= 0

For I = 1 To 78
Waitms 10
If Sec_old <> _sec Then
Exit For
End If
If Dcfsec_old <> Dcf_sec Then
Exit For
End If
Next
Waitms 220
Sec_old = _sec
Dcfsec_old = Dcf_sec

Locate 1 , 1
Lcd Time$ ; " " ; Lookupstr(_weekday , Wochentag) ; " " ; Date$ ; " "


Für die DCF Zeit, und für den Sensor:

Config 1wire = Porta.0
Dim T As Byte
Dim Id1(8) As Byte
Dim Id2(8) As Byte
Dim Ar1(2) As Byte
Dim Ar2(2) As Byte
Dim Ar(2) As Byte
Dim Temperatur1 As Integer
'Dim Temperatur2 As Integer
Dim Halb As Byte

Id1(1) = 1wsearchfirst()
'Id2(1) = 1wsearchnext()



1wreset 'reset
1wwrite &H55 'Match Rom command
1wwrite Id1(1) , 8 'Id von Sensor 1
1wwrite &H44 'Convert T

Waitms 150 '300 'warten bis convert T fertig ist
1wreset 'reset
1wwrite &H55 'match rom command
1wwrite Id1(1) , 8 'id von sensor 1
1wwrite &HBE

For T = 1 To 2
Ar(i) = 1wread(1)

Next
Deflcdchar 0 , 4 , 10 , 10 , 4 , 32 , 32 , 32 , 32 ' replace ? with number (0)
Deflcdchar 1 , 15 , 9 , 9 , 15 , 9 , 15 , 8 , 8 ' replace ? with number (1)

Locate 3 , 1
Temperatur1 = Ar(1)

If Ar(2) > 0 Then Temperatur1 = 0 Else Shift Temperatur1 , Right

Lcd "Au" ; Chr(1) ; "entempra " ; Temperatur1 ; ".";

Halb = Ar(1) And 1

If Halb = 1 Then Lcd "5" Else Lcd "0"

Locate 3 , 18
Lcd ; Chr(0)
Locate 3 , 19
Lcd "C"


Hast Du eventuell nen Code für den DS1820 mit negativer Temp-Anzeige?

Eisbaeeer
22.09.2007, 18:18
Also versuche gerade auch, mehrere DS1820 abzufragen und gleichzeitig die DCF Zeit zu decodieren.
Beides funktioniert einwandfrei, aber unabhängig voneinander.

Nun das Problem ist, dass der DS1820 mind. 750ms zur Decodierung benötigt. Vor allem, wenn man die DS1820 als 1-wire benutzt. Also muss der Bus 750ms auf High liegen, damit die Decodierung funktioniert.

Nun möchte ich nicht die 750ms abwarten, der Atmega langweilt sich in der Zeit und könnte andere Dinge tun, z.B. das DCF Signal weiter decodieren.

Wie ich das ganze löse, weiss ich noch nicht. Hat jemand eine Idee?
Eventuell mit einem Takt (letzter noch übrig gebliebener Timer)?

Grüße Eisbaeeer

for_ro
22.09.2007, 19:37
Hallo zusammen,
ich habe für die ganzen Aufgaben nur einen Timer laufen. Der läuft mit 8KHz über, weil er auch noch RC5 empfangen soll.
Ich benutze allerdings nicht mehr die DCF-Routine von Bascom, sondern meine eigene, weil ich da flexibler bin.
Der Sekundentakt (Interrupt) setzt ein Flag, das im Hauptprogramm abgefragt wird. Dann werden alle 7 DS1820 ausgelesen und anschließend sofort wieder die Konvertierung gestartet. Daher keine extra Wartezeit. Wenn der Sekundentakt wieder das Flag setzt, sind die DS1820 längst fertig.
Das DCF- und das RC5-Signal liegen an externen Interrupt Eingängen. Die Interruptroutinen setzen auch wieder jeweils ein Flag, welches im Hauptprogramm abgefragt wird.
Das ganze sieht dann so aus:


Do
If Interrupt_vektor.7 = 1 Then
'Verarbeitung der eingehenden RC5 Signale
Endif
If Interrupt_vektor.6 = 1 Then
'Verarbeitung der eingehenden DCF Signale
Endif
If Interrupt_vektor.5 = 1 Then
'Konvertierung der Temperaturen
Endif
loop

Get_rc5_isr: 'Verarbeiten der RC5 Impulse
'Print #1 , "Received Get_rc5 Interrupt"
Incr Bit_nummer
Interrupt_vektor.7 = 1
Return

Dcf_empfang_isr: 'Impuls auf Pind.1
'Print #1 , "Received Dcf_empfang Interrupt"
Interrupt_vektor.6 = 1
Return

Sectic:
'Print #1 , "Received Sectic Interrupt"
Debug_main = Ja
Interrupt_vektor.5 = 1
Return


Alles kann parallel laufen.

Gruß

Rolf

mat-sche
22.09.2007, 20:11
Hallo und nen netten Abend for_ro,

liebbitte kann ich Deinen code bekommen?

Eisbaeeer
22.09.2007, 20:27
Hi for_ro

Danke, das war der entscheidende Hinweis.
Manchmal denkt man einfach zu kompliziert.

Wie habe ich das jetzt realisiert:

In meiner Timer Subroutine, die schon da ist (alle 25ms), habe ich eine Variable (Dim Count as byte) erhöht. Jetzt frage ich diese ab und verzweige. Die 750ms warten im Sub Convert_temp kann ich jetzt rausnehmen.



If Count = 100 Then Gosub Convert_temp
If Count = 200 Then Gosub Read_temp1





'-------------------------------------------------------------------------------
'Sub Convert_Temp
Sub Convert_temp
1wreset
1wwrite &HCC 'Skip Rom
1wwrite &H44 'Convert Temp
' 1wreset
End Sub

'-------------------------------------------------------------------------------
'Sub Read_temp1
Sub Read_temp1
1wreset
1wwrite &H55 'Match Rom
1wwrite Id1(1) , 8 'DS1820 ID senden
1wwrite &HBE 'Read Scratchpad
Ar1(1) = 1wread(9) 'Temp Wert auslesen
1wreset
Tmp = Ar1(1) And 1
If Tmp = 1 Then Decr Ar1(1)
T = Makeint(ar1(1) , Ar1(2))
T = T * 50
T = T - 25
T1 = Ar1(8) - Ar1(7)
T1 = T1 * 100
T1 = T1 / Ar1(8)
T = T + T1
T = T / 10
T6 = T / 10
T4 = Fusing(t6 , "#.#")
End Sub

Grüße Eisbaeeer