Salam Habr.
Yəqin ki, saat və ya hava stansiyası alanların çoxu qablaşdırmada Radio ilə idarə olunan saatı və ya hətta Atom Saatının loqosunu görüblər. Bu çox rahatdır, çünki saatı stolun üstünə qoymaq kifayətdir və bir müddət sonra o, avtomatik olaraq dəqiq vaxta uyğunlaşacaq.
Bunun necə işlədiyini anlayaq və Python-da dekoder yazaq.
Müxtəlif vaxt sinxronizasiya sistemləri var. Avropada ən populyarı Alman sistemidir
Aşağıda yazılan hər şey DCF77 haqqında olacaq.
Siqnal qəbulu
DCF77 77.5 KHz tezliyində işləyən və AM siqnallarını ötürən uzundalğalı stansiyadır. 50 kVt gücündə olan stansiya Frankfurtdan 25 km aralıda yerləşir, 1959-cu ildə işə başlamış, 1973-cü ildə tarix haqqında məlumat dəqiq vaxta əlavə edilmişdir. 77 kHz tezliyində dalğa uzunluğu çox böyükdür, buna görə anten sahəsinin ölçüləri də çox layiqdir (Vikipediyadan foto):
Belə bir antenna və giriş gücü ilə qəbul zonası demək olar ki, bütün Avropanı, Belarusiyanı, Ukraynanı və Rusiyanın bir hissəsini əhatə edir.
Hər kəs qeyd edə bilər. Bunu etmək üçün onlayn qəbulediciyə getmək kifayətdir
Eyni yerdə yükləmə düyməsini sıxırıq və bir neçə dəqiqəlik bir fraqmenti qeyd edirik. Əlbəttə ki, 77.5 kHz tezliyi qeyd edə bilən "real" qəbulediciniz varsa, ondan istifadə edə bilərsiniz.
Əlbəttə ki, İnternet üzərindən dəqiq vaxt radio siqnallarını qəbul edərək, həqiqətən dəqiq vaxt əldə etməyəcəyik - siqnal gecikmə ilə ötürülür. Ancaq məqsədimiz yalnız siqnalın strukturunu başa düşməkdir, bunun üçün İnternet qeydi kifayət qədərdir. Real həyatda, əlbəttə ki, qəbul və dekodlaşdırma üçün xüsusi cihazlar istifadə olunur, onlar aşağıda müzakirə olunacaq.
Beləliklə, qeydi aldıq, onu emal etməyə başlayaq.
Siqnalın dekodlanması
Faylı Python ilə yükləyək və onun strukturuna baxaq:
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()
Tipik bir amplituda modulyasiyasını görürük:
Deşifrəni asanlaşdırmaq üçün Hilbert transformasiyasından istifadə edərək siqnal zərfini götürürük:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Genişləndirilmiş nəticə:
Gəlin aşağı ötürücü filtrdən istifadə edərək səs-küy emissiyalarını hamarlayaq, eyni zamanda orta dəyəri hesablayaq, sonra təhlil etmək üçün lazımlı olacaq.
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
Nəticə (sarı xətt): analiz etmək kifayət qədər asan olan demək olar ki, düzbucaqlı siqnal.
Təhlil
Əvvəlcə bit ardıcıllığını əldə etməlisiniz. Siqnal quruluşunun özü çox sadədir.
Nəbzlər ikinci intervallara bölünür. İmpulslar arasındakı məsafə 0.1s olarsa (yəni impulsun uzunluğu 0.9s-dir), bit ardıcıllığına “0” əlavə edirik, əgər məsafə 0.2s (yəni uzunluq 0.8s) olarsa, əlavə edirik “1”. Hər dəqiqənin sonu "uzun" nəbzlə göstərilir, 2 s uzunluğunda, bit ardıcıllığı sıfırlanır və doldurulma yenidən başlayır.
Yuxarıdakıları Python-da yazmaq asandır.
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
Nəticədə, bitlərin ardıcıllığını alırıq, nümunəmizdə iki saniyə belə görünür:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Yeri gəlmişkən, maraqlıdır ki, siqnalda məlumatların "ikinci təbəqəsi" də var. Bit ardıcıllığı da ilə kodlanır
Son addımımız: faktiki məlumatları əldə edin. Bitlər saniyədə bir dəfə ötürülür, ona görə də bizdə kifayət qədər çox məlumat kodlaşdırılan cəmi 59 bit var:
Bitlər -də təsvir edilmişdir
Özbaşına sınaq keçirmək istəyənlər üçün deşifrə kodu spoylerin altında verilir.
Mənbə kodu
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)
Proqramı işlədəndə belə bir nəticə görəcəyik:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Əslində, bütün sehr budur. Belə bir sistemin üstünlüyü ondan ibarətdir ki, dekodlaşdırma son dərəcə sadədir və istənilən, ən sadə mikrokontrollerdə edilə bilər. Biz sadəcə impulsların uzunluğunu sayırıq, 60 bit yığırıq və hər dəqiqənin sonunda dəqiq vaxtı alırıq. Vaxt sinxronizasiyasının digər üsulları ilə müqayisədə (məsələn, GPS və ya Allah qorusun, İnternet :), belə radio sinxronizasiyası praktiki olaraq elektrik tələb etmir - məsələn, adi bir ev meteoroloji stansiyası 2 AA batareyasında təxminən bir il işləyir. Buna görə də, hətta qol saatları da radio sinxronizasiyası ilə hazırlanır, əlbəttə ki, divar saatları və ya küçə stansiyası saatlarını qeyd etmirəm.
DCF-nin rahatlığı və sadəliyi də DIY həvəskarlarını cəlb edir. Cəmi 10-20 dollara siz hazır qəbuledicisi və Arduino və ya digər nəzarətçiyə qoşula bilən TTL çıxışı olan hazır anten modulu ala bilərsiniz.
Arduino üçün artıq yazılmış və
Arzu edənlər hətta radio sinxronizasiyası olan yeni mexanizm quraşdıraraq köhnə nənənin saatını təkmilləşdirə bilərlər:
Siz ebay-da "Radio Controlled Movement" açar sözlərindən istifadə edərək tapa bilərsiniz.
Və nəhayət, bura qədər oxuyanlar üçün həyat hack. Növbəti bir neçə min kilometrdə bir radio siqnal ötürücüsü olmasa belə, belə bir siqnalı özünüz yaratmaq asandır. Google Play-də qulaqlıqlara siqnal verən "DCF77 Emulator" adlı proqram var. Müəllifin fikrincə, qulaqcıq naqilini gecə-gündüz büksəniz, onlar siqnalı tutacaqlar (görəsən, necə olur, çünki adi qulaqlıqlar 77KHz siqnal verməyəcək, amma yəqin ki, qəbul harmonika ilə bağlıdır). Proqram mənim üçün Android 9-da ümumiyyətlə işləmədi - sadəcə səs yox idi (və ya bəlkə də eşitmədim - 77KHz :), amma bəlkə kimsə daha şanslı olacaq. Bəziləri isə özlərini eyni Arduino və ya ESP32-də etmək asan olan tam hüquqlu DCF siqnal generatoru edirlər:
(mənbə
Nəticə
DCF sistemi həqiqətən olduqca sadə və rahat oldu. Sadə və ucuz qəbuledicinin köməyi ilə siz həmişə və hər yerdə, əlbəttə ki, qəbul zonasında dəqiq vaxta sahib ola bilərsiniz. Belə görünür ki, hətta geniş yayılmış rəqəmsallaşmaya və “Əşyaların İnterneti”nə baxmayaraq, belə sadə həllər hələ uzun müddət tələb olunacaq.
Mənbə: www.habr.com