DCF77 : Comment fonctionne le système de signalisation horaire ?

Bonjour Habr.

Beaucoup de ceux qui achètent une montre ou une station météo ont probablement vu le logo de l'horloge radiocommandée ou même de l'horloge atomique sur l'emballage. C'est très pratique, car il vous suffit de poser l'horloge sur la table et, au bout d'un moment, elle s'ajustera automatiquement à l'heure exacte.
DCF77 : Comment fonctionne le système de signalisation horaire ?

Voyons comment cela fonctionne et écrivons un décodeur en Python.

Il existe différents systèmes de synchronisation horaire. Le système le plus populaire en Europe est le système allemand DCF-77, le Japon a son propre système JJY, aux USA il existe un système WWVB, et ainsi de suite. Ensuite, l'histoire portera sur le DCF77, comme le plus pertinent et le plus accessible pour la réception dans certains endroits de la partie européenne de la Russie et des pays voisins (les résidents de l'Extrême-Orient peuvent avoir l'opinion opposée, cependant, ils peuvent à leur tour recevoir et analyser le signal japonais ;).

Tout ce qui est écrit ci-dessous concernera le DCF77.

Réception des signaux

DCF77 est une station à ondes longues fonctionnant à une fréquence de 77.5 kHz et transmettant des signaux en modulation d'amplitude. La station de 50 kW est située à 25 km de Francfort, elle a commencé à fonctionner en 1959 et en 1973, des informations sur la date ont été ajoutées à l'heure exacte. La longueur d'onde à une fréquence de 77 KHz est très longue, donc les dimensions du champ d'antenne sont également assez correctes (photo de Wikipédia) :
DCF77 : Comment fonctionne le système de signalisation horaire ?

Avec une telle antenne et une telle puissance absorbée, la zone de réception couvre presque toute l’Europe, la Biélorussie, l’Ukraine et une partie de la Russie.

DCF77 : Comment fonctionne le système de signalisation horaire ?

N'importe qui peut enregistrer un signal. Pour ce faire, il suffit de se rendre sur le récepteur en ligne http://websdr.ewi.utwente.nl:8901/, sélectionnez-y la fréquence 76.5KHz et la modulation USB. Une image devrait s'ouvrir et ressembler à ceci :

DCF77 : Comment fonctionne le système de signalisation horaire ?

Là, nous appuyons sur le bouton de téléchargement et enregistrons un fragment de plusieurs minutes. Bien sûr, si vous disposez d’un « vrai » récepteur capable d’enregistrer la fréquence 77.5 KHz, vous pouvez l’utiliser.

Bien entendu, en recevant des signaux horaires radio via Internet, nous ne recevrons pas une heure vraiment précise - le signal est transmis avec un retard. Mais notre objectif est uniquement de comprendre la structure du signal, pour cela l'enregistrement Internet est largement suffisant. Dans la vraie vie, bien sûr, des appareils spécialisés sont utilisés pour la réception et le décodage ; ils seront abordés ci-dessous.

Nous avons donc reçu l'enregistrement, commençons à le traiter.

Décodage du signal

Chargeons le fichier en utilisant Python et voyons sa structure :

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

Nous voyons une modulation d'amplitude typique :
DCF77 : Comment fonctionne le système de signalisation horaire ?

Pour simplifier le décodage, prenons l'enveloppe du signal en utilisant la transformée de Hilbert :

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

Résultat agrandi :
DCF77 : Comment fonctionne le système de signalisation horaire ?

Lisons les émissions sonores à l'aide d'un filtre passe-bas, et calculons en même temps la valeur moyenne, qui sera utile plus tard pour l'analyse.

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

Résultat (ligne jaune) : un signal presque carré assez simple à analyser.
DCF77 : Comment fonctionne le système de signalisation horaire ?

L'analyse

Vous devez d’abord obtenir la séquence de bits. La structure du signal elle-même est très simple.
DCF77 : Comment fonctionne le système de signalisation horaire ?

