DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Hallo Habr.

Wahrscheinlich haben viele, die eine Uhr oder eine Wetterstation kaufen, das Logo Radio Controlled Clock oder sogar Atomic Clock auf der Verpackung gesehen. Das ist sehr praktisch, denn man muss die Uhr nur auf den Tisch stellen, und sie stellt sich nach einer gewissen Zeit automatisch auf die genaue Uhrzeit ein.
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Lassen Sie uns erklären, wie das funktioniert, und einen Decoder in der Programmiersprache Python schreiben.

Es gibt verschiedene Zeit-synchronisierungssysteme. Das bekannteste in Europa ist das deutsche System DCF-77, in Japan gibt es ein eigenes System JJY, in den USA gibt es ein System WWVB, und so weiter. Der folgende Bericht handelt von DCF77, da es das am meisten relevante und in einigen Teilen Europas, einschließlich Russland und angrenzenden Ländern, empfangbare Signal ist (Bewohner des Fernen Ostens könnten eine andere Meinung haben, sie können jedoch den japanischen Signal empfangen und analysieren;).

Alles, was hier geschrieben wird, bezieht sich auf DCF77.

Signalempfang

DCF77 ist eine Langwellensstation, die auf einer Frequenz von 77,5 kHz arbeitet und Signale in Amplitudenmodulation überträgt. Die Station mit einer Leistung von 50 kW befindet sich 25 km von Frankfurt entfernt und nahm ihren Betrieb bereits 1959 auf; im Jahr 1973 wurde die Datumsinformation zur genauen Uhrzeit hinzugefügt. Die Wellenlänge bei einer Frequenz von 77 kHz ist eher groß, daher sind die Abmessungen des Antennenfeldes ebenfalls ziemlich anständig (Foto aus Wikipedia):
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Mit einer solchen Antenne und zugeführter Leistung umfasst der Empfangsbereich fast ganz Europa, Weißrussland, die Ukraine und einen Teil Russlands.

DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Jeder kann das Signal aufzeichnen. Dazu muss man nur einen Online-Empfänger nutzen http://websdr.ewi.utwente.nl:8901/, dort die Frequenz 76,5 kHz und die USB-Modulation auswählen. Es sollte sich ein Bild öffnen, das etwa so aussieht:

DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Dort klicken wir auf die Schaltfläche Download und zeichnen einen Abschnitt von mehreren Minuten auf. Natürlich kann man bei Vorhandensein eines „echten“ Empfängers, der die Frequenz von 77,5 kHz aufzeichnen kann, auch diesen verwenden.

Natürlich erhalten wir, wenn wir Radiosignale mit exakter Uhrzeit über das Internet empfangen, nicht die wirklich genaue Zeit — das Signal wird mit einer Verzögerung übertragen. Aber unser Ziel ist es nur, die Struktur des Signals zu verstehen; dafür sind Internetaufzeichnungen mehr als ausreichend. In der Realität werden natürlich spezialisierte Geräte zum Empfang und zur Dekodierung verwendet, über die unten gesprochen wird.

Also, wir haben eine Aufzeichnung erhalten, lassen Sie uns mit ihrer Analyse beginnen.

Signal dekodieren

Laden wir die Datei mit Python und schauen wir uns ihre Struktur an:

from scipy.io import wavfile
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

sample_rate, data = wavfile.read("dcf_websdr_2019-03-26T20_25_34Z_76.6kHz.wav")
plt.plot(data[:100000])
plt.show()

Wir sehen eine typische Amplitudenmodulation:
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Um die Decodierung zu vereinfachen, nehmen wir die Hüllkurve des Signals mit Hilfe der Hilbert-Transformation:

analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])

Das Ergebnis in vergrößerter Ansicht:
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Wir glätten Ausreißer durch ein Tiefpassfilter und berechnen gleichzeitig den Mittelwert, der später zum Parsen benötigt wird.

b, a = signal.butter(2, 20.0/sample_rate)
zi = signal.lfilter_zi(b, a)
A, _ = signal.lfilter(b, a, A, zi=zi*A[0])
avg = (np.amax(A) + np.amin(A))/2

Das Ergebnis (gelbe Linie): ein nahezu rechteckiges Signal, das relativ leicht zu analysieren ist.
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Parsing

Zuerst müssen wir die Bitfolge erhalten. Die Struktur des Signals ist sehr einfach.
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Die Impulse sind in Sekundenintervalle unterteilt. Wenn der Abstand zwischen den Impulsen 0.1s beträgt (d.h. die Länge des Impulses 0.9s), fügen wir der Bitfolge "0" hinzu, wenn der Abstand 0.2s beträgt (d.h. die Länge 0.8s), fügen wir "1" hinzu. Das Ende jeder Minute wird durch einen "langen" Impuls von 2s Länge gekennzeichnet, die Bitfolge wird dabei zurückgesetzt und die Füllung beginnt von neuem.

Das oben Geschriebene lässt sich leicht in Python umsetzen.

sig_start, sig_stop = 0, 0
pos = 0
bits_str = ""
while pos < cnt - 4:
    if A[pos]  avg:
        # Signalbeginn
        sig_start = pos
    if A[pos] > avg and A[pos+1] < avg:
        # Signalende
        sig_stop = pos

        diff = sig_stop - sig_start
    
        if diff  0.85*sample_rate and diff  1.5*sample_rate:
            print(bits_str)
            bits_str = ""

    pos += 1

Als Ergebnis erhalten wir eine Bitfolge, die in unserem Beispiel für zwei Sekunden so aussieht:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Übrigens ist es interessant, dass im Signal auch eine "zweite Schicht" von Daten existiert. Die Bitfolge ist ebenfalls kodiert mit Phasenmodulation. Theoretisch sollte dies eine stabilere Decodierung auch bei schwächeren Signalen ermöglichen.

Unser letzter Schritt: die eigentlichen Daten erhalten. Die Bits werden einmal pro Sekunde übertragen, sodass wir insgesamt 59 Bits haben, die viele Informationen kodieren:
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Die Bits sind wie folgt beschrieben Wikis, und sie sind ziemlich neugierig. Die ersten 15 Bits werden nicht verwendet, obwohl es Pläne gab, sie für Warnsysteme und den Zivilschutz zu nutzen. Bit A1 zeigt an, dass die Uhren in der nächsten Stunde auf Sommerzeit umgestellt werden. Bit A2 zeigt an, dass in der nächsten Stunde eine zusätzliche Sekunde, die manchmal zur Korrektur der Zeit gemäß der Erdrotation verwendet wird, hinzugefügt wird. Die übrigen Bits kodieren die Stunden, Minuten, Sekunden und das Datum.

DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Für alle, die selbst experimentieren möchten, ist der Code zum Dekodieren unter dem Spoiler aufgeführt.
Quellcode

def decode(bits):
    if bits[0] != '0' or bits[20] != '1':
        return
    
    minutes, hours, day_of_month, weekday, month, year = map(convert_block,
                                                             (bits[21:28], bits[29:35], bits[36:42], bits[42:45],
                                                              bits[45:50], bits[50:58]))
    days = ('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag')
    print('{dow}, {dom:02}.{mon:02}.{y}, {h:02}:{m:02}'.format(h=hours, m=minutes, dow=days[weekday],
                                                               dom=day_of_month, mon=month, y=year))


def convert_ones(bits):
    return sum(2**i for i, bit in enumerate(bits) if bit == '1')


def convert_tens(bits):
    return 10*convert_ones(bits)


def right_parity(bits, parity_bit):
    num_of_ones = sum(int(bit) for bit in bits)
    return num_of_ones % 2 == int(parity_bit)


def convert_block(bits, parity=False):
    if parity and not right_parity(bits[:-1], bits[-1]):
        return -1
    
    ones = bits[:4]
    tens = bits[4:]
    return convert_tens(tens) + convert_ones(ones)

Wenn wir das Programm ausführen, werden wir etwa diese Ausgabe sehen:

0011110110111000001011000001010000100110010101100010011000
Dienstag, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Dienstag, 26.03.19, 21:42

Das ist eigentlich die ganze Magie. Der Vorteil eines solchen Systems liegt darin, dass die Dekodierung extrem einfach ist und auf jedem noch so einfachen Mikrocontroller durchgeführt werden kann. Wir zählen einfach die Pulsdauer, sammeln 60 Bits und am Ende jeder Minute erhalten wir die genaue Zeit. Im Vergleich zu anderen Methoden zur Zeitsynchronisation (zum Beispiel GPS oder, Gott bewahre, das Internet:) erfordert diese Radiosynchronisation praktisch keinen Strom — zum Beispiel funktioniert ein gewöhnliches Heimwettergerät etwa ein Jahr lang mit 2 AA-Batterien. Daher werden sogar Armbanduhren mit Radiosynchronisation hergestellt, ganz zu schweigen von Wand- oder Straßenbahnhöfen.

Der Komfort und die Einfachheit von DCF ziehen auch Bastler an. Für nur 10-20 $ kann man ein fertiges Modul mit Antenne und fertigem Empfänger sowie TTL-Ausgang kaufen, das man an Arduino oder einen anderen Controller anschließen kann.
DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Für Arduino sind bereits passende Bibliotheken verfügbar. Es ist jedoch bekannt – egal was man mit einem Mikrocontroller macht, am Ende erhält man entweder eine Uhr oder ein Wetterstation. Mit einem solchen Gerät ist es tatsächlich nicht schwierig, die genaue Uhrzeit zu erhalten, vorausgesetzt, man befindet sich in Empfangsbereich. Man kann auch auf die Uhr den Schriftzug „Atomic Clock“ anbringen und gleichzeitig jedem, der es hören möchte, erklären, dass das Gerät tatsächlich mit Atomuhren synchronisiert wird.

Wer möchte, kann sogar die alten Uhren der Großmutter aufrüsten, indem er einen neuen Mechanismus mit Funk-Synchronisation einbaut:

DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?

Einen solchen kann man bei ebay mit den Schlüsselwörtern „Radio Controlled Movement“ finden.

Und schließlich ein Lifehack für diejenigen, die bis hierher gelesen haben. Selbst wenn in den nächsten paar tausend Kilometern kein einziger Radiosignal-Transmitter vorhanden ist, ist es nicht schwer, ein solches Signal selbst zu generieren. Im Google Play Store gibt es eine App mit dem Namen „DCF77 Emulator“, die ein Signal über die Kopfhörer ausgibt. Laut Aussage des Autors, wenn man das Kabel der Kopfhörer um die Uhr wickelt, fangen sie das Signal ein (interessant, wie, denn normale Kopfhörer geben kein 77kHz-Signal aus, aber wahrscheinlich erfolgt der Empfang über Harmonische). Bei mir auf Android 9 hat die App überhaupt nicht funktioniert – es gab einfach keinen Ton (oder vielleicht habe ich ihn nicht gehört – schließlich sind es 77kHz :), aber vielleicht hat jemand mehr Glück. Einige stellen sich übrigens auch einen vollwertigen DCF-Signalgenerator her, den man recht einfach mit der gleichen Arduino oder ESP32 bauen kann:

DCF77: Wie funktioniert das System zur Übertragung von präzisen Zeitmessungen?
(Quelle sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Fazit

Das DCF-System stellte sich als tatsächlich recht einfach und praktisch heraus. Mit einem einfachen und günstigen Empfänger kann man immer und überall die genaue Uhrzeit haben, natürlich im Empfangsbereich. Ich denke, selbst trotz der allgegenwärtigen Digitalisierung und „Internet der Dinge“ werden solche einfachen Lösungen noch lange gefragt sein.

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster