مرحبا هبر.
من المحتمل أن العديد من الذين اشتروا ساعة أو محطة أرصاد جوية قد شاهدوا الساعة التي يتم التحكم فيها عن طريق الراديو أو حتى شعار الساعة الذرية على العبوة. هذا مريح للغاية ، لأنه يكفي وضع الساعة على الطاولة ، وبعد فترة يتم ضبطها تلقائيًا على الوقت المحدد.

دعنا نتعرف على كيفية عملها ونكتب وحدة فك ترميز في بايثون.
هناك أنظمة مختلفة لمزامنة الوقت. الأكثر شعبية في أوروبا هو النظام الألماني اليابان لديها نظامها الخاص ، في الولايات المتحدة هناك نظام ، وما إلى ذلك وهلم جرا. علاوة على ذلك ، ستكون القصة حول DCF77 ، باعتبارها الأكثر ملاءمة ويمكن الوصول إليها للاستقبال في بعض الأماكن في الجزء الأوروبي من روسيا والبلدان المجاورة (قد يكون لسكان الشرق الأقصى رأي معاكس ، ومع ذلك ، يمكنهم بدورهم استقبال وتحليل الإشارة اليابانية ؛).
كل ما هو مكتوب أدناه سيكون حول DCF77.
استقبال الإشارة
DCF77 هي محطة ذات موجة طويلة تعمل على 77.5 كيلو هرتز وترسل إشارات AM. المحطة بسعة 50 كيلوواط تقع على بعد 25 كم من فرانكفورت ، بدأت العمل في عام 1959 ، في عام 1973 تم إضافة معلومات حول التاريخ إلى الوقت المحدد. الطول الموجي عند تردد 77 كيلو هرتز كبير جدًا ، لذا فإن أبعاد مجال الهوائي مناسبة جدًا أيضًا (صورة من ويكيبيديا):

مع هذا الهوائي وقدرة الإدخال ، تغطي منطقة الاستقبال تقريبًا كل أوروبا وبيلاروسيا وأوكرانيا وجزء من روسيا.

يمكن لأي شخص التسجيل. للقيام بذلك ، ما عليك سوى الانتقال إلى جهاز الاستقبال عبر الإنترنت ، حدد تردد 76.5 كيلو هرتز وتعديل USB هناك. يجب أن تظهر الصورة على النحو التالي:

في نفس المكان ، نضغط على زر التنزيل ونسجل مقطعًا مدته بضع دقائق. بالطبع ، إذا كان لديك جهاز استقبال "حقيقي" قادر على تسجيل تردد 77.5 كيلو هرتز ، فيمكنك استخدامه.
بالطبع ، عند تلقي إشارات راديو دقيقة للوقت عبر الإنترنت ، لن نحصل على وقت دقيق حقًا - يتم إرسال الإشارة مع تأخير. لكن هدفنا هو فهم بنية الإشارة فقط ، لذلك يعد التسجيل عبر الإنترنت أكثر من كافٍ. في الحياة الواقعية ، بالطبع ، تُستخدم الأجهزة المتخصصة للاستلام وفك التشفير ، وستتم مناقشتها أدناه.
لذا ، تلقينا السجل ، فلنبدأ في معالجته.
فك الإشارة
لنقم بتحميل الملف باستخدام 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()
نرى تعديل السعة النموذجي:

لتبسيط فك التشفير ، نأخذ مظروف الإشارة باستخدام تحويل هيلبرت:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000]) نتيجة موسعة:

دعنا نخفف انبعاثات الضوضاء باستخدام مرشح تمرير منخفض ، وفي نفس الوقت نحسب متوسط القيمة ، سيكون مفيدًا لاحقًا للتحليل.
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 النتيجة (الخط الأصفر): إشارة شبه مستطيلة يسهل تحليلها إلى حد ما.

арсинг
تحتاج أولاً إلى الحصول على تسلسل البت. بنية الإشارة نفسها بسيطة للغاية.

يتم تقسيم النبضات إلى فترات ثانية. إذا كانت المسافة بين النبضات 0.1 ثانية (أي طول النبضة نفسها 0.9 ثانية) ، نضيف "0" إلى تسلسل البتات ، إذا كانت المسافة 0.2 ثانية (أي الطول 0.8 ثانية) ، نضيف "1". تتم الإشارة إلى نهاية كل دقيقة بنبضة "طويلة" ، بطول 2 ثانية ، ويتم إعادة تعيين تسلسل البت إلى الصفر ، ويبدأ الملء مرة أخرى.
ما سبق يسهل كتابته بلغة بايثون.
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
نتيجة لذلك ، نحصل على سلسلة من البتات ، في مثالنا لمدة ثانيتين يبدو كالتالي:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
بالمناسبة ، من المثير للاهتمام وجود "طبقة ثانية" من البيانات في الإشارة. تسلسل البت مشفر أيضًا بـ . من الناحية النظرية ، يجب أن يوفر هذا فك تشفير أكثر قوة حتى في حالة ضعف الإشارة.
خطوتنا الأخيرة: الحصول على البيانات الفعلية. يتم إرسال وحدات البت مرة واحدة في الثانية ، لذلك لدينا 59 بتًا فقط ، يتم فيها ترميز قدر كبير جدًا من المعلومات:

يتم وصف البتات في وهم فضوليون للغاية. لم يتم استخدام أول 15 بتًا ، على الرغم من وجود خطط لاستخدامها في الخطاب العام وأنظمة الدفاع المدني. يشير البت A1 إلى أن الساعة ستتغير إلى التوقيت الصيفي في الساعة التالية. تشير البت A2 إلى أنه سيتم إضافة الساعة التالية ، والتي تستخدم أحيانًا لتصحيح الوقت وفقًا لدوران الأرض. تقوم البتات المتبقية بترميز الساعات والدقائق والثواني والتاريخ.

بالنسبة لأولئك الذين يرغبون في التجربة بمفردهم ، يتم إعطاء رمز فك التشفير تحت المفسد.
شفرة المصدر
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 بتة ، وفي نهاية كل دقيقة نحصل على الوقت المحدد. مقارنة بالطرق الأخرى لمزامنة الوقت (GPS ، على سبيل المثال ، أو لا قدر الله ، الإنترنت :) ، لا تتطلب مزامنة الراديو عمليًا الكهرباء - على سبيل المثال ، تعمل محطة طقس منزلية عادية لمدة عام تقريبًا على بطاريتين AA. لذلك ، حتى ساعات اليد تُصنع بمزامنة الراديو ، ناهيك عن ساعات الحائط أو ساعات محطات الشوارع بالطبع.
تجذب راحة وبساطة DCF أيضًا عشاق DIY. مقابل 10-20 دولارًا فقط ، يمكنك شراء وحدة هوائي جاهزة مع جهاز استقبال جاهز ومخرج TTL يمكن توصيله بوحدة تحكم Arduino أو وحدة تحكم أخرى.

لاردوينو مكتوبة بالفعل و . ومع ذلك ، فمن المعروف بالفعل أنه مهما فعلت على المتحكم الدقيق ، ستحصل إما على ساعة أو محطة طقس. باستخدام مثل هذا الجهاز ، يكون الحصول على الوقت المحدد أمرًا سهلاً حقًا ، ما لم تكن بالطبع في منطقة الاستقبال. حسنًا ، يمكنك تعليق نقش "الساعة الذرية" على الساعة ، وفي نفس الوقت تشرح للجميع أن الجهاز متزامن حقًا باستخدام ساعة ذرية.
يمكن لمن يرغبون حتى ترقية ساعة الجدة العجوز عن طريق تثبيت آلية جديدة بمزامنة الراديو:

يمكنك العثور على واحد على موقع ئي باي باستخدام الكلمات الرئيسية "حركة تسيطر عليها راديو".
وأخيرًا، إليكم حيلة مفيدة لمن وصلوا إلى هنا. حتى لو لم يكن هناك أي جهاز إرسال لاسلكي في نطاق بضعة آلاف من الكيلومترات، فمن السهل توليد إشارة بنفسك. يوجد تطبيق على متجر جوجل بلاي يُسمى "DCF77 Emulator" يُخرج إشارة إلى سماعات الرأس. يدّعي مطوّر التطبيق أنه إذا لففت سلك سماعة الرأس حول الساعة، فستلتقط الإشارة (أتساءل كيف، بما أن سماعات الرأس العادية لا تُصدر إشارة بتردد 77 كيلوهرتز، ولكن ربما يعود ذلك إلى التوافقيات). على ساعتي... Android لم ينجح البرنامج رقم 9 إطلاقاً - لم يصدر أي صوت (أو ربما لم أسمعه - فهو بتردد 77 كيلوهرتز، على أي حال :))، ولكن ربما يحالف الحظ شخصاً آخر. مع ذلك، يقوم بعض الأشخاص ببناء مولد إشارة DCF متكامل خاص بهم، وهو أمر سهل الصنع باستخدام أردوينو أو ESP32.

(المصدر )
اختتام
تبين أن نظام DCF بسيط للغاية ومريح حقًا. بمساعدة جهاز استقبال بسيط ورخيص ، يمكنك الحصول على الوقت المحدد دائمًا وفي كل مكان ، بالطبع في منطقة الاستقبال. يبدو أنه على الرغم من الانتشار الواسع للرقمنة و "إنترنت الأشياء" ، فإن مثل هذه الحلول البسيطة ستكون مطلوبة لفترة طويلة قادمة.
المصدر: www.habr.com
