Hallo zusammen,
ich habe schon sämtliche relevante Beiträge gelesen, aber es war nichts
dabei was mir weiterhelfen hätte können...
Nun zu meinem Problem:
Ich habe das reichelt DCF Modul an den INT1 Eingang gehängt und den
Interrupt so eingestellt, dass er bei steigender Flanke auslöst.
Ich habe in die ISR einen einfachen Pintoggle reingeschrieben um zu
überprüfen ob die Interrupts so kommen wie ich mir das vorstelle..
Wenn ich das Programm nun laufen lasse, sehe ich auf dem Oszi, dass der
Interupt manchmal nicht , manchmal doppelt und meistens normal ausgelöst
wird.
Die blaue Kurve ist das DCF Signal, gelb ist der Pintoggle. (Bild im
Anhang)
Das DCF Modul hängt ohne Pullup und ohne serienwiderstand am INT1. (mit
Pullup getesten, auch keine Besserung)
Hat jemand eine Idee, an was das liegt oder noch besser einen Vorschlag
wie das Problem beseitigt werden kann.
mfg, Alex
Hier der Code von der ISR:
ISR(INT1_vect)
{
if(ms_counter == 0)
{
PORTA |= (1 << PA3); //switch off backlight
ms_counter++;
}
else if(ms_counter==1)
{
PORTA &= ~(1 << PA3); //switch on backlight
ms_counter = 0;
}
}
und hier der Teil aus der main der den Interrupt initialisiert:
/*setup external interrupt 1 for dcf sync*/
MCUCR |= (1<<ISC10) | (1<<ISC11); //rising edge
GICR |= (1<<INT1);
Ich habe ähnlichen Ärger schon mit dem Pollin-DCF gehabt. Da kam während
der negativen Flanke nochmal ganz kurz ein Ausreisser nach oben, der mir
einen erneuten Interrupt ausgelöst hat.
War schwer zu finden, da wirklich sehr kurz.
Du solltest das Signal etwas genauer untersuchen - ordentlich in die
Länge dehnen und die fallende Flanke ansehen.
Also, ich finde die 1. Version von Dude besser. Keine Variable und das
Ganze geht viel schneller.
1
ISR(INT1_vect)
2
{
3
PORTA^=(1<<PA3);//toggle backlight
4
}
Falls PORTA noch irgendwo anders benutzt wird könnte Dir das natürlich
noch reinfunken. Also Code am besten auf den INT und eine Endlosschleife
reduzieren.
das mit dem gleichzeitigen Signalwechsel kann ich mir auch nicht
erklären...
manchmal springt er auch bei fallender flanke in die isr, manchmal
"übersieht" er ne steigende...
der Test mit INT0 und dem abgespecktem Code zeigt auch wieder das selbe
Verhalten.
Probier es mal mit einem Pulldown 10k-100k an der INT-Leitung.
Alertantiv einen Tiefpass-Kondensator. Ich vermute auch Spikes. Wie hoch
ist die Abtastrate Deines Oszis ?? Vielleicht kann es diese Spikes nicht
mitschneiden. Außerdem kannst Du auch noch den Takt vom Atmega mal ganz
runter setzen auf 1MHz, dann ist der Interrupt vielleicht zu träge für
die Spikes und es passiert nicht mehr.
Das mit dem Takt ist nur als Nachweis gemeint. Ich wollte das nicht als
Lösung für das Problem vorschlagen. Wenn es Störungen gibt, dann
brauchst Du ein Filter.
Tja, der abgespeckte Code sieht eigentlich gut aus. Sehe jedenfalls
keine Fehlermöglichkeiten.
Das das Signal teilweise zu identischen Zeiten wechselt ist merkwürdig.
Ist das selbstgelötet? Vielleicht hast Du da aus Versehen einen Schluss
gemacht, der ein wenig halblebig ist und deswegen, wenn Du am Tisch oder
sonstwo wackelst auch mal einen INT auslöst wenn keiner sein sollte.
@dude: rechteckgenerator ist auch erst morgen verfügbar
@analog: 10k pulldown drück das signal soweit, dass INT0 gar nicht mehr
reagiert; samplingrate ist nicht berauschend.. is n 500 euro DSO.. 2,5
KS / s ;AVR runtertakten is keine gute idee, weil der doch noch einiges
zu verarbeiten bekommt..
@besserwisser: ist auf nem steckbrett gesteckt, rüttelt aber nix und
sonst geht auch alles immer reibungslos damit (ints kommen auch wenn ich
vom anderen zimmer aus rüberschau ;) )
@analog: werd morgen zum test mal den generator dranhängen
@besserwisser: 100% kein schluss
@dude: mit fallenden Flanken wieder dasselbe Verhalten; muss ich beim
rechteckerzeugen auf irgendwas spezielles achten (habe das noch nie
gemacht)
> muss ich beim rechteckerzeugen auf irgendwas spezielles achten
Nein, eigentlich nicht. Einen Timer in CTC betreiben und den zugehörigen
OCR-Pin toggeln und mit INT1 verbinden.
Kannst ja auch 1 Hz ca wählen, ist unkritisch.
>AVR runtertakten is keine gute idee,
Gibt aber ein Äquivalent dazu: Den DCF77-Portpin einfach fortlaufend
alle z. B. 10 ms (generiert von Software-Timer) sampeln. Erschlägt Dein
Problem aus prinzipiellem Grund, weil das Sampling wie ein Tiefpass
wirkt. Funktioniert bestens. CPU-Last ist vernachlässigbar (0.01%).
Musst Dich nur von dem Interrupt verabschieden.
derheld2k1 wrote:
> Hallo zusammen,>> Nun zu meinem Problem:> Ich habe das reichelt DCF Modul an den INT1 Eingang gehängt und den> Interrupt so eingestellt, dass er bei steigender Flanke auslöst.
Es ist üblich, dass DCF-Empfang gestört wird, etwa durch
-- Monitor, PC, ...
-- Wetterlage
-- Schaltnetzteil
-- µC in unmittelbarer Nähe
-- Atombomben
-- weiss der Teufel
DCF an einen INT-Port zu hängen ist keine so tolle Idee, weil
1) verbraucht das nen wertvollen INT-Port
2) das Signal wie gesagt nicht sauber ist
Stattdessen empfiehlt sich ein Vorgehen wie bei Tasterentprellung. ZB
indem man einfach alle 10ms auf den Port schaut -- das dann aber gerne
in einer ISR.
Danach kann man Spratzer ausbügeln, also Bitfolgen (hier gesamplet alle
10ms) wie 0001000 ersetzen durch 000000.
Bei extrem mieser Empfangslage muss man zusätzlich über mehrere Minuten
sammeln und Bits reparieren. Ein Voting wie "2 aus 3" ist aber nicht so
einfach zu implementieren, weil sich die Nutzdaten ja ändern. Da
brauch's also etwas mehr Gehirnschmalz.
@dude: bekomme das mit dem timer grad nicht auch die schnelle so
gebacken, werds morgen mit generator machen
@johann: der empfang war anfangs extrem gestört, habe dass aber dank
laptop statt desktop rechner und verlagern des empfängers mittels 2m
kabel ans fenster in griff bekommen, das Signal sieht ja sehr sauber
aufm Oszi aus.
Aber langsam bin ich auch am zweifeln ob das mit dem INT so ne gute idee
ist.
Werd mich mal kurz hinsetzen und des Signal samplen, muss ich ja eh
machen wenn ich die dauer von den "highs" messe um die bits zu
bestimmen, aber das wollte ich eben dann angestossen durch den interrupt
machen "lassen". Und gestörte Daten werf ich einfach weg, indem ich sie
mit der aktuellen zeit vergleiche und er solls nochmal versuchen..
so, im moment komm ich nicht mehr weiter.. mein hirn is einfach voll
(häng da schon den ganzen tag dran)
hier noch die letzten zeilen code die ich zum samplen geschrieben hab,
funktioniert aber noch nicht. der timmerinterrupt kommt jede ms, daher
läuft das array schnell voll und nicht erst nach ner minute. Wer lust
und laune hat des schnell auszubessern ist herzlich eingeladen.
Ansonsten vielen Dank für die schnelle und ausführliche Hilfe, ich werde
morgen weiter berichten.
mfg
Nachtrag:
angenommen es sind doch spikes im DCF signal und ich wills doch mitn
INT1 machen, würde es dann helfen mit RC ladekurve n schmittrigger
anzusteuern?
eigentlich schon oder überseh ich da in meiner momentanen Verwirrtheit
etwas?
>es dann helfen mit RC ladekurve n schmittrigger anzusteuern
Ich würde sagen, es lohnt den Versuch. Das mit dem RC-Tiefpass hat ja
auch am Anfang jemand vorgeschlagen. Grenzfrequenz kann ja sehr niedrig
sein. Hauptsache die 100ms kommen noch durch.
>würde es dann helfen mit RC ladekurve n schmittrigger anzusteuern?
Möglich, aber wozu extra Hardware-Aufwand treiben, wenn sich das Problem
rein softwaremäßig in nullkommanix erschlagen lässt? Nochmal: Dem
Samplen haftet genau die gewünschte Tiefpass-Charakteristik an. Was
willst Du noch?
>der timmerinterrupt kommt jede ms, daher läuft das array schnell voll
Tipp: 10 ms. Ein Array ist überflüssig. Du brauchst doch nur den
aktuell gesampelten Wert und den Vorgängerwert, um jede Flanke
detektieren zu können. Eine Speicherqueue der Länge 1, d. h. eine
simple Variable zum Zwischenspeichern des aktuellen Werts bis zum
nächsten "Tick", reicht also. Die DCF77-Decodier-Zustandsmaschine rufst
Du natürlich auch alle 10 ms auf. Nicht erst 200 Samples in einem Array
sammeln und die Maschine danach 200-fache Arbeit erledigen lassen - das
ist Nonsens. Immer gleich jedes Sample sofort verarbeiten - das ist bei
schnarchlahmen 10 ms kein Problem und bzgl. des Rechenaufwands
dasselbe, aber Du brauchst kein Array.
Hallo nochmal,
habe das Problem jetzt gelöst indem ich wie AVRFan geraten hat, das
Signal zu samplen ohne Interrupt eingang. Funktioniert bestens, auch den
Signalbeginn erkennt die software.
Vielen Dank nochmal für die schnelle Hilfestellungen.
mfg