DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Hello Habr.

Boya ọpọlọpọ awọn ti o ra aago kan tabi ibudo oju ojo ti ri aago Iṣakoso Redio tabi paapaa aami Atomic Clock lori apoti. Eyi jẹ irọrun pupọ, nitori pe o kan nilo lati fi aago sori tabili, ati lẹhin igba diẹ yoo ṣatunṣe laifọwọyi si akoko deede.
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Jẹ ká ro ero bi o ti ṣiṣẹ ki o si kọ kan decoder ni Python.

Awọn ọna amuṣiṣẹpọ akoko oriṣiriṣi lo wa. Awọn julọ gbajumo ni Europe ni awọn German eto DCF-77, Japan ni eto ti ara rẹ JJY, ni AMẸRIKA eto kan wa WWVB, ati bẹbẹ lọ. Nigbamii ti, itan naa yoo jẹ nipa DCF77, gẹgẹbi o ṣe pataki julọ ati wiwọle fun gbigba ni diẹ ninu awọn aaye ni agbegbe Europe ti Russia ati awọn orilẹ-ede ti o wa nitosi (awọn olugbe ti Iha Iwọ-oorun le ni imọran idakeji, sibẹsibẹ, wọn, ni ọna, le gba. ki o si itupalẹ awọn Japanese ifihan agbara;).

Ohun gbogbo ti a kọ ni isalẹ yoo jẹ nipa DCF77.

Gbigbawọle ifihan agbara

DCF77 jẹ ibudo igbi gigun ti n ṣiṣẹ ni igbohunsafẹfẹ 77.5 kHz ati awọn ifihan agbara gbigbe ni awose titobi. Ibusọ 50KW wa ni 25 km lati Frankfurt, o bẹrẹ iṣẹ ni ọdun 1959, ati ni ọdun 1973 alaye ọjọ ti ṣafikun si akoko gangan. Gigun gigun ni igbohunsafẹfẹ ti 77 kHz gun pupọ, nitorinaa awọn iwọn ti aaye eriali tun jẹ bojumu (Fọto lati Wikipedia):
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Pẹlu iru eriali ati titẹ sii agbara, agbegbe gbigba ni wiwa fere gbogbo Yuroopu, Belarus, Ukraine ati apakan ti Russia.

DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Ẹnikẹni le ṣe igbasilẹ ifihan agbara kan. Lati ṣe eyi, kan lọ si olugba lori ayelujara http://websdr.ewi.utwente.nl:8901/, yan awọn igbohunsafẹfẹ 76.5KHz ati USB awose nibẹ. Aworan yẹ ki o ṣii ti o dabi nkan bayi:

DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Nibẹ a tẹ bọtini igbasilẹ ati ṣe igbasilẹ ajẹkù kan ni awọn iṣẹju pupọ ni gigun. Nitoribẹẹ, ti o ba ni olugba “gidi” ti o lagbara lati gbasilẹ igbohunsafẹfẹ 77.5KHz, o le lo iyẹn.

Nitoribẹẹ, nipa gbigba awọn ifihan agbara akoko redio nipasẹ Intanẹẹti, a kii yoo gba akoko deede nitootọ - ifihan naa ti tan kaakiri pẹlu idaduro. Ṣugbọn ibi-afẹde wa nikan ni lati loye ilana ti ifihan naa; fun eyi, gbigbasilẹ Intanẹẹti diẹ sii ju to. Ni igbesi aye gidi, nitorinaa, awọn ẹrọ amọja ni a lo fun gbigba ati iyipada; wọn yoo jiroro ni isalẹ.

Nitorina, a ti gba igbasilẹ naa, jẹ ki a bẹrẹ sisẹ rẹ.

Iyipada ifihan agbara

Jẹ ki a gbe faili naa pẹlu lilo Python ki o wo eto rẹ:

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()

A wo iwọn titobi aṣoju:
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Lati ṣe iyipada iyipada, jẹ ki a mu apoowe ifihan agbara ni lilo iyipada Hilbert:

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

Abajade ti o pọ si:
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Jẹ ki a dan awọn itujade ariwo kuro ni lilo àlẹmọ-kekere, ati ni akoko kanna ṣe iṣiro iye apapọ, eyiti yoo wulo nigbamii fun sisọ.

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

Abajade (laini ofeefee): ifihan agbara igbi onigun mẹrin ti o fẹrẹẹ ti o rọrun pupọ lati ṣe itupalẹ.
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Ṣiṣayẹwo

Akọkọ ti o nilo lati gba awọn bit ọkọọkan. Ilana ifihan ara rẹ rọrun pupọ.
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Awọn iṣọn ti pin si awọn aaye arin keji. Ti aaye laarin awọn iṣọn jẹ 0.1s (ie ipari ti pulse funrararẹ jẹ 0.9s), ṣafikun “0” si ọkọọkan bit; ti ijinna ba jẹ 0.2s (ie ipari jẹ 0.8s), ṣafikun “1”. Ipari iṣẹju kọọkan jẹ itọkasi nipasẹ pulse “gun” kan, gigun 2s gigun, ọkọọkan bit ti tunto si odo, ati kikun yoo bẹrẹ lẹẹkansi.

Eyi rọrun lati kọ ni 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

Bi abajade, a gba ọkọọkan awọn die-die, ninu apẹẹrẹ wa fun iṣẹju-aaya meji o dabi eyi:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Nipa ọna, o jẹ iyanilenu pe ifihan agbara tun ni “ipo keji” ti data. Awọn bit ọkọọkan ti wa ni tun ti yipada nipa lilo awose alakoso. Ni imọran, eyi yẹ ki o pese iyipada ti o lagbara diẹ sii paapaa ninu ọran ifihan agbara alailagbara.

