Habari Habr.
Huenda wengi wanaonunua saa au kituo cha hali ya hewa wameona nembo ya Saa Inayodhibitiwa ya Redio au hata nembo ya Saa ya Atomiki kwenye kifungashio. Hii ni rahisi sana, kwa sababu unahitaji tu kuweka saa kwenye meza, na baada ya muda itarekebisha moja kwa moja kwa wakati halisi.
Wacha tuone jinsi inavyofanya kazi na tuandike decoder huko Python.
Kuna mifumo tofauti ya ulandanishi wa wakati. Maarufu zaidi katika Ulaya ni mfumo wa Ujerumani
Kila kitu kilichoandikwa hapa chini kitakuwa kuhusu DCF77.
Mapokezi ya ishara
DCF77 ni kituo cha mawimbi marefu kinachofanya kazi kwa mzunguko wa 77.5 kHz na kusambaza ishara katika urekebishaji wa amplitude. Kituo cha 50KW kiko kilomita 25 kutoka Frankfurt, kilianza kufanya kazi mnamo 1959, na mnamo 1973 habari ya tarehe iliongezwa kwa wakati halisi. Urefu wa mawimbi kwa mzunguko wa 77 KHz ni mrefu sana, kwa hivyo vipimo vya uwanja wa antena pia ni bora (picha kutoka Wikipedia):
Kwa antenna hiyo na pembejeo ya nguvu, eneo la mapokezi linashughulikia karibu Ulaya yote, Belarus, Ukraine na sehemu ya Urusi.
Mtu yeyote anaweza kurekodi ishara. Ili kufanya hivyo, nenda tu kwa mpokeaji mtandaoni
Huko tunabonyeza kitufe cha kupakua na kurekodi kipande kwa dakika kadhaa. Bila shaka, ikiwa una kipokeaji "halisi" chenye uwezo wa kurekodi mzunguko wa 77.5KHz, unaweza kutumia hiyo.
Bila shaka, kwa kupokea ishara za wakati wa redio kupitia mtandao, hatutapokea wakati sahihi - ishara hupitishwa kwa kuchelewa. Lakini lengo letu ni kuelewa tu muundo wa ishara; kwa hili, kurekodi mtandao ni zaidi ya kutosha. Katika maisha halisi, kwa kweli, vifaa maalum hutumiwa kupokea na kusimbua; watajadiliwa hapa chini.
Kwa hivyo, tumepokea rekodi, wacha tuanze kuichakata.
Usimbuaji wa Mawimbi
Wacha tupakie faili kwa kutumia Python na tuone muundo wake:
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()
Tunaona urekebishaji wa kawaida wa amplitude:
Ili kurahisisha usimbaji, wacha tuchukue bahasha ya mawimbi kwa kutumia kibadilishaji cha Hilbert:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Matokeo yaliyopanuliwa:
Hebu tupunguze uzalishaji wa kelele kwa kutumia chujio cha chini, na wakati huo huo tuhesabu thamani ya wastani, ambayo itakuwa muhimu baadaye kwa uchanganuzi.
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
Tokeo (mstari wa manjano): mawimbi karibu ya mraba ambayo ni rahisi kuchanganua.
Kuchanganua
Kwanza unahitaji kupata mlolongo kidogo. Muundo wa ishara yenyewe ni rahisi sana.
Mapigo yanagawanywa katika vipindi vya pili. Ikiwa umbali kati ya mipigo ni 0.1s (yaani urefu wa mpigo yenyewe ni 0.9), ongeza "0" kwenye mlolongo wa biti; ikiwa umbali ni 0.2s (yaani urefu ni 0.8s), ongeza "1". Mwisho wa kila dakika unaonyeshwa na pigo la "muda mrefu", 2s kwa muda mrefu, mlolongo wa kidogo umewekwa upya hadi sifuri, na kujaza huanza tena.
Hapo juu ni rahisi kuandika katika 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
Kama matokeo, tunapata mlolongo wa bits, kwa mfano wetu kwa sekunde mbili inaonekana kama hii:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Kwa njia, ni ya kuvutia kwamba ishara pia ina "safu ya pili" ya data. Mlolongo kidogo pia umesimbwa kwa kutumia
Hatua yetu ya mwisho: kupata data halisi. Biti hupitishwa mara moja kwa sekunde, kwa hivyo tunayo jumla ya biti 59, ambazo habari nyingi husimbwa:
Viungo vimeelezewa ndani
Kwa wale ambao wanataka kujaribu wenyewe, msimbo wa decoding hutolewa chini ya spoiler.
Msimbo wa chanzo
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)
Tunapoendesha programu, tutaona matokeo sawa na haya:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Kweli, hiyo ni uchawi wote. Faida ya mfumo kama huo ni kwamba kuweka rekodi ni rahisi sana na inaweza kufanywa kwa yoyote, hata kidhibiti kidogo rahisi. Tunahesabu tu urefu wa mapigo, kujilimbikiza bits 60, na mwisho wa kila dakika tunapata wakati halisi. Ikilinganishwa na njia zingine za maingiliano ya wakati (GPS, kwa mfano, au Hasha, Mtandao :), maingiliano ya redio kama haya hayahitaji umeme - kwa mfano, kituo cha hali ya hewa ya nyumbani huendesha kwa karibu mwaka kwa betri 2 za AA. Kwa hiyo, hata saa za mikono zinafanywa na maingiliano ya redio, bila kutaja, bila shaka, kuona za ukuta au saa za kituo cha mitaani.
Urahisi na urahisi wa DCF pia huvutia wapenda DIY. Kwa $ 10-20 tu unaweza kununua moduli ya antenna iliyopangwa tayari na mpokeaji tayari na pato la TTL, ambalo linaweza kushikamana na Arduino au mtawala mwingine.
Tayari imeandikwa kwa Arduino
Wale wanaotaka wanaweza hata kuboresha saa ya bibi yao wa zamani kwa kusakinisha utaratibu mpya na maingiliano ya redio:
Unaweza kupata moja kwenye ebay kwa kutumia maneno muhimu "Radio Controlled Movement".
Na mwishowe, utapeli wa maisha kwa wale ambao wamesoma hadi sasa. Hata ikiwa hakuna kipeperushi kimoja cha ishara ya redio katika kilomita elfu kadhaa zinazofuata, sio ngumu kutoa ishara kama hiyo mwenyewe. Kuna programu kwenye Google Play inayoitwa "DCF77 Emulator" ambayo hutoa mawimbi kwa vipokea sauti vinavyobanwa kichwani. Kulingana na mwandishi, ikiwa utafunga waya wa vichwa vya sauti karibu na saa, watachukua ishara (inafurahisha jinsi gani, kwa sababu vichwa vya sauti vya kawaida havitatoa ishara ya 77KHz, lakini mapokezi labda ni kwa sababu ya maelewano). Kwenye Android 9, programu haikufanya kazi kabisa kwangu - hakukuwa na sauti (au labda sikuisikia - ni 77KHz, baada ya yote :), lakini labda mtu atakuwa na bahati nzuri. Wengine, hata hivyo, hujitengenezea jenereta kamili ya ishara ya DCF, ambayo ni rahisi kutengeneza kwenye Arduino sawa au ESP32:
(chanzo
Hitimisho
Mfumo wa DCF uligeuka kuwa rahisi sana na rahisi. Kwa msaada wa mpokeaji rahisi na wa bei nafuu, unaweza kuwa na wakati halisi daima na kila mahali, bila shaka katika eneo la mapokezi. Inaonekana kwamba hata licha ya kuenea kwa dijiti na Mtandao wa Vitu, suluhisho rahisi kama hizo zitakuwa na mahitaji kwa muda mrefu.
Chanzo: mapenzi.com