DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Hola Habr.

Probablemente muchos, al adquirir un reloj o una estación meteorológica, hayan visto en el embalaje el logotipo Radio Controlled Clock o incluso Atomic Clock. Es muy conveniente, ya que es suficiente con colocar el reloj sobre la mesa, y en un tiempo, se ajustará automáticamente a la hora exacta.
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Vamos a analizar cómo funciona esto y escribir un decodificador en el lenguaje Python.

Existen diferentes sistemas de sincronización de tiempo. El más popular en Europa es el sistema alemán DCF-77, en Japón hay su propio sistema JJY, en EE. UU. hay un sistema WWVB, y así sucesivamente. A continuación, el relato será sobre DCF77, como el más pertinente y accesible para recibir en algunas partes de la parte europea de Rusia y países vecinos (los residentes del Lejano Oriente pueden tener una opinión opuesta; sin embargo, a su vez, pueden recibir y analizar la señal japonesa;)

Todo lo escrito a continuación será sobre DCF77.

Recepción de la señal

DCF77 es una estación de onda larga que opera en la frecuencia de 77.5 kHz, y transmite señales en modulación de amplitud. La estación con una potencia de 50 kW está situada a 25 km de Frankfurt, comenzó a funcionar en 1959, y en 1973 se agregó información sobre la fecha al tiempo exacto. La longitud de onda a una frecuencia de 77 kHz es bastante grande, por lo que el tamaño del campo antena también es considerable (foto de Wikipedia):
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Con esta antena y potencia suministrada, la zona de recepción abarca casi toda Europa, Bielorrusia, Ucrania y parte de Rusia.

DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Cualquiera puede grabar la señal. Para ello, es suficiente con entrar en un receptor en línea http://websdr.ewi.utwente.nl:8901/, elegir allí la frecuencia 76.5 kHz y la modulación USB. Debería abrirse una imagen aproximadamente de este tipo:

DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Allí también presionamos el botón de descarga y grabamos un fragmento de varios minutos. Por supuesto, si se tiene un «verdadero» receptor capaz de grabar la frecuencia de 77.5 kHz, se puede usar también este.

Por supuesto, al recibir señales de radio de tiempo exacto a través de Internet, no obtendremos realmente la hora exacta: la señal se transmite con retraso. Pero nuestro objetivo es solo entender la estructura de la señal, para esto las grabaciones de internet son más que suficientes. En realidad, por supuesto, se utilizan dispositivos especializados para la recepción y decodificación, de los cuales se hablará más adelante.

Así que, hemos recibido la grabación, comencemos a procesarla.

Decodificación de la señal

Cargaremos un archivo con Python y veremos su estructura:

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 una modulación de amplitud típica:
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Para simplificar la decodificación, tomaremos la envoltura de la señal usando la transformación de Hilbert:

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

El resultado ampliado:
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Suavizaremos los picos de interferencia utilizando un filtro de paso bajo y calcularemos el valor medio, que será útil más tarde para el análisis.

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

El resultado (línea amarilla): una señal casi rectangular, que es bastante fácil de analizar.
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Análisis

Primero debemos obtener la secuencia de bits. La estructura de la señal es muy simple.
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Los pulsos están divididos en intervalos de un segundo. Si la distancia entre pulsos es de 0.1 s (es decir, la duración del pulso es de 0.9 s), añadimos "0" a la secuencia de bits, si la distancia es de 0.2 s (es decir, la duración es de 0.8 s), añadimos "1". El final de cada minuto se marca con un "pulso largo" de 2 s, y la secuencia de bits se restablece, comenzando de nuevo.

Lo que se ha escrito anteriormente no es difícil de codificar en Python.

sig_start, sig_stop = 0, 0
pos = 0
bits_str = ""
while pos < cnt - 4:
    if A[pos]  avg:
        # Inicio de la señal
        sig_start = pos
    if A[pos] > avg and A[pos+1] < avg:
        # Fin de la señal
        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

Como resultado, obtenemos una secuencia de bits, en nuestro ejemplo para dos segundos parece así:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Curiosamente, hay también una "segunda capa" de datos en la señal. La secuencia de bits también está codificada utilizando modulación de fase. Teóricamente, esto debería proporcionar una decodificación más robusta incluso en caso de señal debilitada.

Nuestro último paso: obtener los datos propiamente dichos. Los bits se transmiten una vez por segundo, por lo que solo tenemos 59 bits, en los que se codifica bastante información:
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Los bits se describen en Wikipedia, y son bastante curiosos. Los primeros 15 bits no se utilizan, aunque había planes de usarlos para sistemas de alerta y defensa civil. El bit A1 indica que la próxima hora los relojes se ajustarán a la hora de verano. El bit A2 indica que se añadirá un segundo adicional, que a veces se utiliza para corregir el tiempo según la rotación de la Tierra. Los otros bits codifican las horas, minutos, segundos y la fecha.

DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Para aquellos que deseen experimentar por sí mismos, el código para la decodificación se encuentra debajo del spoiler.
Código fuente

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 = ('Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo')
    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)

Al ejecutar el programa, veremos una salida similar a esta:

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

En esencia, esa es toda la magia. La ventaja de este sistema es que la decodificación es extremadamente simple y puede hacerse en cualquier microcontrolador de baja complejidad. Solo contamos la duración de los pulsos, acumulamos 60 bits, y al final de cada minuto obtenemos la hora exacta. Comparado con otros métodos de sincronización de tiempo (GPS por ejemplo, o ni hablar, Internet:), esta sincronización por radio prácticamente no requiere energía — por ejemplo, una estación meteorológica doméstica normal funciona alrededor de un año con 2 baterías AA. Por eso, incluso los relojes de pulsera se hacen con sincronización por radio, sin mencionar, por supuesto, los relojes de pared o los de estaciones de tren.

La conveniencia y simplicidad del DCF también atrae a los aficionados al bricolaje. Por solo 10-20$ se puede comprar un módulo listo con antena y receptor integrado con salida TTL, que se puede conectar a un Arduino o a otro controlador.
DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Ya se han escrito bibliotecas para Arduino y bibliotecas listas. Sin embargo, es algo bien conocido: lo que sea que hagas con un microcontrolador, terminarás obteniendo ya sea un reloj o una estación meteorológica. Con un dispositivo así, realmente no es complicado obtener la hora exacta, siempre que te encuentres en una zona de recepción. También se puede poner en el reloj la inscripción «Reloj Atómico» y explicar a todos los interesados que el dispositivo de hecho se sincroniza a través de relojes atómicos.

Los interesados incluso pueden actualizar los viejos relojes de la abuela, instalando un nuevo mecanismo con sincronización por radio:

DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?

Se puede encontrar uno de estos en eBay con las palabras clave «Movimiento Controlado por Radio».

Y finalmente, un truco para aquellos que han llegado hasta aquí. Incluso si no hay ningún transmisor de señal de radio en los próximos miles de kilómetros, no es difícil generar tal señal de forma independiente. En Google Play hay una aplicación llamada «Emulador DCF77», que envía la señal a los auriculares. Según el autor, si envuelves el cable de los auriculares alrededor del reloj, captarán la señal (es interesante cómo, porque los auriculares normales no emitirán una señal de 77 kHz, pero probablemente la recepción se deba a los armónicos). En mi Android 9, la aplicación no funcionó en absoluto; simplemente no había sonido (o quizás no lo escuché, dado que es 77 kHz :), pero puede que a alguien le funcione mejor. Algunos, sin embargo, construyen un generador completo de señales DCF, que no es difícil de hacer con la misma Arduino o ESP32:

DCF77: ¿cómo funciona el sistema de transmisión de señales de tiempo exacto?
(fuente sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Conclusión

El sistema DCF resultó ser realmente bastante simple y conveniente. Con un receptor sencillo y barato, se puede tener la hora exacta siempre y en todas partes, por supuesto, en la zona de recepción. Considero que, a pesar de la digitalización generalizada y del «Internet de las Cosas», estas soluciones simples seguirán siendo demandadas durante mucho tiempo.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster