Hello Habr.
Marahil marami sa mga bumili ng relo o weather station ang nakakita ng Radio Controlled Clock o kahit na logo ng Atomic Clock sa packaging. Ito ay napaka-maginhawa, dahil kailangan mo lamang ilagay ang orasan sa mesa, at pagkaraan ng ilang sandali ay awtomatiko itong maisasaayos sa eksaktong oras.
Alamin natin kung paano ito gumagana at magsulat ng decoder sa Python.
Mayroong iba't ibang mga sistema ng pag-synchronize ng oras. Ang pinakasikat sa Europa ay ang sistemang Aleman
Lahat ng nakasulat sa ibaba ay tungkol sa DCF77.
Pagtanggap ng signal
Ang DCF77 ay isang mahabang wave station na tumatakbo sa dalas na 77.5 kHz at nagpapadala ng mga signal sa amplitude modulation. Ang istasyon ng 50KW ay matatagpuan 25 km mula sa Frankfurt, nagsimula itong gumana noong 1959, at noong 1973 ang impormasyon ng petsa ay idinagdag sa eksaktong oras. Ang wavelength sa dalas ng 77 KHz ay ββnapakahaba, kaya ang mga sukat ng patlang ng antena ay medyo disente (larawan mula sa Wikipedia):
Sa ganitong antenna at power input, ang lugar ng pagtanggap ay sumasaklaw sa halos lahat ng Europa, Belarus, Ukraine at bahagi ng Russia.
Kahit sino ay maaaring mag-record ng signal. Upang gawin ito, pumunta lamang sa online na receiver
Doon ay pinindot namin ang pindutan ng pag-download at nag-record ng isang fragment ng ilang minuto ang haba. Siyempre, kung mayroon kang "tunay" na receiver na may kakayahang mag-record ng 77.5KHz frequency, magagamit mo iyon.
Siyempre, sa pamamagitan ng pagtanggap ng mga signal ng oras ng radyo sa pamamagitan ng Internet, hindi kami makakatanggap ng tunay na tumpak na oras - ang signal ay ipinapadala nang may pagkaantala. Ngunit ang aming layunin ay upang maunawaan lamang ang istraktura ng signal; para dito, ang pag-record sa Internet ay higit pa sa sapat. Sa totoong buhay, siyempre, ang mga dalubhasang aparato ay ginagamit para sa pagtanggap at pag-decode; tatalakayin sila sa ibaba.
So, natanggap na natin ang recording, simulan na natin itong iproseso.
Signal Decoding
I-load natin ang file gamit ang Python at tingnan ang istraktura nito:
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()
Nakikita namin ang tipikal na modulasyon ng amplitude:
Upang gawing simple ang pag-decode, kunin natin ang signal envelope gamit ang Hilbert transform:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Pinalaki na resulta:
Pakinisin natin ang mga paglabas ng ingay gamit ang isang low-pass na filter, at sabay na kalkulahin ang average na halaga, na magiging kapaki-pakinabang sa ibang pagkakataon para sa pag-parse.
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
Resulta (dilaw na linya): isang halos parisukat na wave signal na medyo madaling suriin.
Pag-parse
Una kailangan mong makuha ang bit sequence. Ang istraktura ng signal mismo ay napaka-simple.
Ang mga pulso ay nahahati sa pangalawang pagitan. Kung ang distansya sa pagitan ng mga pulso ay 0.1s (i.e. ang haba ng mismong pulso ay 0.9s), idagdag ang "0" sa bit sequence; kung ang distansya ay 0.2s (ibig sabihin, ang haba ay 0.8s), idagdag ang "1". Ang katapusan ng bawat minuto ay ipinapahiwatig ng isang "mahabang" pulso, 2s ang haba, ang bit sequence ay ni-reset sa zero, at ang pagpuno ay magsisimulang muli.
Ang nasa itaas ay madaling isulat sa 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
Bilang isang resulta, nakakakuha kami ng isang pagkakasunud-sunod ng mga bit, sa aming halimbawa sa loob ng dalawang segundo ay ganito ang hitsura:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Sa pamamagitan ng paraan, ito ay kagiliw-giliw na ang signal ay mayroon ding "pangalawang layer" ng data. Ang bit sequence ay naka-encode din gamit
Ang aming huling hakbang: pagkuha ng aktwal na data. Ang mga bit ay ipinapadala isang beses bawat segundo, kaya mayroon kaming kabuuang 59 bit, kung saan napakaraming impormasyon ang naka-encode:
Ang mga bit ay inilarawan sa
Para sa mga gustong mag-eksperimento sa kanilang sarili, ang decoding code ay ibinibigay sa ilalim ng spoiler.
Source code
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)
Kapag pinatakbo namin ang programa, makikita namin ang output na katulad nito:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Sa totoo lang, iyon lang ang magic. Ang bentahe ng naturang sistema ay ang pag-decode ay napakasimple at maaaring gawin sa alinman, kahit na ang pinakasimpleng microcontroller. Binibilang lang namin ang haba ng mga pulso, nag-iipon ng 60 bits, at sa dulo ng bawat minuto nakukuha namin ang eksaktong oras. Kung ikukumpara sa iba pang mga paraan ng pag-synchronize ng oras (GPS, halimbawa, o ipagbawal ng Diyos, ang Internet:), ang naturang radio synchronization ay halos hindi nangangailangan ng kuryente - halimbawa, ang isang regular na home weather station ay tumatakbo nang halos isang taon sa 2 AA na baterya. Samakatuwid, kahit na ang mga wristwatches ay ginawa gamit ang radio synchronization, hindi pa banggitin, siyempre, mga relo sa dingding o mga relo sa istasyon ng kalye.
Ang kaginhawahan at pagiging simple ng DCF ay nakakaakit din ng mga mahilig sa DIY. Sa halagang $10-20 lang, makakabili ka ng isang ready-made antenna module na may ready-made na receiver at TTL output, na maaaring ikonekta sa isang Arduino o iba pang controller.
Naisulat na para sa Arduino
Ang mga nagnanais ay maaari pang mag-upgrade ng relo ng kanilang lumang lola sa pamamagitan ng pag-install ng bagong mekanismo na may radio synchronization:
Makakahanap ka ng isa sa ebay gamit ang mga keyword na "Radio Controlled Movement".
At sa wakas, isang life hack para sa mga nakabasa na hanggang dito. Kahit na walang nag-iisang radio signal transmitter sa susunod na ilang libong km, hindi mahirap gumawa ng ganoong signal sa iyong sarili. Mayroong isang programa sa Google Play na tinatawag na "DCF77 Emulator" na naglalabas ng signal sa mga headphone. Ayon sa may-akda, kung ibalot mo ang wire ng mga headphone sa paligid ng relo, kukunin nila ang signal (kawili-wili kung paano, dahil ang mga ordinaryong headphone ay hindi gagawa ng isang 77KHz signal, ngunit ang pagtanggap ay marahil dahil sa mga harmonika). Sa Android 9, ang programa ay hindi gumana sa lahat para sa akin - walang tunog (o marahil ay hindi ko narinig - ito ay 77KHz, pagkatapos ng lahat:), ngunit marahil ang isang tao ay magkakaroon ng mas magandang kapalaran. Ang ilan, gayunpaman, ay ginagawa ang kanilang sarili bilang isang ganap na generator ng signal ng DCF, na madaling gawin sa parehong Arduino o ESP32:
(pinagmulan
Konklusyon
Ang sistema ng DCF ay naging talagang simple at maginhawa. Sa tulong ng isang simple at murang receiver, maaari kang magkaroon ng eksaktong oras palagi at saanman, siyempre sa lugar ng pagtanggap. Tila kahit na sa kabila ng malawakang digitalization at Internet of Things, ang mga simpleng solusyon ay hihingin sa mahabang panahon.
Pinagmulan: www.habr.com