Forum: Projekte & Code DCF-Fehlerkorrektur im Streßtest


von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Hi.

DCF-Empfänger-Software gibt es viele, ich hab hier aber noch nix 
gefunden, was eine Fehlerkorrektur bei mieser Empfangslage macht.

Momentan bin ich in der heissen Phase der Implementierung und kann noch 
gut Ideen einbauen.
Wenn jemand Interesse an so einer Software (AVR) hat würde den Code hier 
reinstellen, nachdem alles spruchreif und besser getestet ist.

Das Bild zeigt die Software in Aktion:

Links das empfangene Signal und rechts daneben das Fehlerkorrigierte 
Signal.

Schwarz:  Bit 0
Hellgelb: Bit 1
Grün: Bit unbekannt
Blau: Minuten-Marke
Rot: Ein Kuckucks-Ei (0 statt 1 oder 1 statt 0) wurde erkannt und 
korrigiert

Paritätsprüfung mache ich noch keine und auch kein Plausibilitätstest, 
der mehrere Bits übergreift.

Mein Problem momentan ist, daß ich keine miesen DCF-Daten habe. Entweder 
die Daten sind gut oder so mies, daß kaum was damit anzufangen ist. Im 
Bild habe ich die Antenne senkrecht gestellt für ne Zeit.

Wenn jemand das alles testen will: Code kommt im nächsten Post.

Johann

von Peter D. (peda)


Lesenswert?

Johann wrote:
> Entweder
> die Daten sind gut oder so mies, daß kaum was damit anzufangen ist.

Das ist auch mein Eindruck.
Daher habe ich keinen Aufwand in die Fehlerkorrektur gesteckt, der 
Gewinn erscheint mir zu gering.
Um wirklich einen nennenswerten Effekt zu erzielen, müßte man wohl schon 
das Analogsignal auswerten.

In der Regel treten Empfangsstörungen nur zeitweise auf. Daher reicht 
es, wenn man mit einem fehlerfreien Datensatz die interne Uhr 
synchronisiert.


Peter

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

Hier trotzdem mal der Code (noch Binärversion).

von Johann (Gast)


Angehängte Dateien:

Lesenswert?

> Daher reicht es, wenn man mit einem fehlerfreien
> Datensatz die interne Uhr synchronisiert.

Wie bekomm ich einen fehlerfreien Datensatz?

Ich werde mal nen höflichen Brief an die PTB schreiben, damit die 
fehlerfreien Datensätze nicht an der österreichischen Grenze halt machen 
;-)

Johann

von Peter D. (peda)


Lesenswert?

Johann wrote:
> Wie bekomm ich einen fehlerfreien Datensatz?

Du prüfst einfach, ob alle Bits einer Minute störfrei sind, d.h. 100ms 
oder 200ms lang und 1000ms oder 2000ms Periode.
Da der Empfänger etwas verschleift, nimmst Du noch ein Toleranzfenster, 
z.B. +/-20ms.
Und sobald ein Impuls ausreißt oder != 59 Impulse, wird das ganze Paket 
verworfen.
Zusätzlich kann man noch die Parität prüfen.

Damit erziele ich einwandfreie Ergebnisse.


Peter

von Andreas K. (a-k)


Lesenswert?

Ich neige dazu, zusätzlich zu ebendiesem und der Parity nach der 
Dekodierung 2 aufeinander folgende Minuten miteinander zu vergleichen, 
also Tag1=Tag2,Stunde1=Stunde2 usw. Dann fliegt zwar der Einfachheit 
halber jedesmal die volle Stunde raus, aber damit kann ich besser leben 
als mit einer falschen Zeit.

von Benedikt K. (benedikt)


Lesenswert?

Andreas Kaiser wrote:
> Ich neige dazu, zusätzlich zu ebendiesem und der Parity nach der
> Dekodierung 2 aufeinander folgende Minuten miteinander zu vergleichen,

Genauso mache ich das auch. Ich verwende dazu die Software von Peter 
Dannegger mit all den Bitlängen Prüfungen und hatte im letzen Jahr nur 
1x den Fall, dass ich etwas falsches emfpangen habe (OK, ich muss dazu 
sagen, ich sitze natürlich nicht den ganzen Tag vor der Uhr und 
betrachte die OK/Fehler LED, und dass ich nur etwa 60km vom Sender 
wegwohne). An diesem einen Tag zeigte interessanterweise keine einzigste 
Funkuhr im Haus das Antennensymbol an.

Es gibt übrigends nicht schlimmeres als eine Funkuhr die falsch anzeigt. 
Dummerweise steht bei mir so ein Billigmodell rum. Die zeigt dann statt 
z.B. 12 Uhr auch mal 10 Uhr an. Anscheinend prüft diese nur Parity, und 
wenn 2bits falsch sind wird dann eben falsch angezeigt.

von Johann (Gast)


Lesenswert?

Peter schrieb:
> Johann wrote:
>> Wie bekomm ich einen fehlerfreien Datensatz?

> Du prüfst einfach, ob alle Bits einer Minute störfrei sind, d.h. 100ms
> oder 200ms lang und 1000ms oder 2000ms Periode.

Sind sie nicht.

So komm ich doch nicht an einen fehlerfreien Datensatz.
So kann ich nur testen, ob ein Datensatz fehlerfrei ist.

> Da der Empfänger etwas verschleift, nimmst Du noch ein Toleranzfenster,
> z.B. +/-20ms.

Selbstredend.

> Und sobald ein Impuls ausreißt oder != 59 Impulse,
> wird das ganze Paket verworfen.

Also immer. So ein Ansatz ist zum scheitern verurteilt.

Wenn Du praktisch keine Störungen aufm Signal hast ist das Thema für 
Dich natürlich komplett ininteressant.

> Zusätzlich kann man noch die Parität prüfen.

Soweit komm ich garnicht. Es geht an diesem Punkt noch nicht darum,
etwas zu prüfen.
Es geht darum, an was ranzukommen, um es prüfen zu können.

> Damit erziele ich einwandfreie Ergebnisse.
> Peter

Soweit die Praxis in Deutschland und die Theorie in Österreich. Wenn ich 
n gutes Signal hätte, würd ich mir die Gedanken nicht machen, glaub mir.

Zusätzlich bügel ich kuze Spikes aus, d.h. wenn sowas wie 00100 oder 
11011 im 10ms-Raster auftaucht, wird das ausgebügelt.

Hilft auch nix.


Ich hab ich mal angefangen, ein Konzept zu machen.

Als Diskussionsgrundlage sind da auch Daten und eine 
Wahrscheinlichkeitsbetrachtung zur Empfangsdauer.

http://www.gjlay.de/pub/dcf77/konzept.html

Johann

von Peter D. (peda)


Lesenswert?

Johann wrote:
> Soweit die Praxis in Deutschland und die Theorie in Österreich. Wenn ich
> n gutes Signal hätte, würd ich mir die Gedanken nicht machen, glaub mir.


Zuerst hattest Du aber gesagt, daß Dein Signal gut ist:

Johann wrote:
> Mein Problem momentan ist, daß ich keine miesen DCF-Daten habe.



Peter

von Johann (Gast)


Lesenswert?

Peter schrieb:

> Johann wrote:
>> Soweit die Praxis in Deutschland und die Theorie in Österreich. Wenn ich
>> n gutes Signal hätte, würd ich mir die Gedanken nicht machen, glaub mir.

> Zuerst hattest Du aber gesagt, daß Dein Signal gut ist:

> Johann wrote:
>> Mein Problem momentan ist, daß ich keine miesen DCF-Daten habe.

> Peter

Sorry für das Missverständnis.
Will meinen: Ich hab kaum mieses Originaldaten für den Test.

Hintergrund:

Ich hab schon mehrere DCF-Uhren gebaut, funktionieren alle prima. Stehen 
200km bzw. ca. 350km von Mainflingen (Saar + Nagold).

Eine steht jedoch bei Wien und schafft den Abgleich nicht, auch nicht 
mit Ausbügeln von Spikes etc. Das Problem ist dort wohl bekannt, ein 
Kumpel 2-3km weiter hat ähnlichen Huddel mit einer gekauften Funkuhr.

Ich will also ein Update des Programms machen für den ATmega8. Den alten 
DCF-Algorithmus hab ich komplett in die Tonne gekloppt, weil er einfach 
(trotz Toleranzen) viel zu strikt war.

Das dcf-2100h.png von enthält Originaldaten, bzw einen brauchbar 
aussehenden Ausschnitt daraus -- Rest ist kompletter Müll. Aber eben zu 
kurz, um mein neues Verfahren zu testen.

Die Uhr steht 1000km weit weg, daher hab ich schlechte Daten selber 
geschnitzt durch Verdrehen der Antenne.

Alternativ wäre das Thema Antennenbau. Aber Analog-Technik ist mir zu 
schwer, und ohne Oszi wird das wohl eh nix...

Johann

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hab mich ein bisschen angelesen zum Antennenbau. Soweit ich weiß, ist in 
dem Modul ein Temic U4224B drinne, im Datenblatt steht was zum 
Antennenabgleich:

http://www.datasheetcatalog.net/datasheets_pdf/U/4/2/2/U4224B.shtml

Das ist mir etwas zu hoch, davon abgesehen verfüge ich nicht über die 
Ausrüstung von mehreren tausend Euronen wie Oszi und F-Generator...

Johann

von sum (Gast)


Lesenswert?

Hi,

hast du mal im Forum gesucht? ICh hatte da mal was geschrieben, was mir 
einen theoretisch Idealen Empfänger realisiert:
Du musst das Empfangssignal mit der zeitinvertierten Impulsantwort 
deines Sendeformfilters falten und zum Abtastzeitpunkt abtasten. Das 
machst du natürlich mit 0 und mit 1 und kommst zu zwei Ergebnissen, die 
dir eigentlich aufschluss über den Wert des gesendeten Bits geben. Nennt 
sich Signalangepasster Filter (SAF). Implementiert hier:
Beitrag "DCF77 Uhr, zum X.ten Mal, jetzt mit SAF"

Nachzulesen. z.B. im Nachrichtenübertragungsskript von Prof. Noll, 
Tu-Berlin.

Ansonsten Schoenes Projekt. Vielleicht erläuterst du hier in möglichster 
kürze, wie du dein Signal aufbereitest, um die Qualität (Ich vermute, du 
redest vom Signal Rausch Abstand SNR) zu verbessern? Den Code wollte ich 
mir deswegen nicht gleich reinziehen müssen.

grüße,
 Clemens

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

sum wrote:
> Hi,
>
> hast du mal im Forum gesucht? ICh hatte da mal was geschrieben, was mir
> einen theoretisch Idealen Empfänger realisiert:
> Du musst das Empfangssignal mit der zeitinvertierten Impulsantwort
> deines Sendeformfilters falten und zum Abtastzeitpunkt abtasten. Das
> machst du natürlich mit 0 und mit 1 und kommst zu zwei Ergebnissen, die
> dir eigentlich aufschluss über den Wert des gesendeten Bits geben. Nennt
> sich Signalangepasster Filter (SAF). Implementiert hier:
> Beitrag "DCF77 Uhr, zum X.ten Mal, jetzt mit SAF"

Ich hab zum Falten zyklische Haar-Wavelets gewählt, das ist am 
einfachsten zu impementieren und passt auf das Signal.

> Ansonsten Schoenes Projekt. Vielleicht erläuterst du hier in möglichster
> kürze, wie du dein Signal aufbereitest, um die Qualität (Ich vermute, du
> redest vom Signal Rausch Abstand SNR) zu verbessern? Den Code wollte ich
> mir deswegen nicht gleich reinziehen müssen.

Den Fred hier hatte ich nicht weiter verfolgt, weil offenbar niemand 
sonst Probleme mit schlechtem DCF-Empfang hat, und ein Neustart der 
Empfänger-Software als probates Mittel bei nem schlechten Bit üblich 
ist.

In meinem Link oben hab ich ein bisschen was geschrieben, ist aber noch 
unvollständig.

Die Aufbereitung geht in 3 Schritten:

-- Sekunden-Sync und Bit-Erkennung
   Über zyklische Faltung wie gesagt, das kleinste Problem

-- Minuten-Erkennung
   Ist bei miesem Signal ebenfalls problematisch,
   weils viele falsche Minuten-Marken hat.
   Geht ebenfalls über Faltung, wobei man als Nebenprodukt
   das wichtige Bit 21 (Minute mod 2) sicher bestimmen kann.

-- Fehlerkorrektur
   Ist gut möglich wegen der hohen Redundanz der DCF-Info.
   Man darf sich nur nicht von den eingestreuten Minuten-Marken
   wurres machen lassen.

Bei den Daten in http://www.gjlay.de/pub/dcf77/konzept.html
sind 1/4 bis 1/3 der empfangenen Bits Schrott. Warum es nicht ratsam 
ist,
die Toleranzen für die Bits hoch zu schrauben, hab ich dort erklärt.

Würd mich mal interessieren, was Dein Algorithmus zu dem Datensatz sagt.

Johann

von sum (Gast)


Lesenswert?

Also, nachdem ich nun den Term "Haar Wavelets" gefunden habe, kann ich 
nur sagen, dass ich die auch verwendet habe. Denn die 0 und die 1 sind 
ja bekanntlich einfach nur rechteckimpulse unterschiedlicher länge. 
Passt also als zeitlich invertierte impulsantwort des sendeformfilters.

Wenn du den ausgang der Faltungen anschaust, erhälst du 
Dreieck/Trapez-ähnliche Signalformen. Anhand der Dreiecksspitzen und der 
Trapezdeckel kannst du den Abtastzeitpunkt erzeugen (Bit 
Synchronisation), die fehlende Absenkung kannst du wie in deinem Link 
gesagt ganz gut erkennen, wenn keine Dreieck/Trapezform vorhanden ist.

Soweit ich mich entsinne, war der Empfang bei mir nicht ideal, das 
Ausgangssignal meines Empfängermoduls hatte viele "Prellungen", ähnlich 
wie an Tastern, Spikes, die eben störungen wiederspiegeln. Dennoch 
konnte ich mit dem Empfang von mind. 3 oder 5 Datensätzen, von denen 
mehr richtig als falsch sein mussten, nach 5-10 min. die Uhrzeit sicher 
empfangen, Die Uhr ist mit dieser SW bei mir seit dem Beitrag (8/06) in 
Betrieb und hat bisher immer die Uhrzeit angezeigt und nie eine falsche 
angezeit - nagut ich hab auch nich immer davor gesessen.

MIch würde durchaus interessieren, was die Uhr bei deinem Signal 
anzeigt...

Die restlichen Fehlerkorrekturen die du vorschlägst beruhen ja auf der 
Charakteristik der übertragenen daten. Diese korrekturen geschehen ja 
erst nach der Entscheidung 0 oder 1. Mein Ansatz war halt, schon vorher 
dafür zuu sorgen, dass die Entscheidung 0 oder 1 entsprechend richtig 
ist.

Grüße,
 Clemens

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

sum wrote:
> Also, nachdem ich nun den Term "Haar Wavelets" gefunden habe, kann ich
> nur sagen, dass ich die auch verwendet habe. Denn die 0 und die 1 sind
> ja bekanntlich einfach nur rechteckimpulse unterschiedlicher länge.
> Passt also als zeitlich invertierte impulsantwort des sendeformfilters.

So verrät jeder den Stall, aus dem er kommt. Der eine aus der Mathe und 
der andere aus der E-Technik ;-)

> MIch würde durchaus interessieren, was die Uhr bei deinem Signal
> anzeigt...

Demnächst kommt die Software bei nem Kumpel in eine Mutteruhr. Falls ne 
Zeit falsch ist wegen Progammierfehler, tickern dann überall die Uhren 
los, so daß man falsche Zeit schnell mitbekommen würde :-)
Für das Bild (zeigt 4 Stunden) gelang einmal der Abgleich aller 3 
Zeit-Komponenten Minute, Stunde und Datum. Allerdings hatte ich noch 
keine Fehlerkorrektur/-erkennung für Minuten-Parity drinne.

> Die restlichen Fehlerkorrekturen die du vorschlägst beruhen ja auf der
> Charakteristik der übertragenen daten. Diese korrekturen geschehen ja
> erst nach der Entscheidung 0 oder 1. Mein Ansatz war halt, schon vorher
> dafür zuu sorgen, dass die Entscheidung 0 oder 1 entsprechend richtig
> ist.

Die Frage ist ja nicht wie bei Hamlet 0 oder 1. Was machst Du zum 
Beispiel mit einem Puls der Länge 130ms oder 3ms? Erster ist sehr 
wahrscheinlich eine 1 und zweiter wahrscheinlich eine 0, aber darauf 
bauen würd ich nicht. Von daher muss man auch nicht-identifizierbare 
Bits "?" zulassen, um die Sekunden-Synchronisation nicht zu verlieren.

Durch die Fehler-Korrktur sammelt man die Zeitinfo über mehrere Minuten 
und füllt immer mehr unbekannte Bits auf, bis schliesslich alle zusammen 
sind. Bei erkannten 0/1-Widersprüchen kann man das entsprechende Bit 
auch auf "?" setzen. Und das Verfahren muss sorgfältig durchdacht 
werden, um Fehlerausbreitung zu vermeiden.

Erzwingt man für jedes Bit einen der Werte 0,1 oder M-Marke, wird man 
bei schlechtem Signal recht viele Falsch-Bits bekommen. Dadurch erhöht 
sich die Wahrscheinlichkeit eines falschen Zeitabgleicht deutlich, weil 
schon 2 Falschbits pro Parity-Bereich genügen (Range-Tests geben nur nen 
recht kleine Zusatzgewinn an Sicherheit).

Die Faltung ist also eher ein einfaches Werkzeug, um bei Schotter-Bits 
nicht den Sync zu verlieren bzw. nachzuregeln; daß man den Wert eines 
Bits dabei rausbekommt ist fast nur noch ein angenehmer Nebeneffekt.

Der betriebene Aufwand hängt natürlich auch mit der Empfangslage 
zusammen, und selbstverständlich will man nicht mehr AUfwand treiben als 
nötig. Bei miesem Empfang dauert alleine die Minuten-Synchronisation 
schon fast 10 Minuten.

Die Faltungen sind der kleinste Teil des Programms, und ich bin noch am 
überlegen, was ich wie optimieren kann, weil je nach Verfahren viel Code 
gebraucht wird (1-3kByte).

von Sven P. (Gast)


Lesenswert?

Meiner Meinung nach ist ne FehlerKORREKTUR beim DCF-Signal ziemlich 
sinnfrei. Ich meine, außer ner grob gewählten Parität hab ich keine 
Ansatzpunkte, irgend nen Fehler zu korrigieren.
Sinnvoller finde ich es, dafür zu sorgen, dass nur korrekte Datenrahmen 
auch ausgewertet und übernommen werden -- für die restliche Zeit muss 
halt eine freilaufende Uhr sorgen.

Die Prüfung auf korrekten Empfang hab ich mal Idiotensicher auf folgende 
Weise umgesetzt:

1. Beim Empfang der Datenbits wir deren Länge von oben und unten 
geprüft. Ich versuchs mal als ASCII-Art auszudrücken:
1
| zu kurz     |  Bit 1  | undefiniert |  Bit 0  | zu lang
2
+-----------------------------------------------------------> t

2. Tritt ein Timeout auf, und sind bislang weniger als 59 Bits empfangen 
worden, führt das zum Neustart.

3. Werden mehr als 59 Bits empfangen, führt das auch zum Neustart

4. Es werden die Informationen aus dem Rahmen gewonnen (Minute, Stunde 
etc.). Dabei werden die mitgelieferten Paritätsbits geprüft.

5. Die Informationen werden einer Bereichsprüfung unterzogen (beim Tag 
des Monats wird vorher mit Berücksichtigung von Schaltjahren die 
Maximalzahl errechnet).

6. Der zerpflückte Rahmen wird zwischengespeichert und dann mit den 
folgenden Rahmen verglichen. Erst nach einer bestimmten Zahl von 
korrekten, aufeinanderfolgenden Rahmen werden die Daten dann übernommen.
Die Prüfung berücksichtigt dabei Szenarien wie Stunden-, Tages- oder 
Monatswechsel entsprechend.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johann L. wrote:
> Für das Bild (zeigt 4 Stunden) gelang einmal der Abgleich aller 3
> Zeit-Komponenten Minute, Stunde und Datum.

Tippfehler. bei dem Bild war es viel öfter, nämlich immer dann, wenn der 
Mittelbalken ganz grün ist. Der Mittelbalken sind die 3 Parity-Bits für 
den rechten Block: grün=ok, gelb=unbekannt, rot=Parity-Fehler erkannt.

Der linke Block stellt die Original-Daten dar, der rechte Block die 
gleichen Daten nach Fehlerkorrektur.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sven Pauli wrote:
> Meiner Meinung nach ist ne FehlerKORREKTUR beim DCF-Signal ziemlich
> sinnfrei. Ich meine, außer ner grob gewählten Parität hab ich keine
> Ansatzpunkte, irgend nen Fehler zu korrigieren.

Das Parity dient der Fehlererkennung und nicht der Fehlerkorrektur, kann 
aber selbst fehlerkorrigiert werden. Also nicht verwirren lassen...

> Sinnvoller finde ich es, dafür zu sorgen, dass nur korrekte Datenrahmen
> auch ausgewertet und übernommen werden -- für die restliche Zeit muss
> halt eine freilaufende Uhr sorgen.

Daß eine alles-oder-Nichts Ansatz nicht zum Ziel führt bei schlechter 
Empfangslage habe ich oben bereits ausführlich erklärt.

Natürlich werden nur als korrekt eingestufte Datensätze in die interne 
Zeit übernommen und natürlich läuft eine DCF-unabhängige Zeitbasis im 
Hintergrund und natürluch funktioniert das bei 1A-Signal und man wird 
keinen Aufwand treiben. Mit vollen Hosen ist eben gut Stinken ;-) und in 
all meinen bisherigen DCF-Uhren hab ich mich auch nie mit dem Thema 
auseinandersetzen müssen.

Aber geh einfach mal davon aus, daß mindestens 25% der empfangenen Bits 
nach Deiner Methode weder als "0" noch als "1" einstufbar sind. Die 
erwartete Zeit, bis bei so einem Signal alle Bits einer Minute einmal 
korrekt empfangen wurden, ist mindestens
Bei 40 Sekunden -- was für die Zeitinfo ausreicht -- sind's zwar nur 
noch 10 Wochen, aber eine solche DCF-Software ist damit wie Du gerne 
sagst "sinnfrei".

Weil die Bit-Ausbeute pro Minute nicht allzu prickeln ist, muss man die 
Bits eben über mehrere Minuten einsammeln.

Schreibt man die Minuten zeilenweise untereinander, dann ist die 
Redundanz in waagerechter Richtung wie Du korrekt bemerkst sehr gering 
und kann nicht zur Fehlerkorrektur herangezogen werden (hat nur 
Hamming-Abstand 1). Die damit realisierbare Fehlererkennung ist nicht 
sehr stark, kann aber durch die landläufigen Plausibilitätstest (Bereich 
und BCD-Format) verbessert werden.

