Сайн уу Хабр.
Цаг, цаг уурын станц худалдаж авсан олон хүн сав баглаа боодол дээр Радио удирдлагатай цаг эсвэл бүр атомын цагны лого зэргийг харсан байх. Энэ нь маш тохиромжтой, учир нь та зүгээр л цагийг ширээн дээр тавих хэрэгтэй бөгөөд хэсэг хугацааны дараа цагийг автоматаар тохируулах болно.
Энэ нь хэрхэн ажилладагийг олж мэдээд Python дээр декодер бичье.
Өөр өөр цаг синхрончлолын системүүд байдаг. Европт хамгийн алдартай нь Германы систем юм
Доор бичсэн бүх зүйл DCF77-ийн тухай байх болно.
Дохио хүлээн авах
DCF77 нь 77.5 кГц давтамжтай ажилладаг, далайцын модуляцаар дохио дамжуулдаг урт долгионы станц юм. 50 кВт-ын хүчин чадалтай станц нь Франкфурт хотоос 25 км-ийн зайд байрладаг бөгөөд 1959 онд ажиллаж эхэлсэн бөгөөд 1973 онд огнооны мэдээллийг яг цагт нь нэмсэн. 77 кГц давтамжтай долгионы урт нь маш урт тул антенны талбайн хэмжээ нь бас хангалттай (Википедиагийн зураг):
Ийм антенн болон цахилгааны оролттой бол хүлээн авах хэсэг нь бараг бүх Европ, Беларусь, Украин, Оросын зарим хэсгийг хамардаг.
Хэн ч дохио бичиж болно. Үүнийг хийхийн тулд зүгээр л онлайн хүлээн авагч руу очно уу
Тэнд бид татаж авах товчийг дараад хэдэн минутын турш фрагмент бичнэ. Мэдээжийн хэрэг, хэрэв танд 77.5KHz давтамжийг бичих чадвартай "жинхэнэ" хүлээн авагч байгаа бол үүнийг ашиглаж болно.
Мэдээжийн хэрэг, интернетээр дамжуулан радио цагийн дохиог хүлээн авснаар бид үнэн зөв цагийг хүлээн авахгүй - дохио нь сааталтай дамждаг. Гэхдээ бидний зорилго бол дохионы бүтцийг ойлгох явдал бөгөөд үүний тулд интернетийн бичлэг хангалттай. Бодит амьдрал дээр мэдээжийн хэрэг хүлээн авах, тайлах тусгай төхөөрөмжийг ашигладаг бөгөөд тэдгээрийг доор авч үзэх болно.
За ингээд бичлэгээ хүлээж авлаа, боловсруулж эхэлцгээе.
Дохио тайлах
Python ашиглан файлыг ачаалж, бүтцийг нь харцгаая:
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()
Бид ердийн далайцын модуляцийг харж байна:
Тайлбарыг хялбарчлахын тулд Хилберт хувиргалтыг ашиглан дохионы дугтуйг авч үзье.
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Томруулсан үр дүн:
Дуу чимээний ялгаруулалтыг нам дамжуулалтын шүүлтүүр ашиглан жигдрүүлж, дундаж утгыг тооцоолъё, энэ нь дараа нь задлан шинжлэхэд хэрэг болно.
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
Үр дүн (шар шугам): дүн шинжилгээ хийхэд хялбар бараг дөрвөлжин долгионы дохио.
Шинжилгээ
Эхлээд та битийн дарааллыг авах хэрэгтэй. Дохионы бүтэц нь өөрөө маш энгийн.
Импульс нь хоёр дахь интервалд хуваагдана. Хэрэв импульсийн хоорондох зай 0.1 секунд бол (өөрөөр хэлбэл импульсийн урт нь 0.9 секунд) бол битийн дараалалд "0" нэмнэ; хэрэв зай 0.2 секунд бол (өөрөөр хэлбэл урт нь 0.8 секунд) бол "1" нэмнэ. Минут бүрийн төгсгөлийг "урт" импульсээр зааж, 2 секундын урттай, битийн дарааллыг тэг болгож, дүүргэлт дахин эхэлнэ.
Дээрхийг 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
Үүний үр дүнд бид битүүдийн дарааллыг авдаг бөгөөд бидний жишээн дээр хоёр секундын турш дараах байдалтай байна.
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Дашрамд хэлэхэд дохио нь мэдээллийн "хоёрдахь давхарга" -тай байдаг нь сонирхолтой юм. Битийн дарааллыг мөн ашиглан кодчилдог
Бидний сүүлчийн алхам: бодит мэдээллийг авах. Битүүд секундэд нэг удаа дамждаг тул бидэнд маш их мэдээлэл кодлогдсон нийт 59 бит байна:
Битүүдийг тайлбарласан болно
Бие даан туршилт хийхийг хүсч буй хүмүүст зориулсан код тайлах кодыг спойлерын доор өгсөн болно.
Эх код
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)
Бид програмыг ажиллуулах үед үүнтэй төстэй гаралтыг харах болно:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Үнэндээ энэ бол бүх ид шид юм. Ийм системийн давуу тал нь код тайлах нь маш энгийн бөгөөд ямар ч, бүр хамгийн энгийн микроконтроллер дээр ч хийж болно. Бид зүгээр л импульсийн уртыг тоолж, 60 бит хуримтлуулж, минут бүрийн төгсгөлд бид яг цагийг авдаг. Цагийн синхрончлолын бусад аргуудтай харьцуулахад (жишээлбэл, GPS, эсвэл Бурхан хориглодог, Интернет :)) ийм радио синхрончлол нь бараг ямар ч цахилгаан шаарддаггүй - жишээлбэл, ердийн гэрийн цаг уурын станц нь 2 АА батерейгаар нэг жил орчим ажилладаг. Тиймээс бугуйн цагийг ч гэсэн радио синхрончлолоор хийдэг бөгөөд мэдээж ханын цаг эсвэл гудамжны станцын цагийг дурдахгүй.
DCF-ийн тав тухтай, энгийн байдал нь DIY сонирхогчдыг татдаг. Ердөө 10-20 доллараар та бэлэн хүлээн авагч, TTL гаралт бүхий бэлэн антенны модулийг худалдаж авах боломжтой бөгөөд үүнийг Arduino эсвэл бусад хянагчтай холбож болно.
Arduino-д зориулж аль хэдийн бичсэн
Хүссэн хүмүүс хуучин эмээгийнхээ цагийг радио синхрончлол бүхий шинэ механизм суулгаж сайжруулж болно.
Та "Радио удирдлагатай хөдөлгөөн" гэсэн түлхүүр үгсийг ашиглан ebay дээрээс нэгийг олох боломжтой.
Эцэст нь энэ хүртэл уншсан хүмүүст зориулсан лайф хакер. Дараагийн хэдэн мянган км-т ганц ч радио дохио дамжуулагч байхгүй байсан ч өөрөө ийм дохио үүсгэх нь хэцүү биш юм. Google Play дээр чихэвч рүү дохио өгдөг "DCF77 Emulator" нэртэй програм байдаг. Зохиогчийн хэлснээр, хэрэв та чихэвчний утсыг цагны эргэн тойронд ороох юм бол тэд дохиог авах болно (энэ нь сонирхолтой юм, учир нь энгийн чихэвч 77 кГц дохио гаргахгүй, гэхдээ хүлээн авалт нь гармоникаас үүдэлтэй байж магадгүй). Android 9 дээр энэ програм миний хувьд огт ажиллахгүй байсан - зүгээр л ямар ч дуу чимээ байхгүй (эсвэл би сонсоогүй байж магадгүй - энэ нь 77 кГц, эцэст нь :)), гэхдээ хэн нэгэнд илүү аз тохиох байх. Гэсэн хэдий ч зарим нь өөрсдийгөө Arduino эсвэл ESP32 дээр хийхэд хялбар, бүрэн эрхт DCF дохио үүсгэгч болгодог.
(эх сурвалж
дүгнэлт
DCF систем нь үнэхээр энгийн бөгөөд тохиромжтой болсон. Энгийн бөгөөд хямд хүлээн авагчийн тусламжтайгаар та үргэлж, хаа сайгүй, мэдээжийн хэрэг хүлээн авах хэсэгт цагийг яг таг авах боломжтой. Хэдийгээр дижиталчлал, эд зүйлсийн интернет өргөн тархсан ч ийм энгийн шийдлүүд удаан хугацаанд эрэлт хэрэгцээтэй байх шиг байна.
Эх сурвалж: www.habr.com