Close

First live data

A project log for DIY SDR for fun

I try programming my own SDR for fun and to learn Python and digital signal processing.

max-felix-mllerMax-Felix Müller 05/05/2019 at 21:150 Comments

The demo code only shows raw sample data. There is also another demo that converts the samples into a plot, showing the frequency and power.


But I wanted more. Why not have that plot updated as new samples come in?

I recently learned about the matplotlib animation thingy, which enables you to update your graph at a given itnerval.

I haven't quite figured out how to run it as a complete seperate thread so while the window is opened, the program doesn't continue, but at least it updates.

So here's my code:

from matplotlib import pyplot as plt
import matplotlib.animation as animation
from rtlsdr import RtlSdr
import numpy as np

sdr = RtlSdr()
# configure device
sdr.sample_rate = 2.4e6  # Hz
sdr.center_freq = 94.7e6  # Hz
sdr.freq_correction = 60   # PPM
sdr.gain = 'auto'

fig = plt.figure()
graph_out = fig.add_subplot(1, 1, 1)


def animate(i):
    graph_out.clear()
    #samples = sdr.read_samples(256*1024)
    samples = sdr.read_samples(128*1024)
    # use matplotlib to estimate and plot the PSD
    graph_out.psd(samples, NFFT=1024, Fs=sdr.sample_rate /
                  1e6, Fc=sdr.center_freq/1e6)
    #graph_out.xlabel('Frequency (MHz)')
    #graph_out.ylabel('Relative power (dB)')


try:
    ani = animation.FuncAnimation(fig, animate, interval=10)
    plt.show()
except KeyboardInterrupt:
    pass
finally:
    sdr.close() 

While the window is open, every 10ms (or slower if the calculations take too long, which they do), new samples will be collected. Matplotlib provides a function called psd() which automatically plots power over frequency and adjusts for the center frequency as well as the sampling frequency.

But what if I want to contine further with the power and frequency data?

For example, if I want to output the common waterfall, I would need the power and freuqency values as a list or an array. Numpy array would be preferred but whatever works is ok for now.

Well I did some googling and found this:

# new import
from matplotlib import mlab as mlab

# new plot
power, psd_freq = mlab.psd(samples, NFFT=1024, Fs=sdr.sample_rate /
                               1e6)
    psd_freq = psd_freq + sdr.center_freq/1e6
    graph_out.semilogy(psd_freq, power)

 The formating got a bit lost there but you get the gist of it I guess.

This way, the psd function returns the values instead of directly plotting them. The only thing left to do is to shift the results to the previously set center frequency.

Notice that the frequency shown is in MHz.

Discussions