DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Прывітанне Хабр.

Напэўна многія, якія набываюць гадзіны ці метэастанцыю, бачылі на пакаванні лагатып Radio Controlled Clock ці нават Atomic Clock. Гэта вельмі зручна, бо дастаткова паставіць гадзіннік на стол, і яны праз некаторы час аўтаматычна настрояцца на дакладны час.
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Разбярэмся як гэта працуе і напішам дэкодэр на мове Python.

Існуюць розныя сістэмы сінхранізацыі часу. Найбольш папулярная ў Еўропе - нямецкая сістэма DCF-77, у Японіі ёсць свая сістэма JJY, у ЗША ёсць сістэма WWVB, і гэтак далей. Далей аповяд будзе аб DCF77, як аб найболей актуальнай і даступнай для прыёму ў некаторых месцах еўрапейскай часткі Расеі і суседніх краінах (у жыхароў Далёкага Ўсходу можа быць процілеглае меркаванне, зрэшты яны ў сваю чаргу могуць прыняць і прааналізаваць японскі сігнал;).

Усё напісанае далей, будзе пра DCF77.

Прыём сігналу

DCF77 гэта даўгахвалевая станцыя, якая працуе на частаце 77.5КГц, і якая перадае сігналы ў амплітуднай мадуляцыі. Станцыя магутнасцю 50КВт размешчана ў 25км ад Франкфурта, яна пачала працу яшчэ ў 1959 годзе, у 1973 да дакладнага часу была дададзена інфармацыя аб даце. Даўжыня хвалі пры частаце 77Кгц вельмі вялікая, таму памеры антэннага поля таксама вельмі прыстойныя (фота з Вікіпедыі):
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Пры такой антэне і падводнай магутнасці, зона прыёму ахоплівае практычна ўсю Еўропу, Беларусь, Украіну і частку Расіі.

DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Запісаць сігнал можа кожны. Для гэтага дастаткова зайсці на анлайн-прымач http://websdr.ewi.utwente.nl:8901/, выбраць там частату 76.5Кгц і USB-мадуляцыю. Павінна адкрыцца карцінка прыкладна тыпу такой:

DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Там жа націскаем кнопку download і запісваем фрагмент даўжынёй у некалькі хвілін. Зразумела, пры наяўнасці "сапраўднага" прымача, здольнага запісаць частату 77.5Кгц, можна выкарыстоўваць і яго.

Вядома, прымаючы радыёсігналы дакладнага часу праз Інтэрнэт, мы не атрымаем сапраўды дакладны час - сігнал перадаецца з затрымкай. Але наша мэта толькі зразумець структуру сігналу, для гэтага інтэрнэт-запісы больш за досыць. У рэале вядома, выкарыстоўваюцца спецыялізаваныя прылады для прыёму і дэкадаванні, пра іх будзе сказана ніжэй.

Такім чынам, мы атрымалі запіс, прыступім да яго апрацоўкі.

Дэкадаванне сігналу

Загрузім файл з дапамогай 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()

Мы бачым тыповую амплітудную мадуляцыю:
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Для спрашчэння дэкадавання возьмем абгінаючую сігналу з дапамогай пераўтварэння Гільберта:

analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])

Вынік у павялічаным выглядзе:
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Згладзім выкіды ад перашкод з дапамогай low-pass фільтра, заадно вылічым сярэдняе значэнне, яно спатрэбіцца потым для парсінгу.

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

Вынік (жоўтая лінія): практычна прастакутны сігнал, які даволі лёгка аналізаваць.
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Парсінг

Спачатку трэба атрымаць бітавую паслядоўнасць. Сама структура сігналу вельмі простая.
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Імпульсы падзелены на секундныя інтэрвалы. Калі адлегласць паміж імпульсамі складае 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 біт, у якіх закадзіравана дастаткова шмат інфармацыі:
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Біты апісаны ў Вікіпедыі, і яны даволі цікаўныя. Першыя 15 біт не выкарыстоўваюцца, хаця былі планы выкарыстоўваць для сістэм абвесткі і грамадзянскай абароны. Біт A1 паказвае на тое, што ў наступную гадзіну гадзіны будуць пераведзены на летні час. Біт А2 паказвае, што ў наступную гадзіну будзе дададзена дадатковая секунда, Якая часам выкарыстоўваецца для карэкцыі часу ў адпаведнасці з кручэннем Зямлі. Астатнія біты кадуюць гадзіны, хвіліны, секунды і дату.

DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Для тых, хто захоча паэксперыментаваць самастойна, код для дэкадавання прыведзены пад спойлерам.
зыходны код

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 прыцягваюць і аматараў самаробак. Усяго за 10-20$ можна купіць гатовы модуль з антэны з гатовым прымачом і TTL-выхадам, які можна падлучыць да Arduino ці іншаму кантролеру.
DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Для Arduino ужо напісаны і гатовыя бібліятэкі. Зрэшты, і так вядома - што ні рабі на мікракантролеры, атрымліваюцца альбо гадзіны, альбо метэастанцыя. З такой прыладай атрымліваць дакладны час сапраўды нескладана, калі вядома знаходзіцца ў зоне прыёму. Ну і можна павесіць на гадзіннік надпіс "Atomic Clock", і заадно тлумачыць усім жадаючым, што прылада сапраўды сінхранізуецца з дапамогай атамных гадзін.

Жадаючыя могуць нават праапгрэйдзіць старыя бабуліны гадзіны, усталяваўшы ў іх новы механізм з радыёсінхранізацыяй:

DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?

Знайсці такі можна на ebay па ключавых словах "Radio Controlled Movement".

І нарэшце, лайфхак для тых хто дачытаў да сюды. Нават калі ў бліжэйшых пары тысяч км няма ніводнага перадатчыка радыёсігналу, такі сігнал нескладана згенераваць самастойна. У Google Play ёсць праграма з назвай "DCF77 Emulator", якая выводзіць сігнал на навушнікі. Па запэўненнях аўтара, калі абматаць провад навушнікаў вакол гадзін, яны зловяць сігнал (цікава як, бо звычайныя навушнікі не выдадуць сігнал 77КГц, але верагодна прыём ідзе за кошт гарамонік). У мяне на Android 9 праграма не зарабіла зусім - проста не было гуку (а можа я яго не чуў - 77КГц бо:), але можа камусьці павязе больш. Некаторыя зрэшты, робяць сабе і паўнавартасны генератар сігналаў DCF, які нескладана зрабіць на той жа Arduino ці ESP32:

DCF77: як працуе сістэма перадачы сігналаў дакладнага часу?
(крыніца sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Заключэнне

Сістэма DCF, аказалася сапраўды цалкам просты і зручнай. З дапамогай нескладанага і таннага прымача можна мець дакладны час заўсёды і ўсюды, зразумела ў зоне прыёму. Думаецца, нават нягледзячы на ​​паўсюдную цыфравізацыі і "інтэрнэт рэчаў", такія простыя рашэнні будуць запатрабаваны яшчэ доўга.

Крыніца: habr.com

Дадаць каментар