Igbesẹ ikẹhin wa: gbigba data gangan. Awọn bits ti wa ni gbigbe ni ẹẹkan fun iṣẹju-aaya, nitorinaa a ni apapọ awọn ege 59, ninu eyiti ọpọlọpọ alaye ti wa ni koodu:
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Awọn die-die ti wa ni apejuwe ninu Wikipedia, ati awọn ti wọn wa ni oyimbo iyanilenu. Awọn die-die 15 akọkọ ko lo, botilẹjẹpe awọn ero wa lati lo wọn fun awọn eto ikilọ ati aabo ilu. Bit A1 tọkasi pe aago yoo yipada si akoko fifipamọ oju-ọjọ ni wakati ti n bọ. Bit A2 tọkasi wipe afikun fifo keji, eyiti a lo nigba miiran lati ṣatunṣe akoko ni ibamu si yiyi Earth. Awọn die-die to ku ṣe koodu awọn wakati, iṣẹju, iṣẹju-aaya ati ọjọ.

DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Fun awọn ti o fẹ lati ṣe idanwo lori ara wọn, koodu iyipada ni a fun labẹ apanirun.
Orisun

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)

Nigbati a ba ṣiṣẹ eto naa, a yoo rii abajade ti o jọra si eyi:

0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42

Looto, idan niyen. Awọn anfani ti iru eto ni wipe iyipada jẹ lalailopinpin o rọrun ati ki o le ṣee ṣe lori eyikeyi, ani awọn alinisoro microcontroller. A nìkan ka awọn ipari ti awọn itọka, accumulate 60 die-die, ati ni opin ti kọọkan iseju a gba awọn gangan akoko. Ti a ṣe afiwe si awọn ọna mimuuṣiṣẹpọ akoko miiran (GPS, fun apẹẹrẹ, tabi Ọlọrun kọ, Intanẹẹti:), imuṣiṣẹpọ redio bẹ ko nilo ina - fun apẹẹrẹ, ile-iṣẹ oju ojo deede ti ile kan n ṣiṣẹ fun ọdun kan lori awọn batiri 2 AA. Nitorinaa, paapaa awọn aago ọwọ ni a ṣe pẹlu amuṣiṣẹpọ redio, kii ṣe mẹnuba, dajudaju, awọn iṣọ odi tabi awọn aago ibudo ita.

Irọrun ati ayedero ti DCF tun ṣe ifamọra awọn alara DIY. Fun o kan $10-20 o le ra module eriali ti a ti ṣetan pẹlu olugba ti a ti ṣetan ati iṣelọpọ TTL, eyiti o le sopọ si Arduino tabi oludari miiran.
DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

Ti kọ tẹlẹ fun Arduino setan-ṣe ikawe. Sibẹsibẹ, o ti mọ tẹlẹ pe ohunkohun ti o ṣe lori microcontroller, o pari pẹlu boya aago tabi ibudo oju ojo. Pẹlu iru ẹrọ kan, gbigba akoko gangan jẹ rọrun gaan, ti a pese, dajudaju, pe o wa ni agbegbe gbigba. O dara, o le kọ akọle “Atomic Clock” sori aago rẹ, ati ni akoko kanna ṣe alaye fun gbogbo eniyan pe ẹrọ naa ti ṣiṣẹpọ gaan ni lilo aago atomiki kan.

Awọn ti o fẹ paapaa le ṣe igbesoke aago iya-nla wọn atijọ nipa fifi ẹrọ tuntun sori ẹrọ pẹlu amuṣiṣẹpọ redio:

DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?

O le wa ọkan lori ebay nipa lilo awọn koko-ọrọ "Igbepo iṣakoso redio".

Ati nikẹhin, gige igbesi aye fun awọn ti o ti ka eyi jina. Paapaa ti ko ba si atagba ifihan agbara redio ẹyọkan ni tọkọtaya ẹgbẹrun kilomita ti nbọ, ko nira lati ṣe iru ifihan agbara funrararẹ. Eto kan wa lori Google Play ti a pe ni “DCF77 Emulator” ti o ṣe afihan ifihan si awọn agbekọri. Gẹgẹbi onkọwe naa, ti o ba fi ipari si okun waya ti awọn agbekọri ni ayika aago, wọn yoo gba ifihan agbara (o jẹ iyanilenu bawo ni, nitori awọn agbekọri lasan kii yoo ṣe ifihan ifihan 77KHz, ṣugbọn gbigba jẹ boya nitori awọn irẹpọ). Lori Android 9, eto naa ko ṣiṣẹ rara fun mi - ko si ohun rara (tabi boya Emi ko gbọ - o jẹ 77KHz, lẹhinna :), ṣugbọn boya ẹnikan yoo ni orire to dara julọ. Diẹ ninu, sibẹsibẹ, jẹ ki ara wọn di olupilẹṣẹ ifihan agbara DCF ni kikun, eyiti o rọrun lati ṣe lori Arduino tabi ESP32 kanna:

DCF77: Bawo ni eto ifihan akoko ṣiṣẹ?
(orisun sgfantasytoys.wordpress.com/2015/05/13/synchronize-redio-controlled-watch-lai-wiwọle)

ipari

Eto DCF ti jade lati rọrun pupọ ati irọrun. Pẹlu iranlọwọ ti o rọrun ati olugba olowo poku, o le ni akoko deede nigbagbogbo ati ni gbogbo ibi, dajudaju ni agbegbe gbigba. O dabi pe paapaa laibikita oni-nọmba kaakiri ati Intanẹẹti ti Awọn nkan, iru awọn solusan ti o rọrun yoo wa ni ibeere fun igba pipẹ.

orisun: www.habr.com

Fi ọrọìwòye kun