In senkrechter Richtung ergibt sich hingegen eine sehr hohe Redundanz. 
Je nach Gusto kann diese zur Fehlerkorrektur oder -erkennung genutzt 
werden, was aber Plausibilitäts-Tests auf oberster Ebene m.E. nicht 
überflüssig macht.

von Sven P. (Gast)


Lesenswert?

Ich hab mal versucht, mich in die Theorie von Haar-Faltungen einzulesen 
-- nun raff ich auch was ihr hier alle wollt -- entsprechend war mein 
Post weiter oben bissi vorschnell (tschuldigung), aber nun gut.

Angenommen, man versucht einen Empfang Fehlerkorrektur durch 
Haar-Faltungen, dann werden zunächst zyklisch in jeder Sekunde die 
Abtastwerte vom Funkempfänger gefaltet, wodurch das Signal aus 
Mainflingen in drei diskrete Zustände (1, 0 und indeterminant) überführt 
wird. Über die Empfangsdauer entsteht dadurch ein eindimensionales Feld, 
ja?

Der Beginn eines jeden Feldes sei bekannt (praktisch die fehlende 
Absenkung des Trägers, also unterm Strich eine Zeitüberschreitung oder 
sowas).

Eine Anzahl dieser Felder wird nun nebeneinander angeordnet (es entsteht 
ein zweidimensionaler Vektor) und es wird wiederum gefaltet, um 
eventuelle Fehlstellen (also indeterminante Zustände) zu interpolieren, 
wenn man es denn so formulieren möchte.
1
n | 1 | 2 | 3 | 4 | z
2
--+---+---+---+---+---
3
 0| 0   0   0   0 |
4
 1| 1   0   0   1 |
5
 2| 1   1   1   1 |
6
 3| 0   0   0   1 |
7
 .| .   .   .   . |
8
 .| .   .   .   . |
9
 .| .   .   .   . |
10
56| 0   0   ?   1 |
11
57| ?   1   ?   0 |
12
58| ?   0   1   1 |
13
59| ?   ?   ?   ? |

Nach Empfang eines neuen Feldes rücken die drei gespeicherten Felder um 
eine Stelle weiter, wobei das älteste der Felder verloren geht und das 
gerade empfangene an erster Stelle erscheint.
Die Spalte z soll das Ergebnis der Faltung über die Zeile aufnehmen und 
darf keine indeterminanten Zustände mehr enthalten.

Schließlich werden die z-Spalten nach DCF-Manier ausgewertet, die 
Paritätsbits geprüft und all das damit angestellt, was ich in meinem 
ersten Post erwähnt hatte. Wobei zu überlegen wäre, ob sich die 
Kontinuität (auf Minute 4 folgt Minute 5) nicht auch schon während der 
letzten Faltung prüfen ließe.

Hab ich das Prinzip soweit einigermaßen ... verstanden?

von sum (Gast)


Lesenswert?

Hoi Hey,

deine Beschreibung, Johannes, ist sehr schön formuliert: "Die bits 
einsammeln". Natürlich erhält man dann eine deutlich bessere 
Signalqualität und kann Fehler korrigieren, wenn der Hamming-abstand 
stimmt. Nur: wonach misst du die "Länge" der Absenkungen? Wenn du von x 
oder y ms redest, denke ich immer gleich (tschuldigung), an DCF77->INT0, 
was natürlich totaler quatsch ist. Insofern: deine Iddee, die ich jetzt 
endlich verstanden zu haben scheine, ist super. Ich hoffe, du legst auch 
die richtigen Grundlagen bei der Entscheidung 0/1/M/?. Vorbereitung ist 
die Halbe Arbeit.
Für mich ist jetzt noch folgende Frage interessant:
Wie bewertest du das Ausgangssignal des Integrators, wie lang integriert 
dein INtegrator (ich vermute du wirst auch einen Kammfilter/fliessender 
Mittelwert nehmen), und woher nimmst du den abtastzeitpunkt. Vielleicht 
erklärst du das noch kurz (oder habe ich es überlesen? ich zweifle 
langsam an mir selbst...) oder nimmst hier noch ein paar Anregungen von 
den Ideen aus meinem Code (Link sieze oben).

Grüße,
 Clemens

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sven Pauli wrote:
> Ich hab mal versucht, mich in die Theorie von Haar-Faltungen einzulesen
> -- nun raff ich auch was ihr hier alle wollt -- entsprechend war mein
> Post weiter oben bissi vorschnell (tschuldigung), aber nun gut.
>
> Angenommen, man versucht einen Empfang Fehlerkorrektur durch
> Haar-Faltungen, dann werden zunächst zyklisch in jeder Sekunde die
> Abtastwerte vom Funkempfänger gefaltet, wodurch das Signal aus
> Mainflingen in drei diskrete Zustände (1, 0 und indeterminant) überführt
> wird. Über die Empfangsdauer entsteht dadurch ein eindimensionales Feld,
> ja?

Soweit korrekt, nur sind es 4 Zustände. Der 4te ist die Minuten-Marke, 
abgekürzt als M oder #.

> Der Beginn eines jeden Feldes sei bekannt (praktisch die fehlende
> Absenkung des Trägers, also unterm Strich eine Zeitüberschreitung oder
> sowas).

Nein, keine Zeitüberschreitung. Wie in der Animation "haar-faltung.gif" 
zum Haar-Wavelet wird dieses verwendet, um das Maximum zu finden. Wenn 
das Maximum klein ist, zB kleiner als 2 bei 100 Samples/Sekunde, dann 
ist das Bit ein #.

> Eine Anzahl dieser Felder wird nun nebeneinander angeordnet (es entsteht
> ein zweidimensionaler Vektor) und es wird wiederum gefaltet, um
> eventuelle Fehlstellen (also indeterminante Zustände) zu interpolieren,
> wenn man es denn so formulieren möchte.

Nein. Wenn Bit n von Minute m ein 0 ist und zwei Minuten später ist es 
eine 1, kannst Du nicht interpolieren, um Bit n von Minute m+1 zu 
bestimmen (übrigens auch nicht, wenn die Werte beide 0 sind).

> Nach Empfang eines neuen Feldes rücken die drei gespeicherten Felder um
> eine Stelle weiter, wobei das älteste der Felder verloren geht und das
> gerade empfangene an erster Stelle erscheint.

Jepp. Zuerst hatte ich 3 Minutel à 60 DCF-Bits gespeichert (jedes 
DCF-Bit kann wie gesagt 4 Werte haben. Ist also eher ein double Bit).
Es hat sich aber gezeigt, daß ich das nicht brauche und 2 Minutensätze 
reichen.

Minute m wird fehlerkorrigiert aus Minute m-1, das genügt zum 
Aufsammeln.

> Schließlich werden die z-Spalten nach DCF-Manier ausgewertet, die
> Paritätsbits geprüft und all das damit angestellt, was ich in meinem
> ersten Post erwähnt hatte.

> Hab ich das Prinzip soweit einigermaßen ... verstanden?

Bis auf das, was in der Fehlerkorrektur passiert.

Die Werte der DCF-Bits aus der Faltung zu erhalten stellt zwar genau 
genommen schon eine Art der Fehlerkorrektur dar (Mainflingen sendet nur 
exakt 100ms oder 200ms oder keine Absenkung, sobald man etwas anderes 
als 0 oder 1 akzeptiert, ist das ne Fehlerkorrektur).

Das meine ich aber nicht, wenn ich von "Fehlerkorrektur" rede. Die 
Fehlerkorrektur bzw. das Flicken unbekannter DCF-Bits ist unabhängig 
davon, wie man an diese Bits herankommt.

Die Fehlerkorrektur ist blankes Bit-Gefummel.

Nehmen wir mal an, es sind folgende Werte für DCF-Bits ab Position 21 
(Minute.0) empfangen worden:
1
       21 22 23 24 25 26
2
-------------------------
3
m       ?  ?  0  1  ?  1
4
m+1     ?  1  0  ?  ?  0 
5
-------------------------
6
m+1     ?  1  0  1  ?  ?

Das wäre ein schlechtes Signal, zeigt aber das Prinzip:

Weil Bit 22 von Minute m+1 gleich 1 ist, müssen alle höherwertigen Bits 
von m und m+1 übereinstimmen. Zunächst kann von m nach m+1 kein Reset 
stattgefunden haben (der Reset-Wert der Minute ist 0, und Bit 22 ist 1). 
Damit ist die Minute von m nach m+1 um 1 erhöht worden. Daraus folgt, 
daß alle Bits ab Bit 23 gleich sein müssen (überleg Dir, warum).

Daher kann Bit 24 übernommen werden. Bit 26 wurde gelöscht, weil es 
offenbar einen Übertragungsfehler gab. Bits höher als 26 können auch 
alle übernommen werden, ausser Minuten-Parity.

Diese Korrektur geschieht bei mir nur auf Bit-Ebene. Es ist nicht 
ratsam, zu viel Kenntnis zu nutzen. Beispiel: Minute m wurde als 19 
übertragen. Fehlt Minute m+1, dann muss der Wert 20 sein. Verwendet man 
dieses Wissen zur Korrektur, raubt man sich eine wichtige Möglichkeit 
zur Fehlererkennung. Gerade bei schlechtem Signal sind Falsch-Bits 
relativ häufig, und eine Fehlererkennung also doppelt wichtig. Wenn man 
aber 20 berechnet aus 19+1, wird der Fehler-Check trivial.

Zudem ergibt sich die Frage: Was, wenn im obigen Beispiel Bit22 falsch 
übertragen wurde? Dann würde man daraus viele falsche Schlussfolgerungen 
ziehen. Ein Weg aus dem Dilemma wäre, bei mehr als einem Falschbit pro 
Datensatz den Satz komplett zu löschen. Ein anderer Ausweg ist, sich 
nicht auf unsichere Voraussetzungen zu verlassen. Bit 0 der Minute 
wechselt mit jeder Minute und ist jede 2-te Minute 1. In allen 
ungeraden Minuten kann man also alle Bits ausser Bit 0 und Minute-Parity 
aus der Vorminute übernehmen bzw. nen Test auf Bitfehler machen, wenn 
beide Bits ungleich ? sind. Und man weiß in dem Fall, daß Minute-P 
wechseln muss.

Dieser einfache Fall ist sehr leicht zu implementieren. Er korrigiert 
nicht so agressiv wie der Algorithmus, der Grundlage für die Daten in 
der Visualisierung "dcf-10ms-pulses-ec.png" war, aber bringt eine 
deutliche Verbesserung der Datenlage. Wenn man nicht korrigieren möchte, 
bietet er immer noch die Möglichkeit der Erkennung von Falschbits, die 
deutlich besser ist als sich nur auf Parity zu verlassen. Zugleich 
bleiben genügend Redundanzen, damit auf höherer Ebene 
Plausibilitäts-Tests nicht trivial werden aufgrund der Korrektur.

sum wrote:
> Hoi Hey,
>
> deine Beschreibung, Johannes, ist sehr schön formuliert: "Die bits
> einsammeln". Natürlich erhält man dann eine deutlich bessere
> Signalqualität und kann Fehler korrigieren, wenn der Hamming-abstand
> stimmt. Nur: wonach misst du die "Länge" der Absenkungen? Wenn du von x
> oder y ms redest, denke ich immer gleich (tschuldigung), an DCF77->INT0,
> was natürlich totaler quatsch ist. Insofern: deine Iddee, die ich jetzt
> endlich verstanden zu haben scheine, ist super. Ich hoffe, du legst auch
> die richtigen Grundlagen bei der Entscheidung 0/1/M/?. Vorbereitung ist
> die Halbe Arbeit.

Was aus den Faltungen rauskommt bewerte ich ganz analog zu einer 
gebräuchlichen Bitlängen-Bestimung. Der Maximalwert ist implizit gegeben 
durch die Breite des Wavelets und muss nicht mehr getestet werden.
Als Minimalwert geht Länge -2ms bis -3ms. Größer würde ich die Toleranz 
auf keinen Fall machen. Wie gesagt ist es besser mit ? zu leben als mit 
einer falschen 0 oder falschen 1.

> Für mich ist jetzt noch folgende Frage interessant:
> Wie bewertest du das Ausgangssignal des Integrators, wie lang integriert
> dein INtegrator (ich vermute du wirst auch einen Kammfilter/fliessender
> Mittelwert nehmen), und woher nimmst du den abtastzeitpunkt.

-- zyklisch Falten mit 100ms Haar-Wavelet
-- zyklisch  Falten mit 200ms Haar-Wavelet
-- (zyklisch) Falten mit 1s Haar-Wavelet, d.h alls Samples der Sekunde 
summieren

Wenn noch kein Sek-Sync erfolt ist, wird überall gefaltet. Die Samples 
mehrerer guter Bits (einsortiert als DCF0 oder DCF1) werden aufsummiert, 
im Endeffekt also das Signal über mehrere Sekunden gemittelt. Im 
Idealfall sieht das so aus:
1
          **********
2
          *        *
3
          *        **********
4
          *                 *
5
          *                 *
6
***********                 ******************************

Damit erkennt man den Sekundenanfang und weiß danach, wo zu falten ist.

Nach dem Sekunden-Sync bewerte ich auch anders, hier mal als C-Snip
1
#define LEN_SEC 100
2
// Länge einer Sekunde, d.h. Anzahl Samples pro Sekunde
3
// Muss < 127 sein
4
5
#define LEN_0_MIN  7
6
#define LEN_0      9
7
8
#define LEN_1_MIN 17
9
#define LEN_1     19
10
11
uint8_t rate_bit (void)
12
{
13
    haar_eval_t * r = timeinfo.dcf.eval;
14
    uint8_t mode = timeinfo.dcf.synced_sec ? HAAR_0_START : HAAR_0_ALL;
15
    haar3 (summ, mode, r);
16
17
    // Jeweils Maximum (und Index) für zykl. Haar-Faltung mit Wavelet-Breite
18
    uint8_t r0_max = r[0].max; // 1s
19
    uint8_t r1_max = r[1].max; // 100ms
20
    uint8_t r2_max = r[2].max; // 200ms
21
22
    if (!timeinfo.dcf.synced_sec)
23
    {
24
        if (r2_max >= LEN_1_MIN)
25
            if ((uint8_t) (r0_max-r2_max) <= 6)
26
                return 1;
27
28
        if (r1_max >= LEN_0_MIN)
29
            if ((uint8_t) (r0_max-r1_max) <= 6)
30
                if ((uint8_t) (r2_max-r1_max) <= 3)
31
                    return 0;
32
    }
33
    else
34
    {
35
        if (r2_max >= LEN_1_MIN)
36
            if ((uint8_t) (r0_max-r2_max) <= 10)
37
                return 1;
38
39
        if (r1_max >= LEN_0_MIN)
40
            if ((uint8_t) (r0_max-r2_max) <= 10)
41
                if (r2_max <= 12)
42
                    return 0;
43
44
        if (r2_max  == 0)
45
            if (r0_max <= 5)
46
                return 2;
47
    }
48
49
    return 3;
50
}
51
52
// 0 = 0
53
// 1 = 1
54
// 2 = Minuten-Marke
55
// 3 = Schrott

D.h. ich schau auf Mindestlängen (Maxlängen sind gegeben durchs 
Wavelet). Ausserdem erlaub ich ausserhalb des Wavelets nur ne gewisse 
Anzahl an Spikes. Die Anzahl Spikes ausserhalb des Ansenkung erhält man 
einfach, indem man das Faltergebnis von der Gesamtsumme über 1 Sekunde 
abzieht.

Grüß, Johann

von sum (Gast)


Lesenswert?

Hallo Johann,

nun war ich ein paar Tage nicht hier und schon schreibst du dir die 
Finger wund! Sehr schön. Aber leider kann ich aus deinem Code-Beispiel 
nicht so richtig schlau werden, dafür sind die Abkürzungen zu kryptisch.
ICh denke aber, du hast dir schon sehr wohl Gedanken über 
Toleranz-Schwellen, Abtastzeitpunkt, etc gemacht...

Deine Erklärungen zur Bit-Sammlung/Korrektur, nachdem auf 0/1/#/? 
entschieden wurde, sind einleuchtend. Man kann das Prinzip ja auch ganz 
gut in den Grafiken Erkennen (Weiter oben).

Meinst du, es ist möglich, diese Vorgehensweise (Wenn Minutenbit X = 0 
dann Minutenbit Y = 1 oder auch m-1 und m+1 und soweiter) in eine 
Formulierungsform zu bringen, die durch den Mikrocontroller selbst 
gelesen (und verstanden) werden kann? Ich denke da an eine Art Tabelle 
im Flash, in der die Informationen über die Zusammenhänge der Bits 
zueinander von aufeinanderfolgenden Datensaetzen und von Bits eines 
Datensatzes untereinander gespeichert sind, die du dann in eine Funktion 
speist, die dir nach Möglichkeit gleich die fehlerkorrigierte Version 
ausspukt.

Also mal ein Beispiel, was nichts mit DF77 zu tun hat: Du Hast ein 
Display und implementierst ein Menu, das kann Strings, WErte anzeigen, 
auf die Tasten gibt es Reaktionen und die Reaktionen können Wieder 
MEnues aufrufen oder Werte verändern. Das könnte man schön in eine 
Struktur packen, die dann genau dieser Funktion (Menu) übergeben wird 
und die Funkion Menü hat mit dem eigentlichen Menü nichts mehr am Hut. 
Um dein Menü zu ändern brauchst du nur die Sturktur ändern (im Flash).

Die Idee ist, dass es A) einfach zu formulieren ist (eine Struktur im 
Flash ablegen sollte nicht so schwer oder Fehleranfällig sein) und der 
Code (das, was normalerweise Fehleranfällig ist - bei mir zumindest), 
ist mehr oder minder regulär, d.h. es gibt keine großen und vor allem 
nicht so leicht testbaren If-Verschachtelungen. Die Interpretierfunktion 
würde man dann mit einem Stückchen Daten zum Testen füttern, die 
praktisch alles Abdecken. Durch die (gründliche und vor allem Einfache) 
Formulierung des eigentlichen Inhalts in einer Tabelle/Struktur sollten 
dann keine Fehler mehr kommen.
Abgesehen davon, dass eine Tabelle schneller leichter und einfacher zu 
programieren ist, als unendlich viele IF-Then-Else sachen...

Vielleicht fällt dir ja etwas gutes ein, ich habe da erstmal an sowas 
wie Bitmuster gedacht, die mit den Daten gefaltet werden. Damit das 
alles klappt müsste man halt "ausreichend" viele Daten im Ram lagern, 
wobei man auch das formulativ auf die nötigen Daten reduzieren könnte 
(Minutenbits nur die letzten 5 minuten, Stunden nur Mittelwerte der 
Stunde oder sowas, damit der RAMbedarf begrenzt bleibt). Weiterhin kann 
man in der StrukturTabelle auch ablegen, mit welcher Frequenz gefaltet 
wird... Naja, ich hoffe du bekommst einen Eindruck vondem, was ich mir 
so dazu denke.

Grüße,
 Clemens

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

sum wrote:
> Hallo Johann,
>
> Meinst du, es ist möglich, diese Vorgehensweise (Wenn Minutenbit X = 0
> dann Minutenbit Y = 1 oder auch m-1 und m+1 und soweiter) in eine
> Formulierungsform zu bringen, die durch den Mikrocontroller selbst
> gelesen (und verstanden) werden kann? Ich denke da an eine Art Tabelle
> im Flash, in der die Informationen über die Zusammenhänge der Bits
> zueinander von aufeinanderfolgenden Datensaetzen und von Bits eines
> Datensatzes untereinander gespeichert sind, die du dann in eine Funktion
> speist, die dir nach Möglichkeit gleich die fehlerkorrigierte Version
> ausspukt.

Möglich ist so ein abstrakter Ansatz sicher, aber für Hänflinge wie 
kleine AVR tendiere ich eher dazu, Resourcend-schonend zu programmieren.

Ausserdem dürfte so eine Fehlerkorrektur sehr speziell sein und 
ausserhalb von DCF/HBG keine Anwendung finden.

Die sehr einfachen Regeln hatte ich in

http://www.gjlay.de/pub/dcf77/konzept.html#fehlerkorrektur

beschrieben. Dabei muss man darauf achten, nicht zu viel Wissen zu 
nutzen, weil sonst wie gesagt die Konsistenz-Tests trivial werden oder 
Fehlerausbreitung stattfindet.

Die Regel würde ich so zusammenfassen:
1
Wenn eine 1 in Minute oder Stunde empfangen wird,
2
dürfen alle höherwertigen Bits der Vorminute
3
übernommen werden.

Das hat den Vorteil, daß es trivial einfach ist und keine große 
Arithmetik gebraucht wird.

Ausserdem kommt es sehr viel häufiger vor, daß 0-statt-1-Fehler 
auftreten als 1-statt-0-Fehler, die ich praktisch nicht beobachte. Es 
sei denn, das Signal ist so krass, das es eh nicht auswertbar ist. Das 
erhöht die Sicherheit der Korrektur. Es gibt zwar auch eine Regel für 
0-Bits, die ich aber wegen der zwar geringen, aber immerhin 
existierenden 0-statt-1-Fehler nicht anwende, weil das zu 
falsch-angewandter Korrektur führen würden. Nachgeschaltete 
Konsistenztests erkennen das zwar, aber ich verzichte dennoch darauf.

> Grüße,
>  Clemens

von Jörg H. (idc-dragon)


Lesenswert?

Ich habe diesen Thread gerade gefunden...

Unabhängig von der sehr fortgeschrittenen Diskussion kann ich anmerken, 
dass ich einen stark gestörten DCF-Empfang habe. Sieht aus wie ziemlich 
viele Fehlpulse, eine testweise angeschlossene LED ist wie wild am 
Blinken, statt ruhig im Sekundentakt.

Mein Empfänger (eine Haussteuerung) kann locker viele Tage damit 
zubringen auf eine intakte Uhrzeit zu warten. Letztens habe ich das Ding 
entnervt mauell gestellt. Manchmal zieht er sich auch falsches 
Datum/Uhrzeit rein, aber glücklicherweise selten.
Falls ich die Steuerung mal durch einen Eigenbau ersetze bin ich an so 
einem Algorithmus sehr interessiert. Das ist also kein rein akademisches 
Thema.

Wenn jemand also so ein Signal zum Testen braucht, damit kann ich lang 
weg dienen. :-/
Wäre noch zu klären wie ich das aufzeichne. Als WAV?

Jörg

von sum (Gast)


Lesenswert?

Moin Jörg,

du kannst das Signal aufzeichnen, indem du den Demodulatorausgang (also 
hinter der Erkennung der Absenkungen) mit z.B. 1ms Taktperiode 
abtastest und zeilenweise (0/1) in eine Datei packst. Das ganze kann man 
dann gut mit Zip/Gzip packen und hier posten. Wäre aber wichtig, dass du 
da einige Zeit aufzeichnest (ohne Lücken), damit die Erkennung 
tatsächlich simuliert werden kann (einsammeln dauert halt...).

Ich habe leider keinen sonderlich gestörten Empfang hier und kann damit 
nicht dienen.

Grüße,
 Clemens

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.