DCF77: Kako deluje sistem časovnega signala?

Pozdravljeni Habr.

Verjetno je marsikdo, ki je kupil uro ali vremensko postajo, na embalaži videl logotip radijsko vodene ure ali celo atomske ure. To je zelo priročno, saj morate samo postaviti uro na mizo in čez nekaj časa se bo samodejno prilagodila točnemu času.
DCF77: Kako deluje sistem časovnega signala?

Ugotovimo, kako deluje, in napišimo dekoder v Pythonu.

Obstajajo različni sistemi za sinhronizacijo časa. V Evropi je najbolj priljubljen nemški sistem DCF-77, Japonska ima svoj sistem JJY, v ZDA je sistem WWVB, in tako naprej. Nato bo zgodba o DCF77, kot najbolj ustreznem in dostopnem za sprejem v nekaterih krajih v evropskem delu Rusije in sosednjih državah (prebivalci Daljnega vzhoda imajo lahko nasprotno mnenje, vendar lahko prejmejo in analiziraj japonski signal;).

Vse spodaj napisano bo o DCF77.

Sprejem signala

DCF77 je dolgovalovna postaja, ki deluje na frekvenci 77.5 kHz in oddaja signale v amplitudni modulaciji. Postaja 50KW se nahaja 25 km od Frankfurta, obratovati je začela leta 1959, leta 1973 pa so točnemu času dodali datumski podatek. Valovna dolžina pri frekvenci 77 KHz je zelo dolga, zato so tudi dimenzije antenskega polja precej spodobne (fotografija iz Wikipedije):
DCF77: Kako deluje sistem časovnega signala?

S takšno anteno in vhodno močjo sprejemno območje pokriva skoraj vso Evropo, Belorusijo, Ukrajino in del Rusije.

DCF77: Kako deluje sistem časovnega signala?

Vsak lahko posname signal. Če želite to narediti, pojdite na spletni sprejemnik http://websdr.ewi.utwente.nl:8901/, tam izberite frekvenco 76.5 KHz in modulacijo USB. Odpreti se mora slika, ki izgleda nekako takole:

DCF77: Kako deluje sistem časovnega signala?

Tam pritisnemo gumb za prenos in posnamemo nekaj minut dolg fragment. Seveda, če imate "pravi" sprejemnik, ki lahko snema frekvenco 77.5 KHz, ga lahko uporabite.

Seveda s sprejemanjem radijskih časovnih signalov prek interneta ne bomo prejeli zares točnega časa - signal se prenaša z zamikom. Toda naš cilj je le razumeti strukturo signala, za to pa je internetni posnetek več kot dovolj. V resničnem življenju se za sprejem in dekodiranje seveda uporabljajo specializirane naprave, o katerih bomo razpravljali v nadaljevanju.

Tako, posnetek smo prejeli, začnimo z obdelavo.

Dekodiranje signala

Naložimo datoteko s Pythonom in si oglejmo njeno strukturo:

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

Vidimo tipično amplitudno modulacijo:
DCF77: Kako deluje sistem časovnega signala?

Za poenostavitev dekodiranja vzemimo ovojnico signala s Hilbertovo transformacijo:

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

Povečan rezultat:
DCF77: Kako deluje sistem časovnega signala?

Zgladimo emisije hrupa z uporabo nizkopasovnega filtra in hkrati izračunajmo povprečno vrednost, ki bo kasneje uporabna pri razčlenjevanju.

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

Rezultat (rumena črta): skoraj pravokotni signal, ki ga je precej enostavno analizirati.
DCF77: Kako deluje sistem časovnega signala?

Razčlenjevanje

Najprej morate dobiti zaporedje bitov. Sama struktura signala je zelo preprosta.
DCF77: Kako deluje sistem časovnega signala?

Impulzi so razdeljeni na sekundne intervale. Če je razdalja med impulzi 0.1 s (tj. dolžina samega impulza je 0.9 s), dodajte »0« zaporedju bitov; če je razdalja 0.2 s (tj. dolžina je 0.8 s), dodajte »1«. Konec vsake minute je označen z "dolgim" impulzom, dolgim ​​2 s, zaporedje bitov se ponastavi na nič in polnjenje se začne znova.

Zgoraj je enostavno napisati v Pythonu.

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

