DCF77: Como funciona o sistema de sinalização horária?

Olá Habr.

Provavelmente muitos que compram um relógio ou estação meteorológica viram o logotipo do Relógio Controlado por Rádio ou mesmo do Relógio Atômico na embalagem. Isso é muito prático, pois basta colocar o relógio sobre a mesa e depois de um tempo ele se ajustará automaticamente à hora exata.
DCF77: Como funciona o sistema de sinalização horária?

Vamos descobrir como funciona e escrever um decodificador em Python.

Existem diferentes sistemas de sincronização de tempo. O mais popular na Europa é o sistema alemão DCF-77, o Japão tem seu próprio sistema JJY, nos EUA existe um sistema WWVB, e assim por diante. A seguir, a história será sobre o DCF77, como o mais relevante e acessível para recepção em alguns locais da parte européia da Rússia e países vizinhos (os residentes do Extremo Oriente podem ter opinião contrária, porém, eles, por sua vez, podem receber e analise o sinal japonês;).

Tudo o que está escrito abaixo será sobre o DCF77.

Recepção de sinal

DCF77 é uma estação de ondas longas operando na frequência de 77.5 kHz e transmitindo sinais em modulação de amplitude. A estação 50KW está localizada a 25 km de Frankfurt, começou a operar em 1959, e em 1973 foram acrescentadas informações de data à hora exata. O comprimento de onda na frequência de 77 KHz é muito longo, então as dimensões do campo da antena também são bastante decentes (foto da Wikipedia):
DCF77: Como funciona o sistema de sinalização horária?

Com tal antena e entrada de energia, a área de recepção cobre quase toda a Europa, Bielorrússia, Ucrânia e parte da Rússia.

DCF77: Como funciona o sistema de sinalização horária?

Qualquer um pode gravar um sinal. Para fazer isso, basta acessar o receptor online http://websdr.ewi.utwente.nl:8901/, selecione a frequência 76.5KHz e a modulação USB lá. Deve abrir uma imagem parecida com esta:

DCF77: Como funciona o sistema de sinalização horária?

Lá pressionamos o botão de download e gravamos um fragmento de vários minutos. Claro, se você tiver um receptor “real” capaz de gravar a frequência de 77.5 KHz, você poderá usá-lo.

É claro que, ao receber sinais de tempo de rádio pela Internet, não receberemos um tempo verdadeiramente preciso - o sinal é transmitido com atraso. Mas nosso objetivo é apenas entender a estrutura do sinal, para isso a gravação pela Internet é mais que suficiente. Na vida real, é claro, são usados ​​dispositivos especializados para recepção e decodificação; eles serão discutidos abaixo.

Então, recebemos a gravação, vamos começar a processá-la.

Decodificação de Sinal

Vamos carregar o arquivo usando Python e ver sua estrutura:

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

Vemos modulação de amplitude típica:
DCF77: Como funciona o sistema de sinalização horária?

Para simplificar a decodificação, vamos pegar o envelope do sinal usando a transformada de Hilbert:

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

Resultado ampliado:
DCF77: Como funciona o sistema de sinalização horária?

Vamos suavizar as emissões de ruído usando um filtro passa-baixa e, ao mesmo tempo, calcular o valor médio, que será útil posteriormente para análise.

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

Resultado (linha amarela): um sinal de onda quase quadrada e bastante fácil de analisar.
DCF77: Como funciona o sistema de sinalização horária?

Análise

Primeiro você precisa obter a sequência de bits. A estrutura do sinal em si é muito simples.
DCF77: Como funciona o sistema de sinalização horária?

Os pulsos são divididos em segundos intervalos. Se a distância entre os pulsos for 0.1s (ou seja, a duração do pulso em si for 0.9s), adicione “0” à sequência de bits; se a distância for 0.2s (ou seja, a duração for 0.8s), adicione “1”. O final de cada minuto é indicado por um pulso “longo”, de 2s de duração, a sequência de bits é zerada e o enchimento começa novamente.

O texto acima é fácil de escrever em 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

Como resultado, obtemos uma sequência de bits, em nosso exemplo por dois segundos fica assim:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Aliás, é interessante que o sinal também possua uma “segunda camada” de dados. A sequência de bits também é codificada usando modulação de fase. Em teoria, isso deveria fornecer uma decodificação mais robusta, mesmo no caso de um sinal enfraquecido.

Nossa última etapa: obter os dados reais. Os bits são transmitidos uma vez por segundo, então temos um total de 59 bits, nos quais muita informação é codificada:
DCF77: Como funciona o sistema de sinalização horária?

Os bits são descritos em Wikipedia, e eles são bastante curiosos. Os primeiros 15 bits não são utilizados, embora houvesse planos para utilizá-los em sistemas de alerta e defesa civil. O bit A1 indica que o relógio mudará para horário de verão na próxima hora. O bit A2 indica que um adicional segundo bissexto, que às vezes é usado para ajustar o tempo de acordo com a rotação da Terra. Os bits restantes codificam horas, minutos, segundos e data.

DCF77: Como funciona o sistema de sinalização horária?

Para quem deseja experimentar por conta própria, o código de decodificação é fornecido abaixo do spoiler.
Código fonte

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)

Quando executarmos o programa, veremos uma saída semelhante a esta:

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

Na verdade, essa é toda a magia. A vantagem de tal sistema é que a decodificação é extremamente simples e pode ser feita em qualquer microcontrolador, mesmo no mais simples. Simplesmente contamos a duração dos pulsos, acumulamos 60 bits e ao final de cada minuto obtemos a hora exata. Em comparação com outros métodos de sincronização de tempo (GPS, por exemplo, ou Deus me livre, a Internet :), essa sincronização de rádio praticamente não requer eletricidade - por exemplo, uma estação meteorológica doméstica normal funciona por cerca de um ano com 2 baterias AA. Portanto, até os relógios de pulso são feitos com sincronização de rádio, sem falar, é claro, dos relógios de parede ou de estação de rua.

A conveniência e simplicidade do DCF também atraem os entusiastas do DIY. Por apenas US$ 10-20 você pode comprar um módulo de antena pronto com um receptor pronto e saída TTL, que pode ser conectado a um Arduino ou outro controlador.
DCF77: Como funciona o sistema de sinalização horária?

Já escrito para Arduino bibliotecas prontas. Porém, já se sabe que não importa o que você faça em um microcontrolador, você terá um relógio ou uma estação meteorológica. Com esse dispositivo, obter a hora exata é muito fácil, desde, é claro, que você esteja na área de recepção. Pois bem, você pode pendurar a inscrição “Relógio Atômico” no seu relógio e ao mesmo tempo explicar a todos que o aparelho está realmente sincronizado por meio de um relógio atômico.

Quem quiser pode até atualizar o relógio da velha avó instalando um novo mecanismo com sincronização de rádio:

DCF77: Como funciona o sistema de sinalização horária?

Você pode encontrar um no ebay usando as palavras-chave “Movimento controlado por rádio”.

E, finalmente, um truque para quem leu até aqui. Mesmo que não haja um único transmissor de sinal de rádio nos próximos milhares de quilômetros, não é difícil gerar esse sinal sozinho. Existe um programa no Google Play chamado “DCF77 Emulator” que envia o sinal para fones de ouvido. Segundo o autor, se você enrolar o fio dos fones de ouvido em volta do relógio, eles captarão o sinal (é interessante como, porque fones de ouvido comuns não produzirão sinal de 77KHz, mas a recepção provavelmente se deve a harmônicos). No Android 9, o programa não funcionou para mim - simplesmente não havia som (ou talvez eu não tenha ouvido - afinal são 77KHz :), mas talvez alguém tenha mais sorte. Alguns, entretanto, tornam-se um gerador de sinal DCF completo, que é fácil de fazer no mesmo Arduino ou ESP32:

DCF77: Como funciona o sistema de sinalização horária?
(fonte sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Conclusão

O sistema DCF revelou-se bastante simples e conveniente. Com a ajuda de um receptor simples e barato, você pode ter a hora exata sempre e em qualquer lugar, claro, na área de recepção. Parece que mesmo apesar da digitalização generalizada e da Internet das Coisas, essas soluções simples serão procuradas durante muito tempo.

Fonte: habr.com

Adicionar um comentário