Silav Habr.
Dibe ku gelek kesên ku demjimêrek an qereqolek hewayê bikirin, li ser pakêtê demjimêra Kontrolkirî ya Radyoyê an tewra logoya Saeta Atomî jî dîtine. Ev pir hêsan e, ji ber ku hûn tenê hewce ne ku demjimêrê deynin ser maseyê, û piştî demekê ew ê bixweber li gorî wextê rast rast bike.
Ka em fêr bibin ka ew çawa dixebite û di Python de dekoderek binivîsin.
Pergalên hevdengkirina demê yên cûda hene. Li Ewropayê ya herî populer sîstema Alman e
Her tiştê ku li jêr hatî nivîsandin dê li ser DCF77 be.
wergirtina sînyala
DCF77 stasyonek pêla dirêj e ku bi frekansa 77.5 kHz dixebite û di modulasyona amplitudê de îşaretan dişîne. Stasyona 50 KW 25 km dûrî Frankfurtê ye, di sala 1959 de dest bi xebatê kir û di sala 1973 de agahdariya tarîxê li dema rast hate zêdekirin. Dirêjahiya pêlê li frekansa 77 KHz pir dirêj e, ji ber vê yekê pîvanên qada antenna jî pir maqûl in (wêne ji Wîkîpediya):
Bi vî rengî antenna û têketina hêzê, qada pêşwaziyê hema hema hemî Ewrûpa, Belarus, Ukrayna û beşek ji Rûsyayê vedigire.
Her kes dikare sînyalek tomar bike. Ji bo vê yekê, tenê biçin wergirê serhêl
Li wir em pêl bişkoka dakêşanê dikin û perçeyek çend hûrdeman tomar dikin. Bê guman, heke we wergirek "rast" heye ku bikaribe frekansa 77.5KHz tomar bike, hûn dikarin wê bikar bînin.
Bê guman, bi wergirtina îşaretên dema radyoyê bi riya Înternetê, em ê wextê rast rast wernegirin - îşaret bi dereng tê veguheztin. Lê mebesta me tenê ew e ku em avahiya sînyalê fam bikin; ji bo vê yekê, tomarkirina Înternetê ji têrtir e. Di jiyana rast de, bê guman, amûrên pispor ji bo wergirtin û şîfrekirinê têne bikar anîn; ew ê li jêr werin nîqaş kirin.
Ji ber vê yekê, me tomar wergirt, em dest bi pêvajoyê bikin.
Deşîfrekirina sînyala
Ka em pelê bi karanîna Python bar bikin û avahiya wê bibînin:
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()
Em modulasyona amplitude ya tîpîk dibînin:
Ji bo hêsankirina dekodkirinê, em zerfa nîşanê bi karanîna veguherîna Hilbert bigirin:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Encama mezinkirî:
Werin em bi karanîna parzûnek nizm-derbasê emîsyonên deng xweş bikin, û di heman demê de nirxa navîn hesab bikin, ku dê paşê ji bo parskirinê bikêr be.
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
Encam (xeta zer): sînyalek pêla hema çargoşe ku analîzkirina wê pir hêsan e.
Parsing
Pêşî hûn hewce ne ku rêza bit bigirin. Struktura sînyala xwe pir hêsan e.
Pîlan di navberên duyemîn de têne dabeş kirin. Ger dûrahiya di navbera pêlşan de 0.1 s be (ango dirêjahiya pêlê bi xwe 0.9 s e), "0" li rêza bit-ê lê zêde bike; heke dûrahî 0.2 s be (ango dirêjahî 0.8 s be), "1" lê zêde bike. Dawiya her deqîqê bi pêlekek "dirêj" tê destnîşan kirin, 2s dirêj, rêza bit ji sifirê tê vegerandin, û dagirtin dîsa dest pê dike.
Li jor nivîsandina li Python hêsan e.
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
Wekî encamek, em rêzek bits distînin, di mînaka me de ji bo du çirkeyan wiha xuya dike:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Bi awayê, balkêş e ku sînyala di heman demê de "qata duyemîn" ya daneyê jî heye. Rêzeya bit jî bi kar tê kodkirin
Pêngava meya paşîn: bidestxistina daneyên rastîn. Bit di çirkeyê de carekê têne şandin, ji ber vê yekê me bi tevahî 59 bit hene, ku tê de gelek agahdarî têne kod kirin:
Bit di nav de têne diyar kirin
Ji bo kesên ku dixwazin bi tena serê xwe ceribandinê bikin, koda deşîfrekirinê di binê spoilerê de tê dayîn.
Koda çavkaniyê
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)
Dema ku em bernameyê dimeşînin, em ê encamek bi vî rengî bibînin:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Bi rastî, ev hemî sêrbaz e. Feydeya pergalek wusa ev e ku deşîfrekirin zehf hêsan e û dikare li ser her, tewra mîkrokontrolkerê herî hêsan jî were kirin. Em bi tenê dirêjahiya pêlan dihejmêrin, 60 bit berhev dikin, û di dawiya her hûrdemê de em wextê rast distînin. Li gorî awayên din ên hevdengkirina demê (mînak, GPS, an Xwedê nehêle, Înternetê :), hevdengkirina radyoyê bi rastî bê elektrîkê hewce dike - mînakî, stasyonek hewayê ya malê ya birêkûpêk bi qasî salekê li ser 2 bataryayên AA-yê dixebite. Ji ber vê yekê, tewra demjimêrên destan jî bi hevdemkirina radyoyê têne çêkirin, nebêjin, bê guman, demjimêrên dîwar an demjimêrên stasyona kolanan.
Rehetî û sadebûna DCF di heman demê de dilxwazên DIY-ê jî dikişîne. Bi tenê 10-20 $ hûn dikarin modulek antenna amadekirî bi wergirek amade û derana TTL-ê bikirin, ku dikare bi Arduino an kontrolkerek din ve were girêdan.
Jixwe ji bo Arduino hatî nivîsandin
Kesên ku bixwazin dikarin saeta dapîra xwe ya kevn jî bi sazkirina mekanîzmayek nû ya bi hevdemkirina radyoyê nûve bikin:
Hûn dikarin yek li ser ebay-ê bi karanîna keywords "Tevgera Kontrolkirî ya Radyoyê" bibînin.
Û di dawiyê de, hackek jiyanê ji bo kesên ku heta niha xwendine. Tewra ku di çend hezar km pêş de yek veguhezkarek sînyala radyoyê tune be jî, ne dijwar e ku meriv bi xwe sînyalek wusa çêbike. Li ser Google Playê bernameyeke bi navê “DCF77 Emulator” heye ku sînyalê derdixe guhê. Li gorî nivîskar, ger hûn têla guhêran li dora demjimêrê bipêçin, ew ê sînyalê hildin (balkêş e ku çawa, ji ber ku guhên asayî dê sînyalek 77KHz dernexin, lê wergir belkî ji ber ahengan e). Li ser Android 9-ê, bername ji min re qet nexebitî - bi tenê deng tune bû (an jî dibe ku min nebihîstiye - ew 77KHz e, her tişt :), lê dibe ku kesek çêtir bextewar be. Lêbelê, hin ji xwe re hilberînerek sînyala DCF-ya bêkêmasî dikin, ku çêkirina wê li ser heman Arduino an ESP32 hêsan e:
(kanî
encamê
Pergala DCF derket holê ku bi rastî pir hêsan û hêsan e. Bi alîkariya wergirek sade û erzan, hûn dikarin her dem û li her deverê wextê rast hebin, bê guman li qada pêşwaziyê. Wusa dixuye ku tevî dîjîtalîzasyona berbelav û Înternetê ya Tiştan jî, çareseriyên weha hêsan dê ji bo demek dirêj di daxwaziyê de bin.
Source: www.habr.com