Helo Habr.
Mae'n debyg bod llawer sy'n prynu oriawr neu orsaf dywydd wedi gweld y Cloc a Reolir gan Radio neu hyd yn oed logo'r Cloc Atomig ar y pecyn. Mae hyn yn gyfleus iawn, oherwydd does ond angen i chi roi'r cloc ar y bwrdd, ac ar ôl ychydig bydd yn addasu'n awtomatig i'r union amser.
Gadewch i ni ddarganfod sut mae'n gweithio ac ysgrifennu datgodiwr yn Python.
Mae yna wahanol systemau cydamseru amser. Y mwyaf poblogaidd yn Ewrop yw'r system Almaeneg
Bydd popeth a ysgrifennir isod yn ymwneud â'r DCF77.
Derbyniad signal
Mae DCF77 yn orsaf tonnau hir sy'n gweithredu ar amledd o 77.5 kHz ac yn trawsyrru signalau mewn modiwleiddio osgled. Mae'r orsaf 50KW wedi'i lleoli 25 km o Frankfurt, dechreuodd weithredu ym 1959, ac ym 1973 ychwanegwyd gwybodaeth dyddiad at yr union amser. Mae'r donfedd ar amledd o 77 KHz yn hir iawn, felly mae dimensiynau'r maes antena hefyd yn eithaf gweddus (llun o Wikipedia):
Gyda mewnbwn antena a phŵer o'r fath, mae'r dderbynfa yn cwmpasu bron pob rhan o Ewrop, Belarus, yr Wcrain a rhan o Rwsia.
Gall unrhyw un recordio signal. I wneud hyn, ewch i'r derbynnydd ar-lein
Yno rydyn ni'n pwyso'r botwm llwytho i lawr ac yn recordio darn sawl munud o hyd. Wrth gwrs, os oes gennych chi dderbynnydd “go iawn” sy'n gallu cofnodi'r amledd 77.5KHz, gallwch chi ddefnyddio hynny.
Wrth gwrs, trwy dderbyn signalau amser radio trwy'r Rhyngrwyd, ni fyddwn yn derbyn amser gwirioneddol gywir - mae'r signal yn cael ei drosglwyddo gydag oedi. Ond dim ond deall strwythur y signal yw ein nod; ar gyfer hyn, mae'r recordiad Rhyngrwyd yn fwy na digon. Mewn bywyd go iawn, wrth gwrs, defnyddir dyfeisiau arbenigol ar gyfer derbyn a datgodio; fe'u trafodir isod.
Felly, rydym wedi derbyn y recordiad, gadewch i ni ddechrau ei brosesu.
Datgodio Signalau
Gadewch i ni lwytho'r ffeil gan ddefnyddio Python a gweld ei strwythur:
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()
Rydym yn gweld modiwleiddio osgled nodweddiadol:
I symleiddio datgodio, gadewch i ni gymryd yr amlen signal gan ddefnyddio trawsnewidiad Hilbert:
analytic_signal = signal.hilbert(data)
A = np.abs(analytic_signal)
plt.plot(A[:100000])
Canlyniad mwy:
Gadewch i ni lyfnhau allyriadau sŵn gan ddefnyddio hidlydd pas-isel, ac ar yr un pryd cyfrifwch y gwerth cyfartalog, a fydd yn ddefnyddiol yn ddiweddarach ar gyfer dosrannu.
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
Canlyniad (llinell felen): signal tonnau sgwâr bron sy'n eithaf hawdd i'w ddadansoddi.
Dosrannu
Yn gyntaf mae angen i chi gael y dilyniant bit. Mae'r strwythur signal ei hun yn syml iawn.
Rhennir y corbys yn ail gyfyngau. Os mai’r pellter rhwng corbys yw 0.1s (h.y. hyd y curiad ei hun yw 0.9s), ychwanegwch “0” i’r dilyniant didau; os yw’r pellter yn 0.2s (h.y. mae’r hyd yn 0.8s), ychwanegwch “1”. Mae diwedd pob munud yn cael ei nodi gan guriad “hir”, 2s o hyd, mae'r dilyniant didau yn cael ei ailosod i sero, ac mae llenwi'n dechrau eto.
Mae'r uchod yn hawdd i'w ysgrifennu yn 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
O ganlyniad, rydyn ni'n cael dilyniant o ddarnau, yn ein hesiampl am ddwy eiliad mae'n edrych fel hyn:
0011110110111000001011000001010000100110010101100010011000
0001111100110110001010100001010000100110010101100010011000
Gyda llaw, mae'n ddiddorol bod gan y signal "ail haen" o ddata hefyd. Mae'r dilyniant didau hefyd yn cael ei amgodio gan ddefnyddio
Ein cam olaf: cael y data gwirioneddol. Mae darnau'n cael eu trosglwyddo unwaith yr eiliad, felly mae gennym ni gyfanswm o 59 did, lle mae cryn dipyn o wybodaeth wedi'i hamgodio:
Disgrifir y darnau yn
I'r rhai sydd am arbrofi ar eu pen eu hunain, rhoddir y cod datgodio o dan y spoiler.
Cod ffynhonnell
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)
Pan fyddwn yn rhedeg y rhaglen, byddwn yn gweld allbwn tebyg i hyn:
0011110110111000001011000001010000100110010101100010011000
Tuesday, 26.03.19, 21:41
0001111100110110001010100001010000100110010101100010011000
Tuesday, 26.03.19, 21:42
A dweud y gwir, dyna'r holl hud. Mantais system o'r fath yw bod dadgodio yn hynod o syml a gellir ei wneud ar unrhyw un, hyd yn oed y microreolydd symlaf. Yn syml, rydyn ni'n cyfrif hyd y corbys, yn cronni 60 did, ac ar ddiwedd pob munud rydyn ni'n cael yr union amser. O'i gymharu â dulliau eraill o gydamseru amser (GPS, er enghraifft, neu Dduw yn gwahardd, y Rhyngrwyd :), cydamseru radio o'r fath yn ei gwneud yn ofynnol bron dim trydan - er enghraifft, mae gorsaf dywydd cartref rheolaidd yn rhedeg am tua blwyddyn ar 2 batris AA. Felly, mae hyd yn oed watsys arddwrn yn cael eu gwneud gyda chydamseru radio, heb sôn, wrth gwrs, gwylio wal neu oriorau gorsaf stryd.
Mae hwylustod a symlrwydd DCF hefyd yn denu selogion DIY. Am ddim ond $10-20 gallwch brynu modiwl antena parod gyda derbynnydd parod ac allbwn TTL, y gellir ei gysylltu ag Arduino neu reolwr arall.
Wedi ysgrifennu yn barod ar gyfer Arduino
Gall y rhai sy'n dymuno hyd yn oed uwchraddio oriawr eu hen nain trwy osod mecanwaith newydd gyda chydamseru radio:
Gallwch ddod o hyd i un ar ebay gan ddefnyddio'r geiriau allweddol “Radio Controlled Movement”.
Ac yn olaf, hack bywyd i'r rhai sydd wedi darllen hyd yma. Hyd yn oed os nad oes un trosglwyddydd signal radio yn y cwpl o filoedd km nesaf, nid yw'n anodd cynhyrchu signal o'r fath eich hun. Mae yna raglen ar Google Play o'r enw “DCF77 Emulator” sy'n allbynnu'r signal i glustffonau. Yn ôl yr awdur, os ydych chi'n lapio gwifren y clustffonau o amgylch yr oriawr, byddant yn codi'r signal (mae'n ddiddorol sut, oherwydd ni fydd clustffonau cyffredin yn cynhyrchu signal 77KHz, ond mae'n debyg bod y derbyniad oherwydd harmonics). Ar Android 9, ni weithiodd y rhaglen o gwbl i mi - yn syml, nid oedd unrhyw sain (neu efallai na chlywais ef - mae'n 77KHz, wedi'r cyfan :), ond efallai y bydd rhywun yn cael gwell lwc. Mae rhai, fodd bynnag, yn gwneud eu hunain yn generadur signal DCF llawn, sy'n hawdd ei wneud ar yr un Arduino neu ESP32:
(ffynhonnell
Casgliad
Trodd y system DCF allan i fod yn eithaf syml a chyfleus mewn gwirionedd. Gyda chymorth derbynnydd syml a rhad, gallwch chi gael yr union amser bob amser ac ym mhobman, wrth gwrs yn y dderbynfa. Mae'n ymddangos, hyd yn oed er gwaethaf digideiddio eang a Rhyngrwyd Pethau, y bydd galw am atebion syml o'r fath am amser hir.
Ffynhonnell: hab.com