Tere Habr.
Tõenäoliselt on paljud kella või ilmajaama soetajad näinud pakendil raadio teel juhitavat kella või isegi aatomikella logo. See on väga mugav, sest peate lihtsalt kella lauale panema ja mõne aja pärast kohandub see automaatselt täpse kellaajaga.

Mõelgem välja, kuidas see töötab, ja kirjutame Pythonis dekoodri.
Aja sünkroonimise süsteeme on erinevaid. Euroopas on kõige populaarsem Saksa süsteem , Jaapanis on oma süsteem , USA-s on süsteem , ja nii edasi. Järgmisena tuleb juttu DCF77-st, mis on kohati Venemaa Euroopa osas ja naaberriikides kõige asjakohasem ja vastuvõtvaim (Kaug-Ida elanikud võivad olla vastupidisel arvamusel, aga nemad saavad omakorda vastu võtta). ja analüüsida Jaapani signaali;).
Kõik allpool kirjutatud puudutab DCF77.
Signaali vastuvõtt
DCF77 on pikalainejaam, mis töötab sagedusel 77.5 kHz ja edastab signaale amplituudmodulatsioonis. 50KW jaam asub Frankfurdist 25 km kaugusel, see alustas tööd 1959. aastal ning 1973. aastal lisati täpsele kellaajale ka kuupäevainfo. Lainepikkus 77 KHz sagedusel on väga pikk, seega on ka antennivälja mõõtmed üsna korralikud (foto Wikipediast):

Sellise antenni ja toitesisendiga katab vastuvõtuala peaaegu kogu Euroopa, Valgevene, Ukraina ja osa Venemaast.

Igaüks saab signaali salvestada. Selleks minge lihtsalt võrgus olevale vastuvõtjale , valige seal sagedus 76.5KHz ja USB modulatsioon. Peaks avanema pilt, mis näeb välja umbes selline:

Seal vajutame allalaadimisnuppu ja salvestame mitme minuti pikkuse fragmendi. Muidugi, kui teil on "päris" vastuvõtja, mis suudab salvestada 77.5 kHz sagedust, saate seda kasutada.
Interneti kaudu raadioajasignaale vastu võttes ei saa me muidugi päris täpset aega – signaal edastatakse hilinemisega. Kuid meie eesmärk on mõista ainult signaali struktuuri, selleks on Interneti-salvestusest enam kui piisav. Reaalses elus kasutatakse vastuvõtmiseks ja dekodeerimiseks muidugi spetsiaalseid seadmeid, neid käsitletakse allpool.
Niisiis, oleme salvestise kätte saanud, hakkame seda töötlema.
Signaali dekodeerimine
Laadime faili Pythoni abil ja vaatame selle struktuuri:
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()
Näeme tüüpilist amplituudmodulatsiooni:

Dekodeerimise lihtsustamiseks võtame signaali mähisjoone Hilberti teisenduse abil:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Suurendatud tulemus:

Silume madalpääsfiltri abil müraemissioone ja arvutame samal ajal keskmise väärtuse, millest on hiljem parsimisel kasu.
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
Tulemus (kollane joon): peaaegu ruutlaine signaal, mida on üsna lihtne analüüsida.

Parsimine
Kõigepealt peate saama bitijärjestuse. Signaali struktuur ise on väga lihtne.

Impulssid on jagatud teiseks intervalliks. Kui impulsside vaheline kaugus on 0.1 s (st impulsi enda pikkus on 0.9 s), lisage bitijadale "0", kui kaugus on 0.2 s (st pikkus on 0.8 s), lisage "1". Iga minuti lõppu näitab 2 sekundi pikkune “pikk” impulss, bitijada lähtestatakse nullile ja täitmine algab uuesti.
Ülaltoodud on Pythonis lihtne kirjutada.
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
Selle tulemusel saame bittide jada, meie näites näeb see kahe sekundi jooksul välja järgmine:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Muide, on huvitav, et signaalil on ka "teine kiht". Bitijada kodeeritakse ka kasutades . Teoreetiliselt peaks see tagama tugevama dekodeerimise isegi nõrgenenud signaali korral.
Meie viimane samm: tegelike andmete hankimine. Bite edastatakse üks kord sekundis, seega on meil kokku 59 bitti, millesse on kodeeritud üsna palju teavet:

Bite on kirjeldatud artiklis , ja nad on üsna uudishimulikud. Esimesed 15 bitti ei kasutata, kuigi neid oli plaanis kasutada hoiatussüsteemide ja tsiviilkaitse jaoks. Bit A1 näitab, et kell lülitub järgmise tunni jooksul suveajale. Bit A2 näitab, et täiendav , mida mõnikord kasutatakse aja reguleerimiseks vastavalt Maa pöörlemisele. Ülejäänud bitid kodeerivad tunde, minuteid, sekundeid ja kuupäeva.

Neile, kes soovivad omal käel katsetada, on dekodeerimiskood antud spoileri all.
Lähtekood
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)
Kui käivitame programmi, näeme väljundit, mis on sarnane sellele:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Tegelikult on see kõik maagia. Sellise süsteemi eeliseks on see, et dekodeerimine on ülilihtne ja seda saab teha mis tahes, isegi kõige lihtsama mikrokontrolleriga. Lihtsalt loendame impulsside pikkuse, kogume 60 bitti ja iga minuti lõpus saame täpse aja. Võrreldes teiste aja sünkroniseerimise meetoditega (GPS näiteks või jumal hoidku Internet:), ei vaja selline raadiosünkroniseerimine praktiliselt üldse elektrit – näiteks tavaline kodune ilmajaam töötab umbes aasta 2 AA patareiga. Seetõttu tehakse raadiosünkroniseerimisega isegi käekellasid, rääkimata muidugi seina- või tänavajaamakelladest.
DCF-i mugavus ja lihtsus köidavad ka isetegemise entusiaste. Vaid 10-20 dollari eest saab osta valmis vastuvõtja ja TTL väljundiga valmis antennimooduli, mille saab ühendada Arduino või muu kontrolleriga.

Arduino jaoks juba kirjutatud . Küll aga on juba teada, et ükskõik, mida sa mikrokontrolleriga ka ei teeks, saad lõpuks kas kella või ilmajaama. Sellise seadmega on täpse aja kättesaamine tõesti lihtne, eeldusel muidugi, et oled vastuvõtualal. Noh, saate riputada oma kellale kirja “Aatomkell” ja samal ajal kõigile selgitada, et seade on tõesti aatomkella abil sünkroonitud.
Soovijad saavad oma vana vanaema käekella isegi uuendada, paigaldades uue raadiosünkroniseerimisega mehhanismi:

Selle leiate ebayst märksõnade "Radio Controlled Movement" abil.
Ja lõpuks elunipp neile, kes on siiani lugenud. Isegi kui paari tuhande kilomeetri raadiuses pole ühtegi raadiosaatjat, on lihtne see ise genereerida. Google Plays on rakendus nimega "DCF77 Emulator", mis saadab signaali kõrvaklappidesse. Autor väidab, et kui kõrvaklappide kaabel kella ümber keerata, siis see signaali üles võtab (huvitav, kuidas, kuna tavalised kõrvaklapid ei tekita 77 kHz signaali, aga see on ilmselt tingitud harmoonilistest). Minu kellal... Android Programm 9 ei töötanud üldse – lihtsalt polnud mingit heli (või äkki ma lihtsalt ei kuulnud seda – see on ju 77 kHz. :)), aga ehk kellelgi teisel veab rohkem. Mõned inimesed ehitavad aga oma täisväärtusliku DCF-signaaligeneraatori, mida on lihtne teha Arduino või ESP32 abil:

(allikas )
Järeldus
DCF-süsteem osutus tõesti üsna lihtsaks ja mugavaks. Lihtsa ja soodsa ressiiveri abil saad alati ja igal pool täpse kellaaja, loomulikult vastuvõtualal. Tundub, et isegi laialt levinud digitaliseerimisest ja asjade internetist hoolimata on selliste lihtsate lahenduste järele nõudlus veel kaua.
Allikas: www.habr.com
