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