Salam Habr.
Panginten seueur anu ngagaleuh arloji atanapi stasiun cuaca parantos ningali Jam Dikadalikeun Radio atanapi logo Jam Atom dina bungkusan. Ieu pohara merenah, sabab geus cukup pikeun nempatkeun jam dina méja, sarta sanggeus sababaraha waktu bakal otomatis nyaluyukeun kana waktu pasti.
Hayu urang terang kumaha gawéna sareng nyerat decoder dina Python.
Aya sistem sinkronisasi waktos anu béda. Nu pang populerna di Éropa nyaéta sistem Jerman
Sagalana ditulis di handap bakal ngeunaan DCF77.
panarimaan sinyal
DCF77 mangrupikeun stasiun gelombang panjang anu beroperasi dina 77.5KHz sareng ngirimkeun sinyal AM. Stasion kalayan kapasitas 50 kW perenahna 25 km ti Frankfurt, éta mimiti dianggo dina taun 1959, dina taun 1973 inpormasi ngeunaan tanggalna parantos ditambah kana waktos anu pas. Panjang gelombang dina frékuénsi 77 kHz kacida gedéna, jadi diménsi widang anteneu ogé pohara santun (poto ti Wikipedia):
Kalayan anteneu sareng kakuatan input sapertos kitu, daérah panarimaan nyertakeun ampir sadayana Éropa, Bélarus, Ukraina sareng bagian Rusia.
Saha waé tiasa ngarékam. Jang ngalampahkeun ieu, ngan buka panarima online
Di tempat anu sami, urang pencét tombol unduh sareng ngarékam sempalan salami sababaraha menit. Tangtu, lamun boga panarima "nyata" sanggup ngarekam frékuénsi 77.5 kHz, Anjeun bisa make eta.
Tangtosna, nalika nampi sinyal radio waktos anu akurat dina Internét, urang moal nampi waktos anu leres-leres - sinyalna dikirimkeun kalayan reureuh. Tapi tujuan urang ngan ukur ngartos struktur sinyal, pikeun ieu ngarékam Internét langkung ti cukup. Dina kahirupan nyata, tangtosna, alat khusus dianggo pikeun nampi sareng decoding, aranjeunna bakal dibahas di handap ieu.
Janten, urang nampi catetan, hayu urang ngamimitian ngolahna.
Decoding sinyal
Hayu urang muka file nganggo Python sareng tingali strukturna:
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()
Urang ningali modulasi amplitudo has:
Pikeun nyederhanakeun decoding, urang nyandak amplop sinyal nganggo transformasi Hilbert:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Hasil dimekarkeun:
Hayu urang halus kaluar émisi noise ngagunakeun low-pass filter, dina waktos anu sareng ngitung nilai rata, éta bakal datang dina gunana engké pikeun 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
Hasilna (garis konéng): sinyal ampir rectangular anu cukup gampang dianalisis.
Parsing
Kahiji maneh kudu meunang runtuyan bit. Struktur sinyal sorangan basajan pisan.
Pulsa dibagi kana interval kadua. Lamun jarak antara pulsa 0.1s (ie, panjang pulsa sorangan 0.9s), urang tambahkeun "0" kana runtuyan bit, lamun jarakna 0.2s (ie, panjangna 0.8s), urang tambahkeun. “1”. Ahir unggal menit dituduhkeun ku pulsa "panjang", 2 s lila, runtuyan bit reset ka enol, sarta ngeusian dimimitian deui.
Di luhur gampang ditulis dina 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
Hasilna, urang meunang runtuyan bit, dina conto urang salila dua detik kasampak kawas kieu:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Ku jalan kitu, éta metot nu aya ogé "lapisan kadua" data dina sinyal. Sekuen bit ogé disandikeun ku
Léngkah terakhir kami: kéngingkeun data anu saleresna. Bit dikirimkeun sakali per detik, janten urang ngan ukur gaduh 59 bit, dimana seueur inpormasi anu disandikeun:
Bit dijelaskeun dina
Pikeun maranéhanana anu rék ékspérimén sorangan, kode decoding dibikeun handapeun spoiler nu.
Kode sumber
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)
Ngajalankeun program, urang bakal ningali kaluaran sapertos kieu:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Sabenerna, éta kabéh magic. Kauntungannana sistem sapertos ieu nya éta decoding pisan basajan, sarta bisa dipigawé dina sagala mikrokontroler paling uncomplicated. Urang ngan ukur ngitung panjang pulsa, ngumpulkeun 60 bit, sareng dina tungtung unggal menit urang nampi waktos anu pas. Dibandingkeun sareng metode sinkronisasi waktos anu sanés (GPS, contona, atanapi Gusti nyaram, Internét :), sinkronisasi radio sapertos praktis henteu peryogi listrik - contona, stasiun cuaca bumi biasa dianggo sakitar sataun dina 2 batré AA. Ku alatan éta, malah wristwatches dijieun kalayan sinkronisasi radio, teu nyebut, tangtosna, jam témbok atawa jam stasiun jalan.
Genah sareng kesederhanaan DCF ogé narik para peminat DIY. Pikeun ngan $ 10-20, Anjeun bisa meuli modul anteneu siap-dijieun ku panarima siap-dijieun sarta kaluaran TTL nu bisa disambungkeun ka Arduino atawa controller séjén.
Pikeun Arduino geus ditulis na
Anu hoyong malah tiasa ningkatkeun jam tangan nini ku cara masang mékanisme énggal sareng sinkronisasi radio:
Anjeun tiasa mendakan hiji dina ebay nganggo kecap konci "Gerakan Dikadalikeun Radio".
Sarta pamustunganana, hack hirup pikeun maranéhanana anu geus maca ieu tebih. Sanaos henteu aya pemancar sinyal radio tunggal dina sababaraha sarébu kilométer salajengna, sinyal sapertos kitu gampang dibangkitkeun nyalira. Aya program dina Google Play disebut "DCF77 Émulator" nu outputs sinyal ka headphone. Numutkeun panulis, lamun mungkus kawat headphone sabudeureun jam, maranéhna bakal nyekel sinyal (Kuring heran kumaha, sabab headphone biasa moal masihan kaluar sinyal 77KHz, tapi meureun panarimaan alatan harmonik). Program éta henteu tiasa dianggo pikeun kuring dina Android 9 pisan - ngan saukur teu aya sora (atanapi panginten kuring henteu ngupingkeun - 77KHz, barina ogé :), tapi meureun batur bakal langkung untung. Sababaraha, kumaha oge, nyieun sorangan generator sinyal DCF full-fledged, nu gampang pikeun ngalakukeun dina Arduino sarua atawa ESP32:
(sumber
kacindekan
Sistim DCF tétéla bener cukup basajan tur merenah. Kalayan bantuan hiji panarima basajan tur murah, anjeun tiasa gaduh waktos pasti salawasna tur madhab, tangtu di wewengkon panarimaan. Sigana sanajan sanajan digitalisasi nyebar sareng "Internet of Things", solusi saderhana sapertos kitu bakal dipénta pikeun waktos anu lami.
sumber: www.habr.com