Hai Habr.
Mungkin banyak orang yang membeli jam tangan atau stasiun cuaca melihat logo Radio Controlled Clock atau bahkan Atomic Clock pada kemasannya. Ini sangat nyaman, karena cukup untuk meletakkan jam di atas meja, dan setelah beberapa saat mereka akan secara otomatis menyesuaikan dengan waktu yang tepat.

Mari kita lihat cara kerjanya dan menulis dekoder dengan Python.
Ada beberapa sistem sinkronisasi waktu. Yang paling populer di Eropa adalah sistem
DCF-77 Jerman, Jepang memiliki sistem
JJY sendiri, AS memiliki sistem
WWVB , dan sebagainya. Lebih jauh, ceritanya akan tentang DCF77, sebagai yang paling relevan dan tersedia untuk penerimaan di beberapa tempat di bagian Eropa Rusia dan negara-negara tetangga (penduduk Timur Jauh mungkin memiliki pendapat yang berlawanan, namun mereka, pada gilirannya, dapat menerima dan menganalisis sinyal Jepang;).
Semua yang tertulis di bawah ini adalah tentang DCF77.
Penerimaan sinyal
DCF77 adalah stasiun gelombang panjang yang beroperasi pada frekuensi 77,5 KHz, dan mentransmisikan sinyal dalam modulasi amplitudo. Stasiun dengan kapasitas 50 kW terletak 25 km dari Frankfurt, mulai bekerja kembali pada tahun 1959, pada tahun 1973 informasi tanggal ditambahkan ke waktu yang tepat. Panjang gelombang pada frekuensi 77KHz sangat besar, sehingga dimensi bidang antena juga sangat baik (foto dari Wikipedia):

Dengan antena dan input daya seperti itu, area penerimaan mencakup hampir seluruh Eropa, Belarus, Ukraina, dan bagian dari Rusia.

Setiap orang dapat merekam sinyal. Untuk melakukan ini, cukup buka penerima online
http://websdr.ewi.utwente.nl:8901/ , pilih frekuensi di sana 76,5KHz dan modulasi USB. Gambar sesuatu seperti ini seharusnya terbuka:

Di sana kami menekan tombol unduh dan merekam sebuah fragmen selama beberapa menit. Tentu saja, jika Anda memiliki penerima "nyata" yang mampu merekam frekuensi 77,5KHz, Anda dapat menggunakannya.
Tentu saja, ketika kita menerima sinyal radio dari waktu yang tepat melalui Internet, kita tidak akan mendapatkan waktu yang sangat akurat - sinyal ditransmisikan dengan penundaan. Tetapi tujuan kami hanya untuk memahami struktur sinyal, karena rekaman internet ini lebih dari cukup. Dalam kehidupan nyata, tentu saja, perangkat khusus untuk menerima dan mendekode digunakan, mereka akan dibahas di bawah.
Jadi, kami punya catatan, mari mulai memprosesnya.
Penguraian sinyal
Unduh file menggunakan Python dan lihat strukturnya:
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()
Kami melihat modulasi amplitudo yang khas:

Untuk menyederhanakan decoding, kami mengambil amplop sinyal menggunakan transformasi Hilbert:
analytic_signal = signal.hilbert(data) A = np.abs(analytic_signal) plt.plot(A[:100000])
Menghasilkan tampilan yang diperbesar:

Kami memuluskan emisi dari gangguan menggunakan filter low-pass, pada saat yang sama kami menghitung nilai rata-rata, itu akan berguna nanti untuk penguraian.
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
Hasil (garis kuning): sinyal hampir persegi panjang yang cukup mudah dianalisis.

Parsing
Pertama, Anda perlu mendapatkan urutan bit. Struktur sinyal itu sendiri sangat sederhana.

Pulsa dibagi menjadi interval kedua. Jika jarak antara pulsa adalah 0,1 detik (yaitu panjang pulsa itu sendiri adalah 0,9 detik), tambahkan "0" ke urutan bit, jika jaraknya 0,2 detik (yaitu panjangnya 0,8 detik), tambahkan "1". Akhir setiap menit ditandai dengan pulsa "panjang", panjang 2 detik, urutan bit diatur ulang ke nol, dan pengisian dimulai lagi.
Di atas mudah untuk menulis dengan Python.
sig_start, sig_stop = 0, 0 pos = 0 bits_str = "" while pos < cnt - 4: if A[pos] < avg and A[pos+1] > avg:
Sebagai hasilnya, kami mendapatkan urutan bit, dalam contoh kami selama dua menit kelihatannya seperti ini:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Ngomong-ngomong, sangat menarik bahwa ada "lapisan kedua" data dalam sinyal. Urutan bit juga dikodekan menggunakan
modulasi fase . Secara teoritis, ini harus memberikan decoding yang lebih stabil bahkan dalam kasus sinyal lemah.
Langkah terakhir kami: dapatkan data aktual. Bit dikirimkan sekali per detik, jadi kami hanya memiliki 59 bit, di mana banyak informasi dikodekan:

Bit-bit tersebut dideskripsikan di
Wikipedia , dan mereka cukup ingin tahu. 15 bit pertama tidak digunakan, meskipun ada rencana untuk digunakan untuk sistem peringatan
dan pertahanan sipil . Bit A1 menunjukkan bahwa dalam jam berikutnya jam akan diatur ke waktu musim panas. Bit A2 menunjukkan bahwa satu
detik tambahan akan ditambahkan dalam satu jam berikutnya, yang kadang-kadang digunakan untuk memperbaiki waktu sesuai dengan rotasi Bumi. Bit yang tersisa menyandikan jam, menit, dan tanggal.

Bagi mereka yang ingin bereksperimen sendiri, kode untuk decoding diberikan di bawah spoiler.
Kode sumber 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)
Menjalankan program, kita akan melihat sesuatu seperti ini:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
Sebenarnya, itu semua ajaib. Keuntungan dari sistem seperti itu adalah bahwa decoding sangat sederhana, dan dapat dilakukan pada mikrokontroler yang paling sederhana. Hitung saja panjang pulsa, terakumulasi 60 bit, dan pada akhir setiap menit kita mendapatkan waktu yang tepat. Dibandingkan dengan metode lain sinkronisasi waktu (GPS, misalnya, atau Tuhan melarang, Internet :), sinkronisasi radio seperti itu praktis tidak memerlukan listrik - misalnya, stasiun cuaca rumah biasa bekerja sekitar satu tahun dari 2 baterai AA. Karena itu, bahkan jam tangan dibuat dengan sinkronisasi radio, belum lagi tentu saja, tentang dinding atau stasiun jalan.
Kenyamanan dan kesederhanaan DCF menarik para pecinta produk buatan sendiri. Hanya dengan $ 10-20, Anda dapat membeli modul yang sudah jadi dari antena dengan penerima yang sudah jadi dan output TTL, yang dapat dihubungkan ke Arduino atau pengontrol lainnya.

Untuk Arduino,
perpustakaan yang sudah jadi sudah ditulis. Namun, sudah diketahui bahwa apa pun yang Anda lakukan pada mikrokontroler, Anda mendapatkan jam atau stasiun cuaca. Dengan perangkat seperti itu, mendapatkan waktu yang tepat sangat mudah, asalkan Anda berada di area penerimaan. Nah, Anda bisa menggantung tulisan "Jam Atom" di jam tangan, dan pada saat yang sama menjelaskan kepada semua orang yang menginginkannya, bahwa perangkat itu benar-benar disinkronkan menggunakan jam atom.
Mereka yang menginginkannya bahkan dapat memutakhirkan jam tangan nenek mereka dengan memasang mekanisme baru dengan sinkronisasi radio di dalamnya:

Anda dapat menemukannya di ebay menggunakan kata kunci “Gerakan Radio Controlled”.
Dan akhirnya, hack kehidupan bagi mereka yang telah membaca di sini. Bahkan jika tidak ada satu pemancar sinyal radio dalam beberapa ribu km berikutnya, sinyal seperti itu mudah dihasilkan secara mandiri. Google Play memiliki program yang disebut "DCF77 Emulator" yang mengeluarkan sinyal ke headphone. Menurut penulis, jika Anda membungkus kabel headphone di sekitar jam tangan, mereka akan menangkap sinyal (saya bertanya-tanya bagaimana, karena headphone biasa tidak akan memberikan sinyal 77KHz, tetapi mungkin penerimaannya berasal dari harmonik). Program saya sama sekali tidak bekerja di Android 9 - sama sekali tidak ada suara (atau mungkin saya tidak mendengarnya - 77KHz, setelah semua :), tapi mungkin seseorang akan lebih beruntung. Namun, beberapa membuat diri mereka generator sinyal DCF lengkap, yang mudah dilakukan pada Arduino atau ESP32 yang sama:

(sumber
sgfantasytoys.wordpress.com/2015/05/13/sinkronkan-radio-controlled-watch-without-access )
Kesimpulan
Sistem DCF ternyata sangat sederhana dan nyaman. Dengan bantuan penerima yang sederhana dan murah, Anda dapat memiliki waktu yang tepat kapan saja, di mana saja, tentu saja, di area penerimaan. Tampaknya meskipun ada digitalisasi yang meluas dan "Internet of things", solusi sederhana seperti itu akan diminati dalam waktu yang lama.