DCF77: Kiel funkcias la temposignalsistemo?

Saluton Habr.

Verŝajne multaj, kiuj aĉetas horloĝon aŭ veterstacion, vidis la Radio-Regitan Horloĝon aŭ eĉ la emblemon de Atoma Horloĝo sur la pakaĵo. Ĉi tio estas tre oportuna, ĉar vi nur bezonas meti la horloĝon sur la tablon, kaj post iom da tempo ĝi aŭtomate adaptiĝos al la ĝusta horo.
DCF77: Kiel funkcias la temposignalsistemo?

Ni eltrovu kiel ĝi funkcias kaj skribu malĉifrilon en Python.

Ekzistas malsamaj temposinkronigaj sistemoj. La plej populara en Eŭropo estas la germana sistemo DCF-77, Japanio havas sian propran sistemon JJY, en Usono ekzistas sistemo WWVB, kaj tiel plu. Poste, la rakonto estos pri DCF77, kiel la plej grava kaj alirebla por akcepto en kelkaj lokoj en la eŭropa parto de Rusio kaj najbaraj landoj (loĝantoj de la Malproksima Oriento povas havi la kontraŭan opinion, tamen ili, siavice, povas ricevi; kaj analizu la japanan signalon;).

Ĉio skribita sube temas pri la DCF77.

Signala ricevo

DCF77 estas longonda stacio funkciiganta ĉe frekvenco de 77.5 kHz kaj elsendante signalojn en amplitudmodulado. La 50KW-stacio situas 25 km de Frankfurto, ĝi ekfunkciis en 1959, kaj en 1973 datinformoj estis aldonitaj al la preciza horo. La ondolongo ĉe frekvenco de 77 KHz estas tre longa, do la dimensioj de la antenkampo ankaŭ estas sufiĉe decaj (foto el Vikipedio):
DCF77: Kiel funkcias la temposignalsistemo?

Per tia anteno kaj elektra enigo, la akceptejo kovras preskaŭ la tutan Eŭropon, Belorusion, Ukrainion kaj parton de Rusio.

DCF77: Kiel funkcias la temposignalsistemo?

Ĉiu povas registri signalon. Por fari tion, simple iru al la interreta ricevilo http://websdr.ewi.utwente.nl:8901/, elektu la frekvencon 76.5KHz kaj USB-moduladon tie. Bildo devus malfermiĝi, kiu aspektas kiel ĉi tio:

DCF77: Kiel funkcias la temposignalsistemo?

Tie ni premas la elŝutbutonon kaj registras fragmenton dum kelkaj minutoj. Kompreneble, se vi havas "realan" ricevilon kapablan registri la 77.5KHz-frekvencon, vi povas uzi tion.

Kompreneble, ricevante radio-horajn signalojn per interreto, ni ne ricevos vere precizan tempon - la signalo estas elsendita kun malfruo. Sed nia celo estas nur kompreni la strukturon de la signalo; por tio, la interreta registrado estas pli ol sufiĉa. En la reala vivo, kompreneble, specialigitaj aparatoj estas uzataj por ricevi kaj malkodi; ili estos diskutitaj sube.

Do, ni ricevis la registradon, ni komencu prilabori ĝin.

Signalo Malkodado

Ni ŝarĝu la dosieron per Python kaj vidu ĝian strukturon:

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

Ni vidas tipan amplitudmoduladon:
DCF77: Kiel funkcias la temposignalsistemo?

Por simpligi malkodigon, ni prenu la signalkoverton uzante la Hilbert-konverton:

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

Pligrandigita rezulto:
DCF77: Kiel funkcias la temposignalsistemo?

Ni glatigu bruemisiojn per malalta filtrilo, kaj samtempe kalkulu la averaĝan valoron, kiu estos utila poste por analizado.

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

Rezulto (flava linio): preskaŭ kvadrata ondo-signalo, kiu estas sufiĉe facile analizebla.
DCF77: Kiel funkcias la temposignalsistemo?

Analizado

Unue vi devas akiri la bitan sinsekvon. La signala strukturo mem estas tre simpla.
DCF77: Kiel funkcias la temposignalsistemo?

La pulsoj estas dividitaj en duajn intervalojn. Se la distanco inter pulsoj estas 0.1s (t.e. la longo de la pulso mem estas 0.9s), aldonu "0" al la bitosekvenco; se la distanco estas 0.2s (t.e. la longo estas 0.8s), aldonu "1". La fino de ĉiu minuto estas indikita per "longa" pulso, 2s longa, la bita sekvenco estas rekomencigita al nulo, kaj plenigo komenciĝas denove.

La supre estas facile skribi en 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

Kiel rezulto, ni ricevas sekvencon de bitoj, en nia ekzemplo dum du sekundoj ĝi aspektas jene:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Cetere, estas interese, ke la signalo ankaŭ havas "duan tavolon" de datumoj. La bita sekvenco ankaŭ estas ĉifrita uzante faza modulado. En teorio, tio devus disponigi pli fortikan malkodigon eĉ en la kazo de malfortigita signalo.

