Hallo Leute,
kann mir bitte jemand helfen.
Ich habe ein DCF Empfänger (von Conrad), wie auf dem Bild angeschlossen.
So sieht mein Code aus, das ist jetzt nur zum testen.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
ISR(INT0_vect)//Interrupt INT0
5
{
6
PORTB^=(1<<PB7);
7
}
8
9
intmain()
10
{
11
GIMSK&=~(1<<INT0);// Enable INT0
12
MCUCR|=(1<<ISC00);// Trigger INT0 on rising edge
13
MCUCR|=(1<<ISC01);
14
15
sei();
16
17
DDRD|=(1<<PD2);
18
19
DDRB|=(1<<PB7);
20
21
while(1){
22
23
}
24
}
Es sollte ja lt. Code in Sekundentakt blinken. Es tut das auch, aber
nicht immer, es kommt immer wieder vor, dass dazwischen auch noch blinkt
und ich versteht nicht wieso und mit diesem "dazwischen blinken" kann
man das Signal nicht wirklich auswerten.
Empfang an sich funktioniert hier gut. Ich DCF77 Empfänger an Arduino
angeschlossen, das hat funktioniert.
Alex Wka schrieb:> Stimmt! Danke, ich hab's geändert, leider blinkt immer noch mit Fehlern
Schau Dir einfach die Zusammensetzung des DCF-77-Signals (z.B. auf der
zugehörigen Wiki-Seite) an. Wir wissen nicht, was Du als "Fehler"
bezeichnest. Vermutlich siehst Du nichts weiter als den korrekten Code,
was auch dadurch belegt ist, dass Du mit entsprechender Software die
korrekte Zeit erhältst! Oder was meinst Du mit "es hat funktioniert" in
Deinem ersten Posting?
Bei funktionierendem Empfang sollte die LED jede Sekunde
den Zustand ändern.
- Zum Minutenwechsel dauerts aber 2 Sekunden.
Empfangsstörungen?
- DCF-Modul weit genug vom µC entfernt?
- Zuleitung zum DCF-Modul mit C-s abgeblockt?
Oldie schrieb:> Bei funktionierendem Empfang sollte die LED jede Sekunde> den Zustand ändern.
genau, so sollte es ja sein -eine Sekunde leuchten eine Sekunde nicht
leuchten, aber es kommt immer wieder vor, dass z.B länger als eine
Sekunde blinkt oder kurzer. Diesen Takt (eine Sekunde an, eine Sekunde
aus) kann nicht eine Minute lange gehalten werden.
Fred S. schrieb:> Wir wissen nicht, was Du als "Fehler"> bezeichnest.
Mit Fehler bezeichne ich, dass LED nicht eine Sekunde an und eine
Sekunde aus ist. Es kommt immer wieder vor, dass die LED sich immer
wieder dazwischen ausschaltet oder einschaltet.
Besser ist es, du gibst das DCF Signal direkt aus
und vergleichst das Signalbild mit der DCF-Beschreibung.
Mit wenig Änderungen:
INT0-Interrupt auf beide Flanken, PD2-Pegel im IRQ an PB7
transferieren.
Dann auch noch testen, ob der DCF-, oder der !DCF-Pin
vom Modul besser passen.
Alex Wka schrieb:> Es sollte ja lt. Code in Sekundentakt blinken. Es tut das auch, aber> nicht immer, es kommt immer wieder vor, dass dazwischen auch noch blinkt> und ich versteht nicht wieso und mit diesem "dazwischen blinken" kann> man das Signal nicht wirklich auswerten.
Bevor Du lange am Code rumbastelst, solltest Du als erstes das Signal
direkt am Ausgang mit einer LED anzeigen. Mit etwas Übung kannst Du
am Takt sogar die Uhrzeit ablesen.
Gruss
Harald
> genau, so sollte es ja sein -eine Sekunde leuchten eine Sekunde nicht> leuchten, aber es kommt immer wieder vor, dass z.B länger als eine> Sekunde blinkt oder kurzer. Diesen Takt (eine Sekunde an, eine Sekunde> aus) kann nicht eine Minute lange gehalten werden.
Schau dir nochmal eine Beschreibung zum DCF-Signal an. Eine Sekunde
an/eine Sekunde aus ist Quatsch und könnte gar keine Information
übertragen.
Was ist daran unklar?
Der Pegelwechsel am PD2 = INT0 löst eine Interruptroutine aus.
Manche nennen dies IRQ, bei dir heißt es IRS.
In IRS liest du den Pegel am PD2 ein, und gibst ihn
an PB7 aus.
Martin S. schrieb:> Schau dir nochmal eine Beschreibung zum DCF-Signal an.
DCF-Signal kenne ich schon auswendig. Ich wollte ja testet, ob mein
Signal ok ist, das heißt, wenn die Schaltung ok ist, dann sollte ja LED
eine Sekunde an und eine Sekunde aus sein. Das ist aber nicht der Fall.
Es kommt immer wieder vor, dass LED sich dazwischen (zwischen Sekunden)
immer wieder ein-/ausschaltet. Das heißt für mich, dass das Signal nicht
richtig interpretiert wird.
Ich habe mir dann gedacht evtl. sind das irgendwelche Geräte die das
Signal stören und habe es testweise an Arduino angeschlossen, damit hat
es funktioniert - Arduino konnte das Signal auswerten und mir die
richtige Zeit ausgeben, also es liegt an meiner Schaltung. So, meine
Frage ist was kann das sein bzw. wie kann man das beheben.
Ich habe schon hier im Forum viel von DCF Modul gelesen und ich habe das
Geführ bekommen, dass es bei so ziemlich allen relativ leicht ging.
grundsätzlich sollte ein Signal wie das DCF Signal keinen Interrupt
auslösen, wenn man soetwas programmiert hat man den falschen Ansatz
gewählt.
Das Signal ist jede Sekunde bis auf die 59igste 200ms oder 100ms low,
das muss man auswerten...
Gruß,
DS
Alex Wka schrieb:> viel von DCF Modul gelesen> dass es bei so ziemlich allen relativ leicht ging
Wenn es leicht ginge, würde nicht viel darüber geschrieben. Allerdings
werden die gleichen Fehler immer wieder gemacht.
Was passiert, wenn du das Modul abklemmst? Wenn die LED dann auch
sporadisch blinkt, hast du ein Problem mit Störungen, die in deinen Tiny
hinein spucken.
Als nächstes sieh dir die Ausgangsimpulse des Moduls mit einem Scope an,
ob sie sauber sind.
Und dann platziere das Modul einmal testweise 1m von dem Tiny entfernt.
>>Das heißt für mich, dass das Signal nicht
richtig interpretiert wird.
Falsch, es wir richtig interpretiert, es sind aber STörungen darauf. Wie
geagt, das im Interrupt zu machen ist der falsche Andatz.
Ds
Dennis S. schrieb:> Falsch, es wir richtig interpretiert, es sind aber STörungen darauf. Wie> geagt, das im Interrupt zu machen ist der falsche Andatz.
wie macht man das dann richtig? Das ist mein erster Projekt mit
Mikrocontroller, ich bin für die Vorschläge offen.
das Signal abfragen, z.B. alle 10ms schauen welchen Zustand das Teil hat
und diese Info sammeln, wenn du beispielsweise zwischen 80 und 120ms low
hattest ist es eine DCF NULL und wenn du 180 und 220ms eine Null hattest
ist es eine DCF EINS, also einen 10ms Timer aufsetzen und in einer
Schleife das Signal entsprechend abfargen, wenn nicht alle 800 bis 900ms
etwas kommt in spät 2s etwas erwarten, wenn das Signal länger als die
Timings beschrieben low ist, dann ist es ein Fehler, wenn länger als 2s
nichts kommt auch, das ganze muss während es rein kommt bewertet und
einsortiert werden (59 Bit) und in der 60igsten Sekunden ausgewertet und
an das Display übergeben werden oder in entspechende interne Variablen
zur Weiterverarbeitung...
DS
Dennis S. schrieb:> das Signal abfragen, z.B. alle 10ms schauen welchen Zustand das Teil hat> und diese Info sammeln, wenn du beispielsweise zwischen 80 und 120ms low> hattest ist es eine DCF NULL und wenn du
stimmt ich habe schon sowas auch gesehen, aber ich habe mehr Projekte
gesehen, wo das mit Interrupt gemacht wird, deswegen dachte ich ich, das
es mit Interrupt besser ist. Aber mit Pegel Abfragen kann ich solche
Probleme, wie ich jetzt habe, umgehen. DANKE für den Tipp.
..es ist niemals richtig so ein Signal mit einem Interrupt abzufragen,
das ist zwar das was einem das Schulwissen und die Lektüre nahe zu legen
scheint, aber der Schein trügt, dafür sind Interrupts nicht gemacht. Mit
einem Interrupt kannst du ein sicheres Signal auf ns Länge vermessen,
hier geht es um gurkige 200ms.
Es ist ein externes, ggf. verschmutztes und evtl. unbekanntes oder mit
beliebiger Frequenz und Zustand entsprechendes Signal, je nach
Wetterlage, Position, und Umfeld. Mit anderen Worten es ist ggf.
beliebig und das muss abgefangen werden.
Wenn z.B ein Funkseder in der nähe ist und das Modul, weil es defekt
ist, einen 1Mhz Rechteck auf deinen Interrupt Pin gibt, dann ist dein
Prozessor sehr gut damit beschäftigt diese Interrupts zu behandeln,
dieser Fall sollte betrachtet werden, alles andere ist
gurkenprogramiererei und nicht wasserdicht...
Du hast jetzt zwischendurch kleine peaks auf deinem Signal welche deine
LED toggeln lassen...und du wertest diese aus, warum auch immer... :-)
DS
Diese Alte-Tanten-Beschwörung: "DCF nur nicht über Flanken-
Interrupt einlesen", mag doch kein "Erwachsener" mehr hören.
Macht man's ordentlich, funktioniert es auch in 600 km
Entfernung sicher. Taugt die 10-ms-Poll-Routine nichts,
bekommt man auch bei Mainflingen keine genau gehende Uhr.
Bei beiden Verfahren muss ich mit Hilfe eines Grundtakts
von z.B. 10 ms und einer Zählvariablen sicherstellen, dass
der DCF-Takt nur im Abstand von etwa 1000 +/- 30..50 ms
(oder 2000 +/- 30..50 ms) akzeptiert wird.
Wer das nicht macht, bastelt eben eine schlechte DCF-Uhr.
Die Interrupt-Variante hat den Vorteil, dass ich meine Uhr
bei bekannter Laufzeit (600 km entspricht z.B. 2 ms) und
bekannter Signalverschleifung meines DCF-Empfängers auf
absolut besser 1 ms genau einregeln lassen kann.
Beim 10-ms-Polling habe ich immer +/-10 ms Unsicherheit.
Zugegeben - diese Genauigkeit braucht nicht jeder.
Aber wer den Flankeninterrupt von DCF grundsätzlich ablehnt,
zeigt nur, dass er wohl auch mit Polling keinen ordentliche
Empfangsroutine gebacken kriegt...
Grantler schrieb:> Aber wer den Flankeninterrupt von DCF grundsätzlich ablehnt,> zeigt nur, dass er wohl auch mit Polling keinen ordentliche> Empfangsroutine gebacken kriegt...
So? Aus anderen Gründen brauche ich alle 20msec einen Interrupt. Darin
wird auch ein DCF-Signal abgetastet und ausgewertet. Läuft schon seit
Jahren ohne Probleme. Allerdings ist der Zeitsender auch nur 30km
entfernt.
>>zeigt nur, dass er wohl auch mit Polling keinen ordentliche
Empfangsroutine gebacken kriegt...
...seltsame Schlussfolgerungen hier immer wieder. Aber so sind die
Menschen wohl...
DS
Ich hatte sowas mal mit einem anderen Mikrocontroller gemacht und kam
MIT zusätzlichem Pull-Up Widerstand besser klar. Der Interne Pull-Up war
für mein DCF Modul zu hochohmig.
Ich würde für den Anfang dringend empfehlen, eine LED direkt an den
Ausgang des DCF Moduls anzuschließen. Natürlich mit passendem
Vorwiderstand. Achtung: Nicht jedes Modul kann 20mA treiben - mein
konnte nur 3mA. Aber auch das reicht für eine kleine Kontroll-Anzeige
aus.
Platziere den Empfänger möglichst weit weg von allen anderen
Elektrischen Geräten. Wenigstens 1 Meter Abstand ist angemessen.
Versorge das DCF Modul nicht direkt mit der gleichen Spannung, wie den
Rest der Schaltung. Ein separater Spannungsregler oder ein Tiefpass aus
33 Ohm und 100µF helfen sehr, den Empfang zu verbessern. Eine Spule wäre
besser, aber sowas habe ich nicht in meiner Bastelkiste.
Erwarte nicht, einen kontinierlichen stabilen Empfang zu erhalten. Wenn
Du in einer Stunde 30 richtige und 30 fehlerhafte "runden" empfängst,
kannst Du zufrieden sein. Oder anders gesagt: Mach die Software so, dass
sie sehr fehlertolerant ist.
Ich hatte das mal so gelöst, das meine Uhr primär vom Quarz getaktet
wird. Parallel dazu läuft der DCF Empfang als zweiter Thread. Und der
mach das:
Wenn zwei aufeinander folgende Minuten die gleiche Zeit mit korrekter
Prüfsumme empfangen wurde (natürlich mit +1 Minute) wird sie in die
Variablen der Uhr übertragen.
Hier im Forum wurde schonmal ein ausgefuchsterer Algorithmus
vorgestellt, der noch besser mit Fehlern umgehen kann. Da waren nichtmal
zwei aufeinanderfolgende gute Runden nötig.