DCF77: hvordan fungerer tidssignalsystemet?

Hei Habr.

Sannsynligvis har mange som kjøper en klokke eller en værstasjon sett radiokontrollert klokke eller til og med Atomic Clock-logoen på emballasjen. Dette er veldig praktisk, fordi det er nok å sette klokken på bordet, og etter en stund vil den automatisk justere seg til den nøyaktige tiden.
DCF77: hvordan fungerer tidssignalsystemet?

La oss finne ut hvordan det fungerer og skrive en dekoder i Python.

Det finnes forskjellige tidssynkroniseringssystemer. Det mest populære i Europa er det tyske systemet DCF-77Japan har sitt eget system JJY, i USA er det et system WWVB, og så videre. Videre vil historien handle om DCF77, som den mest relevante og tilgjengelige for mottak noen steder i den europeiske delen av Russland og nabolandene (innbyggerne i Fjernøsten kan ha motsatt oppfatning, men de kan på sin side motta og analysere det japanske signalet;).

Alt som er skrevet nedenfor vil handle om DCF77.

Signalmottak

DCF77 er en langbølgestasjon som opererer ved 77.5KHz og sender AM-signaler. Stasjonen med en kapasitet på 50 kW ligger 25 km fra Frankfurt, den begynte å jobbe i 1959, i 1973 ble informasjon om datoen lagt til det nøyaktige klokkeslettet. Bølgelengden ved en frekvens på 77 kHz er veldig stor, så dimensjonene til antennefeltet er også veldig anstendige (foto fra Wikipedia):
DCF77: hvordan fungerer tidssignalsystemet?

Med en slik antenne og inngangskraft dekker mottaksområdet nesten hele Europa, Hviterussland, Ukraina og deler av Russland.

DCF77: hvordan fungerer tidssignalsystemet?

Hvem som helst kan ta opp. For å gjøre dette, bare gå til nettmottakeren http://websdr.ewi.utwente.nl:8901/, velg en frekvens på 76.5KHz og USB-modulasjon der. Et bilde skal vises omtrent slik:

DCF77: hvordan fungerer tidssignalsystemet?

På samme sted trykker vi på nedlastingsknappen og tar opp et fragment som er noen minutter langt. Selvfølgelig, hvis du har en "ekte" mottaker som er i stand til å ta opp en frekvens på 77.5 kHz, kan du bruke den.

Når vi mottar nøyaktige tidsradiosignaler over Internett, vil vi selvfølgelig ikke få en virkelig nøyaktig tid - signalet overføres med en forsinkelse. Men målet vårt er bare å forstå strukturen til signalet, for dette er internettopptaket mer enn nok. I det virkelige liv brukes selvfølgelig spesialiserte enheter for mottak og dekoding, de vil bli diskutert nedenfor.

Så vi mottok posten, la oss begynne å behandle den.

Signalavkoding

La oss laste filen med Python og se strukturen:

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()

Vi ser en typisk amplitudemodulasjon:
DCF77: hvordan fungerer tidssignalsystemet?

For å forenkle dekodingen tar vi signalkonvolutten ved å bruke Hilbert-transformasjonen:

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

Utvidet resultat:
DCF77: hvordan fungerer tidssignalsystemet?

La oss jevne ut støyutslipp ved hjelp av et lavpassfilter, samtidig beregne gjennomsnittsverdien, det vil komme godt med senere for 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

Resultat (gul linje): et nesten rektangulært signal som er ganske enkelt å analysere.
DCF77: hvordan fungerer tidssignalsystemet?

Parsing

Først må du få bitsekvensen. Selve signalstrukturen er veldig enkel.
DCF77: hvordan fungerer tidssignalsystemet?

Pulsene er delt inn i andre intervaller. Hvis avstanden mellom pulsene er 0.1 s (dvs. lengden på selve pulsen er 0.9 s), legger vi til "0" til bitsekvensen, hvis avstanden er 0.2 s (dvs. lengden er 0.8 s), legger vi til "1". Slutten av hvert minutt indikeres med en "lang" puls, 2 s lang, bitsekvensen tilbakestilles til null, og fyllingen starter på nytt.

Ovenstående er lett å skrive i Python.

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

        diff = sig_stop - sig_start
    
        if diff < 0.85*sample_rate:
            bits_str += "1"
        if diff > 0.85*sample_rate and diff < 1.25*sample_rate:
            bits_str += "0"
        if diff > 1.5*sample_rate:
            print(bits_str)
            bits_str = ""

    pos += 1

