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 и посмотрим его структуру:

от scipy.io import wavfile
от scipy import signal
импортировать matplotlib.pyplot как plt
импортировать numpy как 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: как работи системата за предаване на сигнали за точно време?

Ще изгладим изблиците от смущенията с помощта на нискочестотен филтър и едновременно ще изчислим средната стойност, която ще ни е полезна по-късно за парсирането.

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:
        # Начало на сигнала
        sig_start = pos
    if A[pos] > avg and A[pos+1] < avg:
        # Край на сигнала
        sig_stop = pos

        diff = sig_stop - sig_start
    
        if diff  0.85*sample_rate and diff  1.5*sample_rate:
            print(bits_str)
            bits_str = ""

    pos += 1

В резултат получаваме последователност от битове, в нашия пример за два секунди тя изглежда така:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Интересно е, че в сигнала има и "втори слой" данни. Последователността от битове също е кодирана с помощта на фазова модулация. Теоретично това трябва да осигури по-устойчиво декодиране дори в случай на отслабен сигнал.

Нашата последна стъпка: да получим самите данни. Битовете се предават веднъж в секунда, така че имаме само 59 бита, в които е кодирана доста информация:
DCF77: как работи системата за предаване на сигнали за точно време?

Битовете са описани в Уикипедия, и те са доста любопитни. Първите 15 бита не се използват, въпреки че имаше планове да се използват за системи за предупреждение и гражданска защита. Бит A1 указва, че през следващия час часовниците ще бъдат преместени на лятно време. Бит A2 указва, че през следващия час ще бъде добавена допълнителна секунда, която понякога се използва за корекция на времето в съответствие с въртенето на Земята. Останалите битове кодирани часовете, минутите, секундите и датата.

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 = ('Неделя', 'Понеделник', 'Вторник', 'Сряда', 'Четвъртък', 'Петък', 'Събота', 'Неделя')
    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
Вторник, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Вторник, 26.03.19, 21:42

Всъщност, ето я цялата магия. Предимството на тази система е, че декодирането е изключително простичко и може да се направи на всякакъв, дори и най-прост микроконтролер. Просто измерваме дължината на импулсите, натрупваме 60 бита и в края на всяка минута получаваме точно време. В сравнение с други методи за синхронизация на времето (например GPS, или не дай боже, Интернет:), тази радиосинхронизация практически не изисква електрическа енергия — за пример, обикновена домашна метеостанция работи около година с 2 батерии АА. Затова с радиосинхронизация се правят дори часовници, да не споменаваме, разбира се, настенни или за улични вокзали.

Удобството и простотата на DCF привлекат и любителите на самоделки. Само за 10-20$ можете да купите готов модул с антенка и готов приемник с TTL-изход, който може да бъде свързан към Arduino или друг контролер.
DCF77: как работи системата за предаване на сигнали за точно време?

Вече са написани и готови библиотеки. Впрочем, известно, че каквото и да правим на микроконтролера, получаваме или часовник, или метеостанция. С такова устройство получаването на точно време наистина е лесно, разбира се, ако се намираме в зоната на приемане. И може да сложим надпис «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

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster