DCF77: Kako radi sistem vremenskog signala?

Zdravo Habr.

Vjerovatno su mnogi koji kupuju sat ili meteorološku stanicu vidjeli radio kontrolirani sat ili čak logotip atomskog sata na pakovanju. Ovo je vrlo zgodno, jer samo treba da stavite sat na sto, a nakon nekog vremena on će se automatski prilagoditi tačnom vremenu.
DCF77: Kako radi sistem vremenskog signala?

Hajde da shvatimo kako to radi i napišemo dekoder u Pythonu.

Postoje različiti sistemi za sinhronizaciju vremena. Najpopularniji u Evropi je njemački sistem DCF-77, Japan ima svoj sistem JJY, u SAD postoji sistem WWVB, i tako dalje. Dalje, priča će biti o DCF77, kao najrelevantnijem i najpristupačnijem za prijem u nekim mjestima u evropskom dijelu Rusije i susjednih zemalja (stanovnici Dalekog istoka mogu imati suprotno mišljenje, međutim, oni zauzvrat mogu primiti i analizirati japanski signal;).

Sve napisano u nastavku bit će o DCF77.

Prijem signala

DCF77 je dugovalna stanica koja radi na frekvenciji od 77.5 kHz i emituje signale u amplitudnoj modulaciji. Stanica od 50KW nalazi se 25 km od Frankfurta, počela je sa radom 1959. godine, a 1973. godine dodana je informacija o tačnom vremenu. Talasna dužina na frekvenciji od 77 KHz je veoma duga, tako da su i dimenzije antenskog polja sasvim pristojne (fotografija sa Wikipedije):
DCF77: Kako radi sistem vremenskog signala?

Sa takvom antenom i ulazom za napajanje, prijemno područje pokriva gotovo cijelu Evropu, Bjelorusiju, Ukrajinu i dio Rusije.

DCF77: Kako radi sistem vremenskog signala?

Svako može snimiti signal. Da biste to učinili, samo idite na mrežni prijemnik http://websdr.ewi.utwente.nl:8901/, tamo odaberite frekvenciju 76.5KHz i USB modulaciju. Trebalo bi da se otvori slika koja izgleda otprilike ovako:

DCF77: Kako radi sistem vremenskog signala?

Tamo pritisnemo dugme za preuzimanje i snimimo fragment dug nekoliko minuta. Naravno, ako imate “pravi” prijemnik koji može snimiti frekvenciju od 77.5 KHz, možete to koristiti.

Naravno, primanjem radio signala vremena putem interneta, nećemo dobiti istinski tačno vrijeme - signal se prenosi sa zakašnjenjem. Ali naš cilj je samo razumjeti strukturu signala, za to je više nego dovoljan internet snimak. U stvarnom životu, naravno, za prijem i dekodiranje koriste se specijalizirani uređaji, o njima će biti riječi u nastavku.

Dakle, primili smo snimak, hajde da ga obradimo.

Signal Decoding

Učitajmo datoteku koristeći Python i vidimo njenu strukturu:

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čnu amplitudnu modulaciju:
DCF77: Kako radi sistem vremenskog signala?

Da pojednostavimo dekodiranje, uzmimo omotnicu signala koristeći Hilbertovu transformaciju:

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

Uvećani rezultat:
DCF77: Kako radi sistem vremenskog signala?

Hajde da izgladimo emisije buke pomoću niskopropusnog filtera, a u isto vrijeme izračunamo prosječnu vrijednost, što će nam kasnije biti od koristi za raščlanjivanje.

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 (žuta linija): signal gotovo pravokutnog talasa koji je prilično lako analizirati.
DCF77: Kako radi sistem vremenskog signala?

Parsing

Prvo morate dobiti sekvencu bitova. Sama struktura signala je vrlo jednostavna.
DCF77: Kako radi sistem vremenskog signala?

Impulsi su podijeljeni u sekundarne intervale. Ako je razmak između impulsa 0.1s (tj. dužina samog impulsa je 0.9s), dodajte "0" sekvenci bitova; ako je udaljenost 0.2s (tj. dužina je 0.8s), dodajte "1". Kraj svake minute je označen “dugim” impulsom, dugim 2s, sekvenca bitova se resetuje na nulu i punjenje počinje ponovo.

Gore je lako napisati u 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

Kao rezultat, dobijamo niz bitova, u našem primjeru za dvije sekunde to izgleda ovako:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Inače, zanimljivo je da signal ima i "drugi sloj" podataka. Slijed bitova je također kodiran pomoću fazna modulacija. U teoriji, ovo bi trebalo da obezbedi robusnije dekodiranje čak i u slučaju oslabljenog signala.

Naš posljednji korak: dobivanje stvarnih podataka. Bitovi se prenose jednom u sekundi, tako da imamo ukupno 59 bitova, u kojima je kodirano dosta informacija:
DCF77: Kako radi sistem vremenskog signala?

Bitovi su opisani u Wikipedia, i prilično su radoznali. Prvih 15 bitova se ne koristi, iako je bilo planova da se koriste za sisteme upozorenja i civilnu odbranu. Bit A1 označava da će se sat promijeniti na ljetno računanje vremena u sljedećem satu. Bit A2 označava da je dodatni skok drugi, koji se ponekad koristi za podešavanje vremena prema Zemljinoj rotaciji. Preostali bitovi kodiraju sate, minute, sekunde i datum.

DCF77: Kako radi sistem vremenskog signala?

Za one koji žele sami eksperimentirati, kod za dekodiranje je dat ispod spojlera.
Izvor

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)

Kada pokrenemo program, vidjet ćemo izlaz sličan ovome:

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

Zapravo, to je sva magija. Prednost ovakvog sistema je što je dekodiranje izuzetno jednostavno i može se obaviti na bilo kom, pa i najjednostavnijem mikrokontroleru. Jednostavno brojimo dužinu impulsa, akumuliramo 60 bita i na kraju svake minute dobijamo tačno vrijeme. U poređenju sa drugim metodama vremenske sinhronizacije (GPS, na primer, ili ne daj Bože, Internet:), za takvu radio sinhronizaciju nije potrebna praktički nikakva struja - na primer, obična kućna meteorološka stanica radi oko godinu dana na 2 AA baterije. Stoga se čak i ručni satovi prave sa radio sinhronizacijom, a da ne spominjemo, naravno, zidne satove ili satove uličnih stanica.

Pogodnost i jednostavnost DCF-a također privlače DIY entuzijaste. Za samo 10-20 dolara možete kupiti gotov antenski modul sa gotovim prijemnikom i TTL izlazom, koji se može spojiti na Arduino ili drugi kontroler.
DCF77: Kako radi sistem vremenskog signala?

Već napisano za Arduino gotove biblioteke. Međutim, već je poznato da bez obzira šta radite na mikrokontroleru, na kraju imate ili sat ili meteorološku stanicu. Sa takvim uređajem je zaista lako doći do tačnog vremena, pod uslovom, naravno, da se nalazite u zoni recepcije. Pa, možete okačiti natpis "Atomski sat" na svoj sat, i istovremeno svima objasniti da je uređaj zaista sinhronizovan pomoću atomskog sata.

Oni koji žele mogu čak i nadograditi stari bakin sat ugradnjom novog mehanizma sa radio sinhronizacijom:

DCF77: Kako radi sistem vremenskog signala?

Možete ga pronaći na ebayu koristeći ključne riječi “Radio Controlled Movement”.

I na kraju, lajf hak za one koji su čitali dovde. Čak i ako u sljedećih nekoliko hiljada km nema niti jednog odašiljača radio signala, nije teško sami generirati takav signal. Na Google Play-u postoji program pod nazivom “DCF77 Emulator” koji šalje signal u slušalice. Prema autoru, ako omotate žicu slušalica oko sata, one će uhvatiti signal (zanimljivo je kako, jer obične slušalice neće proizvoditi 77KHz signal, već je prijem vjerovatno zbog harmonika). Na Androidu 9 meni program uopće nije radio - jednostavno nije bilo zvuka (ili ga možda nisam čuo - ipak je 77KHz :)), ali možda će neko imati više sreće. Neki, međutim, prave sebi potpuni generator DCF signala, koji je lako napraviti na istom Arduinu ili ESP32:

DCF77: Kako radi sistem vremenskog signala?
(izvor sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

zaključak

Pokazalo se da je DCF sistem zaista prilično jednostavan i praktičan. Uz pomoć jednostavnog i jeftinog prijemnika možete imati tačno vrijeme uvijek i svugdje, naravno na recepciji. Čini se da će čak i uprkos raširenoj digitalizaciji i Internetu stvari, ovakva jednostavna rješenja biti tražena još dugo.

izvor: www.habr.com

Dodajte komentar