Les impulsions sont divisées en secondes intervalles. Si la distance entre les impulsions est de 0.1 s (c'est-à-dire que la durée de l'impulsion elle-même est de 0.9 s), ajoutez « 0 » à la séquence de bits ; si la distance est de 0.2 s (c'est-à-dire que la durée est de 0.8 s), ajoutez « 1 ». La fin de chaque minute est signalée par une impulsion « longue » de 2 s, la séquence de bits est remise à zéro et le remplissage recommence.

Ce qui précède est facile à écrire 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

En conséquence, nous obtenons une séquence de bits, dans notre exemple pendant deux secondes, elle ressemble à ceci :

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

À propos, il est intéressant de noter que le signal possède également une « deuxième couche » de données. La séquence de bits est également codée en utilisant modulation de phase. En théorie, cela devrait permettre un décodage plus robuste, même dans le cas d'un signal affaibli.

Notre dernière étape : obtenir les données réelles. Les bits sont transmis une fois par seconde, nous avons donc un total de 59 bits, dans lesquels de nombreuses informations sont codées :
DCF77 : Comment fonctionne le système de signalisation horaire ?

Les bits sont décrits dans Wikipedia, et ils sont assez curieux. Les 15 premiers bits ne sont pas utilisés, bien qu'il soit prévu de les utiliser pour les systèmes d'alerte et la protection civile. Le bit A1 indique que l'horloge passera à l'heure d'été dans l'heure suivante. Le bit A2 indique qu'un seconde intercalaire, qui est parfois utilisé pour ajuster l'heure en fonction de la rotation de la Terre. Les bits restants codent les heures, les minutes, les secondes et la date.

DCF77 : Comment fonctionne le système de signalisation horaire ?

Pour ceux qui souhaitent expérimenter par eux-mêmes, le code de décodage est donné sous le spoiler.
Code source

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)

Lorsque nous exécutons le programme, nous verrons un résultat similaire à celui-ci :

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

En fait, c'est toute la magie. L’avantage d’un tel système est que le décodage est extrêmement simple et peut être effectué sur n’importe quel microcontrôleur, même le plus simple. Nous comptons simplement la durée des impulsions, accumulons 60 bits et à la fin de chaque minute nous obtenons l'heure exacte. Comparée à d'autres méthodes de synchronisation de l'heure (GPS, par exemple, ou à Dieu ne plaise, Internet :), une telle synchronisation radio ne nécessite pratiquement aucune électricité - par exemple, une station météo domestique ordinaire fonctionne pendant environ un an avec 2 piles AA. C'est pourquoi même les montres-bracelets sont fabriquées avec synchronisation radio, sans oublier bien sûr les montres murales ou les montres de gare routière.

La commodité et la simplicité du DCF attirent également les bricoleurs. Pour seulement 10 à 20 $, vous pouvez acheter un module d'antenne prêt à l'emploi avec un récepteur prêt à l'emploi et une sortie TTL, qui peut être connecté à un Arduino ou à un autre contrôleur.
DCF77 : Comment fonctionne le système de signalisation horaire ?

Déjà écrit pour Arduino bibliothèques prêtes à l'emploi. Cependant, on sait déjà que peu importe ce que l’on fait sur un microcontrôleur, on se retrouve avec soit une horloge, soit une station météo. Avec un tel appareil, obtenir l’heure exacte est vraiment simple, à condition bien sûr d’être dans la zone d’accueil. Eh bien, vous pouvez accrocher l'inscription «Atomic Clock» sur votre montre, et en même temps expliquer à tout le monde que l'appareil est réellement synchronisé à l'aide d'une horloge atomique.

Ceux qui le souhaitent peuvent même moderniser la montre de leur ancienne grand-mère en installant un nouveau mécanisme avec synchronisation radio :

DCF77 : Comment fonctionne le système de signalisation horaire ?

Vous pouvez en trouver un sur eBay en utilisant les mots-clés « Radio Controlled Movement ».

Et enfin, une astuce pour ceux qui ont lu jusqu'ici. Même s'il n'y a pas un seul émetteur de signal radio dans les prochains milliers de kilomètres, il n'est pas difficile de générer vous-même un tel signal. Il existe un programme sur Google Play appelé « DCF77 Emulator » qui transmet le signal au casque. Selon l'auteur, si vous enroulez le fil des écouteurs autour de la montre, ils capteront le signal (c'est intéressant de savoir comment, car les écouteurs ordinaires ne produiront pas de signal à 77 KHz, mais la réception est probablement due aux harmoniques). Sur Android 9, le programme n'a pas fonctionné du tout pour moi - il n'y avait tout simplement pas de son (ou peut-être que je ne l'ai pas entendu - c'est 77KHz, après tout :), mais peut-être que quelqu'un aura plus de chance. Certains, cependant, se fabriquent un générateur de signaux DCF à part entière, facile à réaliser sur le même Arduino ou ESP32 :

DCF77 : Comment fonctionne le système de signalisation horaire ?
(source sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-driven-watch-without-access)

Conclusion

Le système DCF s’est avéré vraiment simple et pratique. A l'aide d'un récepteur simple et bon marché, vous pouvez avoir l'heure exacte à tout moment et partout, bien sûr à la réception. Il semble que, malgré la numérisation généralisée et l’Internet des objets, des solutions aussi simples resteront demandées pendant longtemps.

Source: habr.com

Ajouter un commentaire