DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Hallo Habr.

Velen die een klok of een weerstation kopen, hebben waarschijnlijk het logo Radio Controlled Clock of zelfs Atomic Clock op de verpakking gezien. Dit is erg handig, want je hoeft de klok alleen maar op tafel te zetten, en na een tijdje stelt hij zichzelf automatisch in op de exacte tijd.
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Laten we bekijken hoe dit werkt en een decoder schrijven in Python.

Er zijn verschillende tijdsynchronisatiesystemen. Het meest populaire in Europa is het Duitse systeem DCF-77, in Japan is er een eigen systeem JJY, in de VS is er een systeem WWVB, enzovoort. Het volgende verhaal gaat over DCF77, als het meest actuele en beschikbare systeem voor ontvangst in bepaalde delen van het Europese deel van Rusland en aangrenzende landen (bewoners van het Verre Oosten hebben misschien een andere mening, maar zij kunnen op hun beurt ook het Japanse signaal ontvangen en analyseren;).

Alles wat hierna wordt besproken, gaat over DCF77.

Ontvangst van het signaal

DCF77 is een lange golfstation dat werkt op een frequentie van 77.5 kHz en signalen in amplitude-modulatie verstuurt. Het station met een vermogen van 50 kW bevindt zich op 25 km van Frankfurt en begon zijn werkzaamheden al in 1959. In 1973 werd er informatie over de datum aan de exacte tijd toegevoegd. De golflengte bij een frequentie van 77 kHz is vrij groot, waardoor de afmetingen van het antenneveld ook aanzienlijk zijn (foto van Wikipedia):
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Met zo'n antenne en aangevoerde kracht beslaat het ontvangstgebied vrijwel heel Europa, Wit-Rusland, OekraĆÆne en een deel van Rusland.

DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Iedereen kan het signaal opnemen. Hiervoor is het voldoende om naar een online ontvanger te gaan http://websdr.ewi.utwente.nl:8901/, daar de frequentie 76.5 kHz en USB-modulatie te kiezen. Er zou een afbeelding moeten verschijnen die er ongeveer zo uitziet:

DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Daar klikken we op de knop download en nemen we een fragment op van enkele minuten. Natuurlijk, met een "echte" ontvanger die in staat is om de frequentie van 77.5 kHz op te nemen, kan die ook worden gebruikt.

Natuurlijk, als we radiosignalen van exacte tijd via het internet ontvangen, krijgen we niet echt exact de tijd — het signaal wordt met vertraging verzonden. Maar ons doel is alleen de structuur van het signaal te begrijpen, hiervoor zijn internetopnames meer dan voldoende. In de praktijk worden uiteraard gespecialiseerde apparaten gebruikt voor ontvangst en decodering, waarover later meer zal worden verteld.

Dus, we hebben de opname, laten we beginnen met de verwerking.

Decodering van het signaal

Laten we het bestand openen met Python en naar de structuur ervan kijken:

van scipy.io import wavfile
van 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()

We zien typische amplitude modulatie:
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Om de decodering te vereenvoudigen, nemen we de enveloppe van het signaal met behulp van de Hilbert-transformatie:

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

Het resultaat in vergroot formaat:
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

We filteren de uitbijters door een low-pass filter te gebruiken en berekenen tegelijkertijd het gemiddelde, dat later nuttig zal zijn voor de parsing.

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

Het resultaat (gele lijn): praktisch een rechthoekig signaal, dat relatief eenvoudig te analyseren is.
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Parsing

Allereerst moeten we de bitreeks verkrijgen. De structuur van het signaal is heel eenvoudig.
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

De pulsen zijn verdeeld over seconden. Als de afstand tussen de pulsen 0,1 s bedraagt (d.w.z. de lengte van de puls 0,9 s), voegen we een '0' toe aan de bitreeks; als de afstand 0,2 s is (d.w.z. de lengte 0,8 s), voegen we een '1' toe. Het einde van elke minuut wordt gemarkeerd met een 'lange' puls van 2 s, en de bitreeks wordt gereset, waarna de telling opnieuw begint.

Het bovenstaande is niet moeilijk te coderen in Python.

sig_start, sig_stop = 0, 0
pos = 0
bits_str = ""
while pos < cnt - 4:
    if A[pos]  avg:
        # Begin signaal
        sig_start = pos
    if A[pos] > avg and A[pos+1] < avg:
        # Einde signaal
        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 resultaat krijgen we een reeks bits, in ons voorbeeld van twee seconden wordt het als volgt weergegeven:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Overigens is het interessant dat er ook een 'tweede laag' van gegevens in het signaal zit. De bitreeks is ook gecodeerd met behulp van fased modulatie. Theoretisch zou dit een meer robuuste decodering moeten garanderen, zelfs bij een verzwakt signaal.

