DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Γεια σου Χαμπρ.

Πιθανώς πολλοί που αγοράζουν ένα ρολόι ή μετεωρολογικό σταθμό έχουν δει το λογότυπο με ραδιοελεγχόμενο ρολόι ή ακόμα και το λογότυπο Atomic Clock στη συσκευασία. Αυτό είναι πολύ βολικό, γιατί απλά πρέπει να βάλετε το ρολόι στο τραπέζι και μετά από λίγο θα προσαρμοστεί αυτόματα στην ακριβή ώρα.
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Ας καταλάβουμε πώς λειτουργεί και ας γράψουμε έναν αποκωδικοποιητή στην Python.

Υπάρχουν διαφορετικά συστήματα συγχρονισμού χρόνου. Το πιο δημοφιλές στην Ευρώπη είναι το γερμανικό σύστημα DCF-77, η Ιαπωνία έχει το δικό της σύστημα JJY, στις ΗΠΑ υπάρχει σύστημα WWVB, και ούτω καθεξής. Στη συνέχεια, η ιστορία θα αφορά το DCF77, ως το πιο σχετικό και προσβάσιμο για υποδοχή σε ορισμένα μέρη στο ευρωπαϊκό τμήμα της Ρωσίας και των γειτονικών χωρών (οι κάτοικοι της Άπω Ανατολής μπορεί να έχουν αντίθετη γνώμη, ωστόσο, με τη σειρά τους, μπορούν να λάβουν και αναλύστε το ιαπωνικό σήμα.).

Όλα όσα γράφονται παρακάτω θα αφορούν το DCF77.

Λήψη σήματος

Ο DCF77 είναι ένας σταθμός μεγάλων κυμάτων που λειτουργεί σε συχνότητα 77.5 kHz και εκπέμπει σήματα σε διαμόρφωση πλάτους. Ο σταθμός 50 KW βρίσκεται 25 χλμ. από τη Φρανκφούρτη, ξεκίνησε τη λειτουργία του το 1959 και το 1973 προστέθηκαν πληροφορίες ημερομηνίας στην ακριβή ώρα. Το μήκος κύματος σε συχνότητα 77 KHz είναι πολύ μεγάλο, επομένως οι διαστάσεις του πεδίου της κεραίας είναι επίσης αρκετά αξιοπρεπείς (φωτογραφία από τη Wikipedia):
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Με μια τέτοια είσοδο κεραίας και ισχύος, ο χώρος λήψης καλύπτει σχεδόν όλη την Ευρώπη, τη Λευκορωσία, την Ουκρανία και μέρος της Ρωσίας.

DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Οποιοσδήποτε μπορεί να ηχογραφήσει ένα σήμα. Για να το κάνετε αυτό, απλώς μεταβείτε στον διαδικτυακό δέκτη http://websdr.ewi.utwente.nl:8901/, επιλέξτε τη συχνότητα 76.5KHz και τη διαμόρφωση USB εκεί. Θα πρέπει να ανοίξει μια εικόνα που μοιάζει κάπως έτσι:

DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Εκεί πατάμε το κουμπί λήψης και καταγράφουμε ένα κομμάτι πολλών λεπτών. Φυσικά, εάν έχετε έναν «πραγματικό» δέκτη ικανό να καταγράφει τη συχνότητα των 77.5 KHz, μπορείτε να τον χρησιμοποιήσετε.

Φυσικά, με τη λήψη σημάτων ώρας ραδιοφώνου μέσω του Διαδικτύου, δεν θα λάβουμε πραγματικά ακριβή χρόνο - το σήμα μεταδίδεται με καθυστέρηση. Αλλά ο στόχος μας είναι μόνο να κατανοήσουμε τη δομή του σήματος· γι' αυτό, η εγγραφή στο Διαδίκτυο είναι υπεραρκετή. Στην πραγματική ζωή, φυσικά, χρησιμοποιούνται εξειδικευμένες συσκευές για τη λήψη και την αποκωδικοποίηση· θα συζητηθούν παρακάτω.

Λοιπόν, λάβαμε την ηχογράφηση, ας ξεκινήσουμε την επεξεργασία της.

Αποκωδικοποίηση σήματος

Ας φορτώσουμε το αρχείο χρησιμοποιώντας Python και ας δούμε τη δομή του:

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

Βλέπουμε τυπική διαμόρφωση πλάτους:
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Για να απλοποιήσουμε την αποκωδικοποίηση, ας πάρουμε το φάκελο του σήματος χρησιμοποιώντας τον μετασχηματισμό Hilbert:

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

Μεγαλωμένο αποτέλεσμα:
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Ας εξομαλύνουμε τις εκπομπές θορύβου χρησιμοποιώντας ένα χαμηλοπερατό φίλτρο και ας υπολογίσουμε ταυτόχρονα τη μέση τιμή, η οποία θα είναι χρήσιμη αργότερα για την ανάλυση.

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

Αποτέλεσμα (κίτρινη γραμμή): ένα σχεδόν τετράγωνο σήμα κύματος που είναι αρκετά εύκολο να αναλυθεί.
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Πάρσινγκ

Πρώτα πρέπει να λάβετε την ακολουθία bit. Η ίδια η δομή του σήματος είναι πολύ απλή.
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Οι παλμοί χωρίζονται σε δεύτερα διαστήματα. Εάν η απόσταση μεταξύ των παλμών είναι 0.1 δευτ. (δηλαδή το μήκος του ίδιου του παλμού είναι 0.9 δευτ.), προσθέστε "0" στην ακολουθία δυαδικών ψηφίων· εάν η απόσταση είναι 0.2 δευτ. (δηλαδή το μήκος είναι 0.8 δευτ.), προσθέστε "1". Το τέλος κάθε λεπτού υποδεικνύεται με έναν «μακρύ» παλμό, διάρκειας 2 δευτερολέπτων, η ακολουθία bit μηδενίζεται και η πλήρωση ξεκινά ξανά.

Τα παραπάνω είναι εύκολο να γραφτούν σε 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

Ως αποτέλεσμα, παίρνουμε μια ακολουθία bit, στο παράδειγμά μας για δύο δευτερόλεπτα μοιάζει με αυτό:

0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000

Παρεμπιπτόντως, είναι ενδιαφέρον ότι το σήμα έχει επίσης ένα "δεύτερο επίπεδο" δεδομένων. Η ακολουθία bit κωδικοποιείται επίσης χρησιμοποιώντας διαμόρφωση φάσης. Θεωρητικά, αυτό θα πρέπει να παρέχει πιο ισχυρή αποκωδικοποίηση ακόμη και στην περίπτωση εξασθενημένου σήματος.

Το τελευταίο μας βήμα: λήψη των πραγματικών δεδομένων. Τα bit μεταδίδονται μία φορά το δευτερόλεπτο, επομένως έχουμε συνολικά 59 bit, στα οποία κωδικοποιούνται πολλές πληροφορίες:
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Τα bit περιγράφονται στο Wikipedia, και είναι αρκετά περίεργοι. Τα πρώτα 15 bit δεν χρησιμοποιούνται, αν και υπήρχαν σχέδια να χρησιμοποιηθούν για συστήματα προειδοποίησης και πολιτική άμυνα. Το bit A1 υποδεικνύει ότι το ρολόι θα αλλάξει σε θερινή ώρα την επόμενη ώρα. Το bit A2 υποδεικνύει ότι ένα πρόσθετο άλμα δευτερόλεπτο, το οποίο μερικές φορές χρησιμοποιείται για τη ρύθμιση του χρόνου σύμφωνα με την περιστροφή της Γης. Τα υπόλοιπα bit κωδικοποιούν ώρες, λεπτά, δευτερόλεπτα και ημερομηνία.

DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Για όσους θέλουν να πειραματιστούν μόνοι τους, ο κωδικός αποκωδικοποίησης δίνεται κάτω από το spoiler.
Κωδικός πηγής

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)

Όταν εκτελούμε το πρόγραμμα, θα δούμε έξοδο παρόμοια με αυτό:

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

Στην πραγματικότητα, αυτή είναι όλη η μαγεία. Το πλεονέκτημα ενός τέτοιου συστήματος είναι ότι η αποκωδικοποίηση είναι εξαιρετικά απλή και μπορεί να γίνει σε οποιονδήποτε, ακόμη και στον πιο απλό μικροελεγκτή. Απλώς μετράμε το μήκος των παλμών, συγκεντρώνουμε 60 bit και στο τέλος κάθε λεπτού παίρνουμε τον ακριβή χρόνο. Σε σύγκριση με άλλες μεθόδους συγχρονισμού χρόνου (GPS, για παράδειγμα, ή Θεός φυλάξοι, το Διαδίκτυο:), αυτός ο συγχρονισμός ραδιοφώνου δεν απαιτεί σχεδόν καθόλου ηλεκτρισμό - για παράδειγμα, ένας κανονικός μετεωρολογικός σταθμός στο σπίτι λειτουργεί για περίπου ένα χρόνο με 2 μπαταρίες AA. Επομένως, ακόμη και τα ρολόγια χειρός κατασκευάζονται με συγχρονισμό ραδιοφώνου, για να μην αναφέρουμε, φυσικά, τα ρολόγια τοίχου ή τα ρολόγια σταθμών δρόμου.

Η ευκολία και η απλότητα του DCF προσελκύει επίσης τους λάτρεις των DIY. Με μόλις 10-20 $ μπορείτε να αγοράσετε μια έτοιμη μονάδα κεραίας με έτοιμο δέκτη και έξοδο TTL, η οποία μπορεί να συνδεθεί σε ένα Arduino ή άλλο ελεγκτή.
DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Έχει ήδη γραφτεί για το Arduino έτοιμες βιβλιοθήκες. Ωστόσο, είναι ήδη γνωστό ότι ό,τι και να κάνεις σε έναν μικροελεγκτή, καταλήγεις είτε με ρολόι είτε με μετεωρολογικό σταθμό. Με μια τέτοια συσκευή, είναι πολύ εύκολο να βρείτε την ακριβή ώρα, με την προϋπόθεση βέβαια ότι βρίσκεστε στο χώρο της ρεσεψιόν. Λοιπόν, μπορείτε να κρεμάσετε την επιγραφή "Atomic Clock" στο ρολόι σας και ταυτόχρονα να εξηγήσετε σε όλους ότι η συσκευή είναι πραγματικά συγχρονισμένη χρησιμοποιώντας ένα ατομικό ρολόι.

Όσοι επιθυμούν μπορούν ακόμη και να αναβαθμίσουν το ρολόι της παλιάς γιαγιάς τους εγκαθιστώντας έναν νέο μηχανισμό με ραδιοσυγχρονισμό:

DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;

Μπορείτε να βρείτε ένα στο ebay χρησιμοποιώντας τις λέξεις-κλειδιά "Radio Controlled Movement".

Και τέλος, ένα life hack για όσους έχουν διαβάσει ως εδώ. Ακόμα κι αν δεν υπάρχει ούτε ένας πομπός ραδιοφωνικού σήματος στα επόμενα δύο χιλιάδες χιλιόμετρα, δεν είναι δύσκολο να δημιουργήσετε μόνοι σας ένα τέτοιο σήμα. Υπάρχει ένα πρόγραμμα στο Google Play που ονομάζεται "DCF77 Emulator" που εξάγει το σήμα στα ακουστικά. Σύμφωνα με τον συγγραφέα, αν τυλίξετε το καλώδιο των ακουστικών γύρω από το ρολόι, θα πάρουν το σήμα (είναι ενδιαφέρον πώς, γιατί τα συνηθισμένα ακουστικά δεν θα παράγουν σήμα 77KHz, αλλά η λήψη οφείλεται πιθανώς σε αρμονικές). Στο Android 9, το πρόγραμμα δεν λειτούργησε καθόλου για μένα - απλά δεν υπήρχε ήχος (ή ίσως δεν τον άκουσα - είναι 77KHz, τελικά :), αλλά ίσως κάποιος θα έχει καλύτερη τύχη. Ορισμένοι, ωστόσο, κάνουν τον εαυτό τους μια πλήρη γεννήτρια σήματος DCF, η οποία είναι εύκολο να κατασκευαστεί στο ίδιο Arduino ή ESP32:

DCF77: πώς λειτουργεί το σύστημα σηματοδότησης ώρας;
(πηγή sgfantasytoys.wordpress.com/2015/05/13/synchronize-radio-controlled-watch-without-access)

Συμπέρασμα

Το σύστημα DCF αποδείχθηκε πολύ απλό και βολικό. Με τη βοήθεια ενός απλού και φθηνού δέκτη, μπορείτε να έχετε την ακριβή ώρα πάντα και παντού, φυσικά στον χώρο της ρεσεψιόν. Φαίνεται ότι ακόμη και παρά την εκτεταμένη ψηφιοποίηση και το Διαδίκτυο των Πραγμάτων, τέτοιες απλές λύσεις θα είναι περιζήτητες για πολύ καιρό.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο