DCF77: как работает системата за предаване на сигнали за точно време?

Здравей Хабр.

Вероятно много от вас, които купуват часовници или метеостанции, са виждали на опаковката логото Radio Controlled Clock или дори Atomic Clock. Това е много удобно, тъй като е достатъчно да поставите часовника на масата и след кратко време той автоматично ще се настрои на точното време.
DCF77: как работает системата за предаване на сигнали за точно време?

Нека разберем как работи това и да напишем декодер на Python.

Съществуват различни системи за синхронизация на времето. Най-популярната в Европа е немската система DCF-77, в Япония имат своя система JJY, в САЩ има система WWVB, и така нататък. По-нататък разказът ще бъде за DCF77, като най-актуална и достъпна за приемане в някои части на европейската част на Русия и съседни страни (жителите на Далечния изток могат да имат противоположно мнение, но те могат да приемат и анализират японския сигнал към своя ред).

Всичко написано по-долу ще бъде за DCF77.

Прием на сигнала

DCF77 е дълговълнова станция, която работи на честота 77.5 kHz и предава сигнали с амплитудна модулация. Станцията с мощност 50 kW се намира на 25 км от Франкфурт, стартирала е работа още през 1959 година, а през 1973 година информацията за датата е добавена към точното време. Дължината на вълната при честота 77 kHz е доста голяма, затова размерите на антенното поле също са значителни (снимка от Уикипедия):
DCF77: как работает системата за предаване на сигнали за точно време?

С такава антена и подаваната мощност, зоната на прием обхваща практически цяла Европа, Беларус, Украйна и част от Русия.

DCF77: как работает системата за предаване на сигнали за точно време?

Всеки може да запише сигнала. За целта е достатъчно да се влезе в онлайн приемник http://websdr.ewi.utwente.nl:8901/, да се избере честота 76.5 kHz и USB модулация. Трябва да се отвори изображение, подобно на това:

DCF77: как работает системата за предаване на сигнали за точно време?

Там натискаме бутона download и записваме фрагмент с дължина няколко минути. Разбира се, при наличие на „настоящ“ приемник, способен да запише честота 77.5 kHz, може да се използва и него.

Разбира се, приемайки радиосигнали за точно време през интернет, няма да получим наистина точно време — сигналът се предава с закъснение. Но нашата цел е само да разберем структурата на сигнала, за това интернет записите са повече от достатъчни. В реалността, разбира се, се използват специализирани устройства за приемане и декодиране, за които ще бъде споменато по-долу.

И така, ние получихме запис, нека преминем към неговата обработка.

Декодиране на сигнала

Ще заредим файл с 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:
        # Започване на сигнала
        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 батерии AA. Затова радиосинхронизацията се използва дори в наручни часовници, да не говорим вече за стенни или улични гари.

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

За Arduino вече са написани и готови библиотеки. Въпреки това, вече е известно — каквото и да правите на микроконтролера, крайният резултат е или часовник, или метеорологична станция. С такова устройство е наистина лесно да се получи точно време, ако разбира се, сте в зоната на прием. Освен това, можете да закачите на часовника надпис „Atomic Clock“ и да обяснявате на всички желаещи, че устройството наистина се синхронизира с атомни часовници.

Желаещите дори могат да надстроят старите бабини часовници, като инсталират нов механизъм с радиосинхронизация:

DCF77: как работает системата за предаване на сигнали за точно време?

Такъв може да се намери в ebay по ключовите думи „Radio Controlled Movement“.

И накрая, лайфхак за тези, които прочетоха до тук. Дори ако в близките хиляди километри няма предавател на радиосигнал, такъв сигнал не е трудно да се генерира самостоятелно. В Google Play има програма с името „DCF77 Emulator“, която излъчва сигнал през слушалките. Според автора, ако обвиете проводника на слушалките около часовника, те ще уловят сигнала (интересно как, тъй като обикновените слушалки не могат да излъчват сигнал 77kHz, но вероятно приемът става чрез хармоници). При мен на Android 9 програмата не сработи изобщо — просто нямаше звук (а може би не чух звука — 77kHz все пак :), но може би на някого ще му повдигне късмета. Някои правят и пълен генератор на 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