Onze laatste stap: de eigenlijke gegevens verkrijgen. De bits worden ƩƩn keer per seconde verzonden, waardoor we in totaal 59 bits hebben die genoeg informatie coderen:
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

De bits worden beschreven in Wikipedia, en ze zijn vrij interessant. De eerste 15 bits worden niet gebruikt, hoewel er plannen waren om ze te gebruiken voor waarschuwingssystemen en civiele verdediging. Bit A1 geeft aan dat de klok in het volgende uur op zomer tijd zal worden gezet. Bit A2 geeft aan dat er in het volgende uur een extra seconde, die soms wordt gebruikt om de tijd aan te passen aan de rotatie van de aarde. De overige bits coderen uren, minuten, seconden en de datum.

DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Voor degenen die zelf willen experimenteren, is de code voor het decoderen hieronder in de spoiler.
Broncode

def decode(bits):
    if bits[0] != '0' or bits[20] != '1':
        return
    
    minuten, uren, dag_van_de_maand, weekdag, maand, jaar = map(convert_block,
                                                             (bits[21:28], bits[29:35], bits[36:42], bits[42:45],
                                                              bits[45:50], bits[50:58]))
    dagen = ('Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag')
    print('{dow}, {dom:02}.{mon:02}.{y}, {h:02}:{m:02}'.format(h=uren, m=minuten, dow=dagen[weekdag],
                                                               dom=dag_van_de_maand, mon=maand, y=jaar))


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)

Als we het programma uitvoeren, zullen we ongeveer deze output zien:

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

Dat is eigenlijk de hele magie. Het voordeel van dit systeem is dat het decoderen uiterst eenvoudig is, en kan worden gedaan op elke, zelfs de simpelste microcontroller. We tellen gewoon de duur van de pulsen, accumuleren 60 bits, en aan het einde van elke minuut krijgen we de exacte tijd. In vergelijking met andere methoden voor tijdsynchronisatie (bijvoorbeeld GPS, of erger nog, het internet :), vereist deze radiosynchronisatie praktisch geen energie — ter vergelijking, een gewone huishoudelijke weerstation werkt ongeveer een jaar op 2 AA-batterijen. Daarom worden zelfs polshorloges gemaakt met radiosynchronisatie, om nog maar te zwijgen van wand- of straatklokken.

Het gemak en de eenvoud van DCF trekt ook doe-het-zelfliefhebbers aan. Voor slechts 10-20$ kan je een kant-en-klaar module kopen met een antenne en een kant-en-klaar ontvanger met TTL-uitgang, die kan worden aangesloten op een Arduino of een andere controller.
DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Voor Arduino zijn al geschreven en bestaande bibliotheken. Het is echter al bekend — wat je ook doet met een microcontroller, het resultaat is altijd of een klok of een weerstation. Met zo'n apparaat is het echt niet moeilijk om de exacte tijd te krijgen, mits je je binnen het ontvangstgebied bevindt. En je kunt zelfs de klok de opschrift "Atomic Clock" geven, en uitleggen aan iedereen die het wil horen dat het apparaat daadwerkelijk gesynchroniseerd wordt met behulp van atoomklokken.

GeĆÆnteresseerden kunnen zelfs de oude klok van oma upgraden door een nieuw mechanisme met radiosynchronisatie te installeren:

DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?

Zo'n mechanisme is te vinden op ebay met de zoekwoorden "Radio Controlled Movement".

En tot slot, een hack voor degenen die tot hier hebben gelezen. Zelfs als er in de komende paar duizend kilometer geen enkele radiosignaalzender in de buurt is, is het niet moeilijk om zo'n signaal zelf te genereren. In de Google Play Store is er een programma genaamd "DCF77 Emulator" dat een signaal naar de hoofdtelefoon stuurt. Volgens de schrijver, als je de draad van de hoofdtelefoon om de klok wikkelt, zullen ze het signaal opvangen (interessant hoe, want gewone hoofdtelefoons zullen geen 77 kHz signaal uitzenden, maar waarschijnlijk komt de ontvangst door harmonischen). Ik kon het programma op mijn Android 9 helemaal niet laten werken — er was gewoon geen geluid (of misschien hoorde ik het niet — 77 kHz is immers:), maar misschien heeft iemand anders meer geluk. Sommigen maken trouwens ook een volledige DCF-signaalgenerator, die je eenvoudig kunt maken met dezelfde Arduino of ESP32:

DCF77: hoe werkt het systeem voor de overdracht van exacte tijdsignalen?
(bron sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Conclusie

Het DCF-systeem bleek echt vrij eenvoudig en handig te zijn. Met behulp van een eenvoudige en goedkope ontvanger heb je altijd en overal de exacte tijd, uiteraard in het ontvangstgebied. Ik denk dat, zelfs ondanks de wijdverspreide digitalisering en het "internet der dingen", zulke eenvoudige oplossingen nog lange tijd gewild blijven.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster