www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Impulslängen DCF 77


Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich wollte mal von denen, die sich schon mit DCF77 beschäftigt haben, 
wissen, wie ihr die Impulslängen des Signals messt.
So in Stichworten...

Gruß Chris

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls du einen AVR benutzt, d nehme ich den ICP (Input-Capture-Pin), der 
hat 'ne 'Rauschunterdrückung' und eignet sich für solche Aufgaben 
hervorragend.

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne ...ist n msp 430

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann ich leider nicht weiterhelfen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit nem Timerinterrupt, der alle 10ms nachschaut, ob sich der Pegel 
geändert hat und mitzählt:

8..12 = 100ms
18..22 = 200ms
90..110 = 1s
190..210 = 2s

D.h. eine Byte-Zählvariable erschlägt alle interessierenden Zeiten.

Einfacher gehts nicht.


Peter

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
undwie triggerst du den timer? mit nem externen Int.?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. wrote:
> undwie triggerst du den timer? mit nem externen Int.?

???

Der Timer läuft durch.
Den braucht man doch eh, für die interne Uhr bei Empfangsstörungen.


Peter

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ganz peil ichs nciht.... könntest du ein code - snipplet posten?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es im MSP430 keine Timer die regelmässig einen
Interrupt auslösen können?

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch natürlich!
Ich hatte mir die ganze Messung nur komplett anders vorgestellt...
Mein Versuch war: steigende Flanke -> timer starten, Fallende Flanke -> 
Timer stoppen -> Zeit auswerten

Eure MEthode hört sich nur wesentlich einfacher an....

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ICh habs nun mal so versucht.... aber irgendwie funzt das nciht :(

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0 (void)
{

  if(P2IN & 0x01)
  {
   timecount += 1;
  }
 
  //position(2,1);
  //int2string(timecount,buffer);
  //printtext(buffer);
  
  if(timecount >= 8 && timecount <= 12)
  {
   position(2,1);
   printtext("0");
   timecount = 0;
  }
  
  if(timecount >= 18 && timecount <= 22)
  {
   position(2,1);
   printtext("1");
   timecount = 0;
  }
 
 CCR0 = 327;
}


Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deiner Funktion wird timecount niemals den Wert
18 erreichen. Wenn timecount bis auf 8 hochgezählt
hat, detektierst du eine 0 und das wars dann auch schon.

Du sollst 1 Sekunde lang den Eingang alle 10 ms beobachten.
Wenn er in dieser 1 Sekunde 8 bis 12 mal 1 war, dann gilt
das als 0.

Du musst also die Interrupts mitzählen. Dein Interrupt tritt
alle 10 ms auf. Nach 100 Interrupts ist also 1 Sekunde vergangen.
Beim Start einer Sekunde setzt du den timecount auf 0.
Danach prüfst du bei jedem Interrupt den Zustand des
Port-Pins und zählst gegebenenfalls den timecount hoch.
Wenn der 100-ste Interrupt auftritt (also nach 1 Sekunde)
schaust du nach wie oft du eine 1 vorgefunden hast (du
wertest also den timecount aus).

Anstatt 100 würde ich vielleicht auf 90 gehen. An der
Anzahl in timecount ändert das nichts, aber du wirst
wahrscheinlich noch etwas Zeit brauchen um dich auf
die nächste 0-1 Flanke synchronisieren zu können.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Art Impulse auszumessen frisst unnötigerweise Rechenleistung, da 
alle 10ms ein INT ausgeführt wird. Dann lieber fallende und steigende 
Flanke auswerten Zeit messen und mit Toleranz bewerten. Damit kann ich 1 
und 0 festlegen. Alles was nicht 1 oder 0 ist muss ein Fehler sein, das 
heißt ich muss wieder von vorne anfangen die Bits zu zählen.

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Sonic: Das ist nicht so ganz richtig. Der Interrupt kommt zwar alle 
10ms, kann aber extrem kurz gehalten werden. Die Auswertung der 
gemessenen Zeiten geschieht in der Main. So wie Du es mit dem ICP 
machst, hatte ich früher auch gearbeitet, bis ich feststellte, daß bei 
Störungen des DCF-Signals durch Maschinen oder Lampen der ICP bis zu 100 
mal pro Sekunde wild getoggelt wurde. An "Messen" war da nicht mehr zu 
denken. Zudem verfälschten kleine Störimpulse immer wieder die Messung. 
Da reichte schon das Einschalten einer Leuchstoffröhre und schon war das 
ganze Zeitprotokoll im Eimer. Durch die 10ms-Timer Variante kann man all 
diese Probleme umgehen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Programmen dieser Art benötigt man sowieso eine
Zeitbasis. Sei es für die Ausgabe auf gemultiplexten
7-Segmentanzeigen (ok, dann sind 10 ms nicht gerade viel)
oder sei es um die Uhr auch dann am laufen zu halten, wenn
das DCF Signal ausfällt. Ob diese Zeitbasis den DCF
Eingang noch zusätzlich beobachtet, fällt dann nicht
mehr wirklich ins Gewicht.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@TravelRec.:
Um Fehler sauber erkennen zu können (Einschaltimpulse von 
Leuchtstofflampen sind welche) muss man den GANZEN Impuls messen, nicht 
in 10ms-Abständen. Wenn ich in Kauf nehmen will, dass ich einen Fehler 
nicht erkenne kann es halt passieren dass ein falsches Protokoll 
'rauskommt. Der Noise-Canceller vom ICP leistet bei mir sehr gute 
Dienste, habe so gut wie kein nicht vollständiges Protokoll.

>In Programmen dieser Art benötigt man sowieso eine Zeitbasis.

Stimmt. Die ist bei mir 1s (Timer1, RTC).
Ich will ja noch was Anderes machen als nur die Uhr laufen zu lassen, da 
kann's mit der Rechenleistung schon mal knapp werden, bzw. für 
Berechnungen etwas länger dauern.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>habe so gut wie kein nicht vollständiges Protokoll.

Ich auch nicht! Der NoiseCanceller des ICP überbrückt gerade mal 4 
CPU-Zyklen, für Störimpulse im oberen µs bis ms-Bereich absolut 
nonsense.

>Um Fehler sauber erkennen zu können (Einschaltimpulse von
>Leuchtstofflampen sind welche) muss man den GANZEN Impuls messen, nicht
>in 10ms-Abständen.

Ich messe den ganzen Impuls, im 10ms "Raster", nicht in 10ms 
"Abständen". Da die DCF-Signale 100 bzw. 200 ms lang sind, bekomme ich 
Zahlen von 8-12 für 100ms +-Toleranz und 18-22 für 200ms +-Toleranz. Ich 
will nicht Fehler erkennen, sondern DCF-Impulse. Die Fehlererkennung 
findet über die Prüfbits im DCF-Protokoll statt. Störimpulse an sich 
haben durch diesen programmtechnischen "Tiefpass" so gut wie keine 
Chance, es sei denn, der Empfang ist völlig hin und das Modul gibt nur 
noch wirres Zeug aus.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich messe den ganzen Impuls, im 10ms "Raster", nicht in 10ms "Abständen".

Ist genau das Gleiche! Du prüfst immer nur zu einem bestimmten 
Zeitpunkt, einen evt. Defekt des Moduls erkennst du so sehr schlecht. 
Kommt wohl immer drauf an wie man an die Sache 'rangeht. Ich prüfe nur 
auf Fehler (auch die Prüfbits), das vereinfacht die Programmierung.
Ist wie bei vielen Sachen: jeder hat seine bevorzugten Methoden.

Autor: Pit Herrmann (pit9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schaut Euch doch mal die zahlreichen Beispiele in der Codesammlung an! 
Da gibt's genug Tipps...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sonic wrote:

> Ich will ja noch was Anderes machen als nur die Uhr laufen zu lassen, da
> kann's mit der Rechenleistung schon mal knapp werden, bzw. für
> Berechnungen etwas länger dauern.

Also bei 4MHz Quarz und reichlich geschätzten 40 Zyklen für den 10ms 
Interrupt komme ich auf ne Wahnsinns-CPU-Belastung von 0,1% !

Kann mir keiner erzählen, daß er 0,1% merkt.


Peter

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
Ich weiß ja nicht ob du nur einzelne Programmfunktionen programmierst, 
bei mir laufen ab und zu auch mal mehrere Funktionen auf einem µC. Eine 
Uhr, se es DCF oder RTC odr beides zusammen sind reine 
Hintergrundfunktionen, die möglichst gar nicht ins Gewicht fallen 
sollten. Sobald ich meinen Programmablauf alle 10ms durch einen INT, sei 
er noch so kurz gehlten, unterbreche, sind andere zeitkritische 
Funktionen sehr schwer zu realisieren.
Aber wie gesagt: jeder wie er will, mir isses halt nach meiner Methode 
lieber.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sonic wrote:

> sollten. Sobald ich meinen Programmablauf alle 10ms durch einen INT, sei
> er noch so kurz gehlten, unterbreche, sind andere zeitkritische
> Funktionen sehr schwer zu realisieren.

Wenn ein Interrupt stört, dann isses vollkommen egal, wie oft er kommt.
Ein 1s Interrupt stört genau so, er stört nur seltener.


Wenn Interrupts stören, mußt Du entweder Dein Programm umstellen oder 
Interrupts zeitweise verbieten.
Und nur, wenn dieses zeitweise Verbieten länger als 10ms dauert, geht 
der 10ms Interrupt in die Hose.


Ich versuche allerdings das Hauptprogramm immer so zu schreiben, daß 
Interrupts nicht stören, egal welche.


Peter

P.S.:
10ms ist doch auch eine gute Zeit für die Tastenentprellung.

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Ich messe den ganzen Impuls, im 10ms "Raster", nicht in 10ms "Abständen".

>Ist genau das Gleiche! Du prüfst immer nur zu einem bestimmten
>Zeitpunkt, einen evt. Defekt des Moduls erkennst du so sehr schlecht.

Naja - ist es nicht. Der Timer guckt zwar nur alle 10ms, aber wenn die 
Impulse außerhalb der vorgegebenen Fenster - von 20ms nach oben und 
unten - liegen, wird dies auch als Fehler gesehen. Kommen ständig 
Fehlimpulse, ist der Empfang gestört oder das Modul defekt. Eindeutiger 
geht´s nicht.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf diese Weise ist bei Störungen schnell mal Null und Eins verwechselt. 
Merkst du dann erst über die Prüfbits.

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso, alles unter 8 ist Murks, 8,9,10,11,12 ist Null / größer 12 und 
kleiner 18 ist Murks, 18,19,20,21,22 ist Eins, alles über 22 ist Murks, 
rund um 100 ist die Austastsekunde 59 - willst Du´s noch genauer? Mein 
Controller verwechselt da nix und weiß eigentlich sofort, was Null und 
Eins ist. Wie gesagt: unter normalen Bedingungen empfange ich keine 
Fehlprotokolle, eine Kontroll-LED zeigt mir den aktuellen Status an. Die 
einzig nennenswerten Probleme treten bei Gewittern in unmittelbarer Nähe 
auf. Dann tritt die interne Quarzuhr in Betrieb.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke wir sollten es dabei bewenden lassen, dass beide Möglichkeiten 
gut funktionieren. Hier weiterzudiskutieren macht wenig Sinn. wie ich 
oben schon erwähnte, jeder ist halt von seiner Variante überzeugt. 
Möglicherweise ist von Fall zu Fall die Eine oder Andere Version 
angebrachter.

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BACK TO TOPIC!!! HELFT MIR LIEBER ;)

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wurden doch mehrere Lösungen gepostet, was ist nicht klar?

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
theoretisch klar ist bis jetzt alles....

hier mal eine neue Version:
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0 (void)
{
  _DINT();
  
  intcount += 1;
  
  if(P2IN & 0x01)
  {
   timecount += 1;
  }
 
  if(intcount > 98)
  {
    if(timecount >= 8 && timecount <= 12)
    {
     position(2,1);
     printtext("0");
     timecount = 0;
    }
  
    if(timecount >= 18 && timecount <= 22)
    {
     position(2,1);
     printtext("1");
     timecount = 0;
    }
    intcount = 0;
  }
 
 CCR0 = 327;
 _EINT();
}


Müsste soweit klappen.... teste grade

Autor: Christian S. (aliendrummer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klappt freu

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. wrote:
> klappt *freu*

Na bitte.


Ich habe auch die Erfahrung gemacht, daß die Timerpollmethode 
störunempfindlicher ist, als die mit Capture.
Es müssen wesentlich mehr Störungen kommen, damit das Signal nicht mehr 
dekodierbar ist.


Peter

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
100% ACK - aber gut nun ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.