Nia lasta paŝo: akiri la realajn datumojn. Bitoj estas elsenditaj unufoje en sekundo, do ni havas entute 59 bitoj, en kiuj sufiĉe multe da informoj estas koditaj:
DCF77: Kiel funkcias la temposignalsistemo?

La bitoj estas priskribitaj en Vikipedio, kaj ili estas sufiĉe scivolemaj. La unuaj 15 bitoj ne estas uzataj, kvankam estis planoj uzi ilin por avertsistemoj kaj civila defendo. Bito A1 indikas, ke la horloĝo ŝanĝos al somera horo en la venonta horo. Bito A2 indikas ke plia sekundo, kiu foje estas uzata por ĝustigi la tempon laŭ la tera rotacio. La ceteraj bitoj kodas horojn, minutojn, sekundojn kaj daton.

DCF77: Kiel funkcias la temposignalsistemo?

Por tiuj, kiuj volas eksperimenti memstare, la malkoda kodo estas donita sub la spoiler.
Fontkodo

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)

Kiam ni rulas la programon, ni vidos eligon similan al ĉi tio:

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

Efektive, tio estas la tuta magio. La avantaĝo de tia sistemo estas, ke malkodado estas ekstreme simpla kaj povas esti farita sur iu ajn, eĉ la plej simpla mikroregilo. Ni simple kalkulas la longecon de la pulsoj, amasigas 60 bitojn, kaj fine de ĉiu minuto ni ricevas la ĝustan tempon. Kompare kun aliaj metodoj de temposinkronigado (GPS, ekzemple, aŭ Dio gardu, Interreto:), tia radiosinkronigado postulas preskaŭ neniun elektron - ekzemple, regula hejma veterstacio funkcias dum proksimume jaro per 2 AA-kuirilaroj. Sekve, eĉ brakhorloĝoj estas faritaj kun radio-sinkronigo, sen mencii, kompreneble, murhorloĝoj aŭ strataj stacidomoj.

La komforto kaj simpleco de DCF ankaŭ altiras DIY-entuziasmulojn. Por nur $ 10-20 vi povas aĉeti pretan antenan modulon kun preta ricevilo kaj TTL-eligo, kiu povas esti konektita al Arduino aŭ alia regilo.
DCF77: Kiel funkcias la temposignalsistemo?

Jam skribita por Arduino pretaj bibliotekoj. Tamen, oni jam scias, ke ne gravas, kion vi faras sur mikroregilo, vi finas kun aŭ horloĝo aŭ veterstacio. Kun tia aparato, akiri la precizan tempon estas vere facila, kondiĉe, kompreneble, ke vi estas en la akceptejo. Nu, vi povas pendigi la surskribon "Atoma Horloĝo" sur via horloĝo, kaj samtempe klarigi al ĉiuj, ke la aparato estas vere sinkronigita per atoma horloĝo.

Tiuj, kiuj deziras, povas eĉ ĝisdatigi la horloĝon de sia malnova avino instalante novan mekanismon kun radiosinkronigado:

DCF77: Kiel funkcias la temposignalsistemo?

Vi povas trovi unu ĉe ebay uzante la ŝlosilvortojn "Radiokontrolita Movado".

Kaj finfine, vivhako por tiuj, kiuj legis ĉi tie. Eĉ se ne estas unu radio-signal-sendilo en la sekvaj du mil km, ne estas malfacile mem generi tian signalon. Estas programo en Google Play nomita "DCF77 Emulator" kiu eligas la signalon al aŭdiloj. Laŭ la aŭtoro, se vi envolvas la draton de la aŭdiloj ĉirkaŭ la horloĝo, ili prenos la signalon (estas interese kiel, ĉar ordinaraj aŭdiloj ne produktos signalon de 77KHz, sed ricevo verŝajne estas pro harmonioj). Sur Android 9, la programo tute ne funkciis por mi - simple estis neniu sono (aŭ eble mi ne aŭdis ĝin - ĝi estas 77KHz, finfine :), sed eble iu havos pli bonan sorton. Kelkaj, tamen, faras sin plenrajta DCF-signalo-generatoro, kiu estas facile fari sur la sama Arduino aŭ ESP32:

DCF77: Kiel funkcias la temposignalsistemo?
(fonto sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

konkludo

La DCF-sistemo montriĝis vere sufiĉe simpla kaj oportuna. Helpe de simpla kaj malmultekosta ricevilo, vi povas havi la ĝustan horon ĉiam kaj ĉie, kompreneble en la akceptejo. Ŝajnas, ke eĉ malgraŭ disvastigita cifereciĝo kaj Interreto de Aĵoj, tiaj simplaj solvoj estos postulataj dum longa tempo.

fonto: www.habr.com

Aldoni komenton