Sugeng Habr.
Mbokmenawa akeh sing tuku jam tangan utawa stasiun cuaca wis ndeleng Jam Kontrol Radio utawa logo Jam Atom ing kemasan. Iki trep banget, amarga sampeyan mung kudu nyelehake jam ing meja, lan sawise sawetara wektu bakal kanthi otomatis nyetel wektu sing tepat.

Ayo ngerteni cara kerjane lan nulis decoder ing Python.
Ana macem-macem sistem sinkronisasi wektu. Sing paling populer ing Eropa yaiku sistem Jerman , Jepang duwe sistem dhewe , ing AS ana sistem , lan sapanunggalane. Sabanjure, crita bakal babagan DCF77, minangka sing paling relevan lan bisa diakses kanggo resepsi ing sawetara panggonan ing bagean Eropa Rusia lan negara-negara tanggane (penduduk Timur Jauh bisa uga duwe pendapat sing ngelawan, nanging, dheweke uga bisa nampa. lan nganalisa sinyal Jepang;).
Kabeh sing ditulis ing ngisor iki bakal dadi babagan DCF77.
Resepsi sinyal
DCF77 minangka stasiun gelombang dawa sing beroperasi kanthi frekuensi 77.5 kHz lan ngirim sinyal kanthi modulasi amplitudo. Stasiun 50KW dumunung 25 km saka Frankfurt, wiwit operasi ing 1959, lan ing 1973 informasi tanggal ditambahake kanggo wektu pas. Dawane gelombang kanthi frekuensi 77 KHz dawa banget, mula dimensi antena uga cukup prayoga (foto saka Wikipedia):

Kanthi antena lan input daya, area resepsi nyakup meh kabeh Eropa, Belarus, Ukraina lan bagean Rusia.

Sapa wae bisa ngrekam sinyal. Kanggo nindakake iki, mung pindhah menyang panrima online , pilih frekuensi 76.5KHz lan modulasi USB ana. Gambar kudu mbukak sing katon kaya iki:

Ing kana kita pencet tombol download lan ngrekam fragmen sawetara menit. Mesthi, yen sampeyan duwe panrima "nyata" sing bisa ngrekam frekuensi 77.5KHz, sampeyan bisa nggunakake.
Mesthine, kanthi nampa sinyal wektu radio liwat Internet, kita ora bakal nampa wektu sing bener-bener akurat - sinyal kasebut ditularake kanthi wektu tundha. Nanging tujuane mung kanggo ngerti struktur sinyal kasebut, kanggo iki, rekaman Internet luwih saka cukup. Ing urip nyata, mesthi, piranti khusus digunakake kanggo nampa lan dekoding, padha bakal rembugan ing ngisor iki.
Dadi, wis entuk rekaman, ayo diproses.
Decoding sinyal
Ayo mbukak file nggunakake Python lan ndeleng strukture:
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()
Kita ndeleng modulasi amplitudo khas:

Kanggo nyederhanakake dekoding, ayo njupuk amplop sinyal nggunakake transformasi Hilbert:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000]) Hasil nggedhekake:

Ayo dadi lancar metu emisi swara nggunakake saringan low-pass, lan ing wektu sing padha ngetung nilai rata-rata, kang bakal migunani mengko kanggo 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 Asil (garis kuning): sinyal gelombang meh persegi sing cukup gampang dianalisis.

Parsing
Pisanan sampeyan kudu njaluk urutan bit. Struktur sinyal dhewe banget prasaja.

Pulsa dipérang dadi interval kapindho. Yen jarak antarane pulsa yaiku 0.1 detik (yaiku dawane pulsa dhewe yaiku 0.9 detik), tambahake "0" menyang urutan bit; yen jarake 0.2 detik (yaiku dawane 0.8 detik), tambahake "1". Pungkasan saben menit dituduhake kanthi pulsa "dawa", 2s dawa, urutan bit direset menyang nul, lan ngisi diwiwiti maneh.
Ing ndhuwur iku gampang kanggo nulis ing 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
Akibaté, kita entuk urutan bit, ing conto kita sajrone rong detik katon kaya iki:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Miturut cara, iku menarik yen sinyal uga duwe "lapisan kapindho" data. Urutan bit uga dienkode nggunakake . Ing teori, iki kudu nyedhiyakake dekoding sing luwih kuat sanajan ana sinyal sing saya ringkih.
Langkah pungkasan kita: njupuk data nyata. Bit ditularake sapisan saben detik, dadi kita duwe total 59 bit, sing cukup akeh informasi sing dikode:

Bit diterangake ing , lan padha cukup penasaran. 15 bit pisanan ora digunakake, sanajan ana rencana kanggo nggunakake sistem peringatan lan pertahanan sipil. Bit A1 nuduhake yen jam bakal ganti dadi wektu awan ing jam sabanjure. Bit A2 nuduhake yen tambahan , sing kadhangkala digunakake kanggo nyetel wektu miturut rotasi bumi. Bit sing isih ana encode jam, menit, detik lan tanggal.

Kanggo sing pengin eksprimen dhewe, kode dekoding diwenehi ing spoiler.
Sumber kode
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)
Nalika kita mbukak program, kita bakal weruh output kaya iki:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Bener, iku kabeh sihir. Kauntungan saka sistem kasebut yaiku dekoding banget prasaja lan bisa ditindakake ing sembarang mikrokontroler, malah sing paling gampang. Kita mung ngetung dawa pulsa, nglumpukake 60 bit, lan ing pungkasan saben menit entuk wektu sing tepat. Dibandhingake karo cara liyane sinkronisasi wektu (GPS, contone, utawa Gusti Allah ngalang-alangi, Internet :)), sinkronisasi radio kuwi sakbenere ora mbutuhake listrik - contone, stasiun cuaca ngarep biasa mlaku kanggo bab setahun ing 2 baterei AA. Mulane, malah jam tangan digawe kanthi sinkronisasi radio, ora kanggo sebutno, mesthi, jam tangan tembok utawa jam tangan stasiun jalanan.
Penak lan kesederhanaan DCF uga narik kawigaten para penggemar DIY. Mung $ 10-20 sampeyan bisa tuku modul antena siap-digawe karo panrima siap-digawe lan output TTL, kang bisa disambungake menyang Arduino utawa controller liyane.

Wis ditulis kanggo Arduino . Nanging, wis dingerteni manawa apa wae sing ditindakake ing mikrokontroler, sampeyan bakal entuk jam utawa stasiun cuaca. Kanthi piranti kasebut, entuk wektu sing tepat pancen gampang, mesthine sampeyan ana ing area resepsi. Inggih, sampeyan bisa nyumerepi prasasti "Jam Atom" ing jam tangan sampeyan, lan ing wektu sing padha nerangake marang kabeh wong manawa piranti kasebut pancen disinkronake nggunakake jam atom.
Sing pengin malah bisa nganyarke jam tangan mbah putri lawas kanthi nginstal mekanisme anyar kanthi sinkronisasi radio:

Sampeyan bisa nemokake siji ing ebay nggunakake tembung kunci "Gerakan Kontrol Radio".
Lan pungkasanipun, trik urip kanggo sing wis maca nganti tekan kene. Sanajan ora ana siji pemancar radio ing jarak sawetara ewu kilometer, gampang banget kanggo nggawe dhewe. Ana aplikasi ing Google Play sing diarani "DCF77 Emulator" sing ngasilake sinyal menyang headphone. Penulis ngaku yen sampeyan mbungkus kabel headphone ing jam tangan, bakal njupuk sinyal kasebut (Aku kepingin weruh kepiye, amarga headphone biasa ora bakal ngasilake sinyal 77 kHz, nanging mbokmenawa amarga harmonik). Ing jam tanganku... Android Program 9 ora bisa digunakake babar pisan—mung ora ana swara (utawa mungkin aku ora bisa krungu—frekuensine 77 kHz. :)), nanging mungkin wong liya bakal luwih begja. Nanging, ana wong sing nggawe generator sinyal DCF dhewe sing lengkap, sing gampang digawe nggunakake Arduino utawa ESP32:

(sumber )
kesimpulan
Sistem DCF ternyata pancen prasaja lan trep. Kanthi bantuan saka panrima prasaja lan mirah, sampeyan bisa duwe wektu pas tansah lan nang endi wae, mesthi ing wilayah reception. Kayane sanajan digitalisasi lan Internet of Things nyebar, solusi sing gampang kaya ngono bakal dikarepake suwe.
Source: www.habr.com