Kot rezultat dobimo zaporedje bitov, v našem primeru za dve sekundi izgleda takole:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Mimogrede, zanimivo je, da ima signal tudi "drugo plast" podatkov. Bitno zaporedje je tudi kodirano z uporabo fazna modulacija. Teoretično bi to moralo zagotoviti robustnejše dekodiranje tudi v primeru oslabljenega signala.

Naš zadnji korak: pridobivanje dejanskih podatkov. Biti se prenašajo enkrat na sekundo, tako da imamo skupno 59 bitov, v katerih je zakodiranih kar nekaj informacij:
DCF77: Kako deluje sistem časovnega signala?

Biti so opisani v Wikipedia, in so precej radovedni. Prvih 15 bitov se ne uporablja, čeprav so bili načrti, da bi jih uporabili za opozorilne sisteme in civilno zaščito. Bit A1 označuje, da se bo ura v naslednji uri preklopila na poletni čas. Bit A2 označuje, da je dodaten preskočna sekunda, ki se včasih uporablja za prilagajanje časa glede na vrtenje Zemlje. Preostali biti kodirajo ure, minute, sekunde in datum.

DCF77: Kako deluje sistem časovnega signala?

Za tiste, ki želijo eksperimentirati sami, je koda za dekodiranje navedena pod spojlerjem.
Izvorna koda

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)

Ko zaženemo program, bomo videli izpis, podoben temu:

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

Pravzaprav je to vsa čarovnija. Prednost takega sistema je v tem, da je dekodiranje izredno preprosto in ga lahko izvedemo na vsakem, še tako preprostem mikrokrmilniku. Preprosto preštejemo dolžino impulzov, zberemo 60 bitov in na koncu vsake minute dobimo točen čas. V primerjavi z drugimi načini časovne sinhronizacije (GPS, na primer, ali bog ne daj, internet:), takšna radijska sinhronizacija ne potrebuje skoraj nič elektrike - običajna domača vremenska postaja na primer deluje približno eno leto na 2 AA bateriji. Zato so tudi ročne ure izdelane z radijsko sinhronizacijo, da seveda ne omenjamo stenskih ur ali uličnih postajnih ur.

Priročnost in preprostost DCF pritegneta tudi ljubitelje DIY. Za samo 10-20 $ lahko kupite že pripravljen antenski modul z že pripravljenim sprejemnikom in TTL izhodom, ki ga lahko povežete z Arduino ali drugim krmilnikom.
DCF77: Kako deluje sistem časovnega signala?

Že napisano za Arduino že pripravljene knjižnice. Je pa že znano, da ne glede na to, kaj narediš na mikrokontrolerju, na koncu dobiš ali uro ali vremensko postajo. S tako napravo je pridobivanje točnega časa res enostavno, če ste seveda v recepciji. No, na uro lahko obesite napis "Atomska ura" in hkrati vsem razložite, da je naprava res sinhronizirana z atomsko uro.

Kdor želi, lahko svojo staro babičino uro celo nadgradi z namestitvijo novega mehanizma z radijsko sinhronizacijo:

DCF77: Kako deluje sistem časovnega signala?

Enega lahko najdete na ebayu s ključnimi besedami "Radio Controlled Movement".

In končno, življenjski trik za tiste, ki so prebrali do tukaj. Tudi če v naslednjih nekaj tisoč km ni nobenega oddajnika radijskega signala, takšnega signala ni težko ustvariti sam. V Googlu Play obstaja program, imenovan »DCF77 Emulator«, ki oddaja signal v slušalke. Po besedah ​​avtorja, če žico slušalk ovijete okoli ure, bodo le-te pobrale signal (zanimivo, kako, saj navadne slušalke ne bodo proizvedle 77KHz signala, ampak je sprejem verjetno posledica harmonikov). Na Androidu 9 mi program sploh ni delal - enostavno ni bilo zvoka (ali pa ga morda nisem slišal - navsezadnje je 77KHz :), mogoče pa bo imel kdo več sreče. Nekateri pa si naredijo polnopravni generator signala DCF, ki ga je enostavno narediti na istem Arduinu ali ESP32:

DCF77: Kako deluje sistem časovnega signala?
(vir sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Zaključek

Sistem DCF se je izkazal za zelo preprostega in priročnega. S pomočjo enostavnega in poceni sprejemnika imate točen čas vedno in povsod, seveda v recepciji. Zdi se, da bo kljub vsesplošni digitalizaciji in internetu stvari po takih preprostih rešitvah še dolgo povpraševanje.

Vir: www.habr.com

Dodaj komentar