Som et resultat får vi en sekvens av biter, i vårt eksempel i to sekunder ser det slik ut:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Forresten, det er interessant at det også er et "andre lag" med data i signalet. Bitsekvensen er også kodet med fasemodulering. Teoretisk sett burde dette gi mer robust dekoding selv ved et svekket signal.

Vårt siste trinn: få de faktiske dataene. Bits sendes en gang per sekund, så vi har bare 59 biter, der ganske mye informasjon er kodet:
DCF77: hvordan fungerer tidssignalsystemet?

Bitene er beskrevet i Wikipediaog de er ganske nysgjerrige. De første 15 bitene blir ikke brukt, selv om det var planer om å bruke dem til høyttaler- og sivilforsvarssystemer. Bit A1 indikerer at klokken vil skifte til sommertid i løpet av den neste timen. Bit A2 indikerer at neste time vil bli lagt til et sprangsekund, som noen ganger brukes til å korrigere tiden i henhold til jordens rotasjon. De gjenværende bitene koder timer, minutter, sekunder og dato.

DCF77: hvordan fungerer tidssignalsystemet?

For de som ønsker å eksperimentere på egenhånd, er dekodingskoden gitt under spoileren.
Kildekode

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 = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
    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)

Når vi kjører programmet, vil vi se noe som denne utgangen:

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

Det er faktisk all magien. Fordelen med et slikt system er at dekodingen er ekstremt enkel, og kan gjøres på hvilken som helst, den mest ukompliserte mikrokontrolleren. Vi teller bare lengden på pulsene, akkumulerer 60 biter, og på slutten av hvert minutt får vi den nøyaktige tiden. Sammenlignet med andre metoder for tidssynkronisering (GPS, for eksempel, eller Gud forby, Internett :), krever slik radiosynkronisering praktisk talt ikke strøm - for eksempel fungerer en vanlig værstasjon i hjemmet i omtrent et år på 2 AA-batterier. Derfor er selv armbåndsur laget med radiosynkronisering, for ikke å snakke om, selvfølgelig, veggklokker eller gatestasjonsklokker.

Bekvemmeligheten og enkelheten til DCF tiltrekker også DIY-entusiaster. For kun $10-20 kan du kjøpe en ferdig antennemodul med en ferdig mottaker og en TTL-utgang som kan kobles til en Arduino eller annen kontroller.
DCF77: hvordan fungerer tidssignalsystemet?

For Arduino allerede skrevet og ferdige biblioteker. Det er imidlertid allerede kjent at uansett hva du gjør på mikrokontrolleren, får du enten en klokke eller en værstasjon. Med en slik enhet er det veldig enkelt å få nøyaktig tid, med mindre du selvfølgelig er i resepsjonsområdet. Vel, du kan henge påskriften "Atomic Clock" på klokken, og samtidig forklare alle at enheten virkelig er synkronisert ved hjelp av en atomklokke.

De som ønsker det kan til og med oppgradere den gamle bestemorklokken ved å installere en ny mekanisme med radiosynkronisering:

DCF77: hvordan fungerer tidssignalsystemet?

Du kan finne en på ebay ved å bruke søkeordene "Radio Controlled Movement".

Og til slutt, et life hack for de som har lest så langt. Selv om det ikke er en eneste radiosignalsender i løpet av de neste par tusen kilometerne, er et slikt signal enkelt å generere på egenhånd. Det er et program på Google Play kalt "DCF77 Emulator" som sender ut et signal til hodetelefonene. Ifølge forfatteren, hvis du pakker hodetelefonledningen døgnet rundt, vil de fange opp signalet (jeg lurer på hvordan, for vanlige hodetelefoner vil ikke gi ut et 77KHz-signal, men sannsynligvis skyldes mottaket harmoniske). Programmet fungerte ikke for meg på Android 9 i det hele tatt - det var rett og slett ingen lyd (eller kanskje jeg ikke hørte det - 77KHz, tross alt :), men kanskje noen vil være mer heldige. Noen gjør seg imidlertid til en fullverdig DCF-signalgenerator, som er lett å gjøre på samme Arduino eller ESP32:

DCF77: hvordan fungerer tidssignalsystemet?
(kilde sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Konklusjon

DCF-systemet viste seg å være ganske enkelt og praktisk. Ved hjelp av en enkel og billig mottaker kan du ha nøyaktig tid alltid og overalt, selvfølgelig i resepsjonsområdet. Det ser ut til at selv til tross for den utbredte digitaliseringen og «tingenes internett», vil slike enkle løsninger være etterspurt i lang tid fremover.

Kilde: www.habr.com

Legg til en kommentar