Eftersom den digitala signalprocessen går över Librtlsdr behöver vi kalla på Python-wrappern PyrtlSDR.read_sample() varje gång vi skall hämta en ny sample.
Detta görs med en while-loop i normala fall på samma sätt som man kör övrig kod i ett program.
Problemet med en while-loop är att den genomför sin cykel i en processorcykel, vilket gör loopen någon miljon gånger snabbare än den sample_rate som signalen kommer i. Vilket gör att hela avkodningen av signalen blir avhuggen i delar som inte sen kan sättas ihop.
Hur kan man få ner frekvensen av loopen så att den hinner processa hela signalen?
Alternativt att man på något sätt ser till att den array som innehåller bits från signalavkodningen blir fylld tills den har korrekt antal bits, men problemet här är att vi kan få gamla bitar från förra samplen då sample-loopen går snabbare än signalen.
Här är demoduleringen:
Vilket är bäst?
1) strypa while-loopen på något sätt?
2) se till i demoduleringen att vi har rätt bit-antal för varje array? Men hur ser vi till att vi då får alla bitar som vi ska ha på korrekt ställe?
Detta görs med en while-loop i normala fall på samma sätt som man kör övrig kod i ett program.
Problemet med en while-loop är att den genomför sin cykel i en processorcykel, vilket gör loopen någon miljon gånger snabbare än den sample_rate som signalen kommer i. Vilket gör att hela avkodningen av signalen blir avhuggen i delar som inte sen kan sättas ihop.
Hur kan man få ner frekvensen av loopen så att den hinner processa hela signalen?
Kod:
from rtlsdr import RtlSdr
sdr = RtlSdr()
# configure sdr-device
sdr.sample_rate = 1.024e6 # Hz
sdr.center_freq = 169.8e6 # Hz
sdr.freq_correction = 60 # PPM
sdr.gain = 5
sample_factor = 64
def get_sample(sample_factor):
#sample from the RTL_SDR
return sdr.read_samples(sample_factor*1024)
def correct_dc_offset(sample):
#DC CORRECTION
#Correcting the dc spike and the center_freq
dc_corr = np.exp(1j * (2 * np.pi * (-offset_frequency / sdr.sample_rate) *
np.arange(0, len(sample))))
return sample * dc_corr
def decimate_and_filter (sample):
#DECIMATION AND FILTERING
# limit the sampling rate using decimation.
dec_sample_rate = sdr.sample_rate // dec_factor
# Butterwoth filter N=3th order, Wn = inverse decimate factor *2
dec_low_filter = sig.butter(N=3, Wn=1 / (dec_factor * 2))
# filter the signal
sample = sig.filtfilt(*dec_low_filter, sample)
# decimate
return sample[::dec_factor], dec_sample_rate
def main():
flag =True
while flag:
sample, dec_sample_r = decimate_and_filter(correct_dc_offset(get_sample(sample_factor)))
sdr.close()
main()
Alternativt att man på något sätt ser till att den array som innehåller bits från signalavkodningen blir fylld tills den har korrekt antal bits, men problemet här är att vi kan få gamla bitar från förra samplen då sample-loopen går snabbare än signalen.
Här är demoduleringen:
Kod:
def el_demodulator(dem, dec_sample_rate):
# calculate the nco step based on the initial guess for the bit rate. Early-Late
# requires sampling 3 times per symbol
nco_step_initial = bit_rate * 3 / dec_sample_rate
# use the initial guess
nco_step = nco_step_initial
# phase accumulator values
nco_phase_acc = 0
# samples queue
el_sample_queue = []
# couple of control values
nco_steps, el_errors, el_samples = [], [], []
# process all samples
for i in range(len(dem)):
# current early-late error
el_error = 0
# time to sample?
if nco_phase_acc >= 1:
# wrap around
nco_phase_acc -= 1
# alpha tells us how far the current sample is from perfect
# sampling time: 0 means that dem[i] matches timing perfectly, 0.5 means
# that the real sampling time was between dem[i] and dem[i-1], and so on
alpha = nco_phase_acc / nco_step
# linear approximation between two samples
sample_value = (alpha * dem[i - 1] + (1 - alpha) * dem[i])
# append the sample value
el_sample_queue += [sample_value]
# got all three samples?
if len(el_sample_queue) == 3:
# get the early-late error: if this is negative we need to delay the
# clock
if el_sample_queue:
el_error = (el_sample_queue[2] - el_sample_queue[0]) / \
-el_sample_queue[1]
# clamp
el_error = np.clip(el_error, -10, 10)
# clear the queue
el_sample_queue = []
# store the sample
elif len(el_sample_queue) == 2:
el_samples += [(i - alpha, sample_value)]
# integral term
nco_step += el_error * 0.01
# sanity limits: do not allow for bitrates outside the 30% tolerance
nco_step = np.clip(nco_step, nco_step_initial * 0.7, nco_step_initial * 1.3)
# proportional term
nco_phase_acc += nco_step + el_error * 0.3
# append
nco_steps += [nco_step]
el_errors += [el_error]
if el_samples:
print (np.array([x[1] for x in el_samples]) >= 0)
Vilket är bäst?
1) strypa while-loopen på något sätt?
2) se till i demoduleringen att vi har rätt bit-antal för varje array? Men hur ser vi till att vi då får alla bitar som vi ska ha på korrekt ställe?