I'm new to the world of RF and signal processing. I have a USRP B210 and I'm trying to detect and generate spectrograms that will be later used to train an AI model that identifies if the signal is a wifi, bluetooth, drone... which means we're focusing on 2.4GHz I guess.
this is the code provided by ettus research on
import uhd
import numpy as np
usrp = uhd.usrp.MultiUSRP()
num_samps = 10000 # number of samples received
center_freq = 100e6 # Hz
sample_rate = 1e6 # Hz
gain = 50 # dB
usrp.set_rx_rate(sample_rate, 0)
usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(center_freq), 0)
usrp.set_rx_gain(gain, 0)
# Set up the stream and receive buffer
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
st_args.channels = [0]
metadata = uhd.types.RXMetadata()
streamer = usrp.get_rx_stream(st_args)
recv_buffer = np.zeros((1, 1000), dtype=np.complex64)
# Start Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
streamer.issue_stream_cmd(stream_cmd)
# Receive Samples
samples = np.zeros(num_samps, dtype=np.complex64)
for i in range(num_samps//1000):
streamer.recv(recv_buffer, metadata)
samples[i*1000:(i+1)*1000] = recv_buffer[0]
# Stop Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
streamer.issue_stream_cmd(stream_cmd)
print(len(samples))
print(samples[0:10])
I tried the basic code provided by Ettus Research on their website and experimented with different values and parameters, sometimes adding a filter... But It seems I'm still very far from my objective
This is the last code I used
import uhd
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter
def butter_lowpass_filter(data, cutoff_freq, sample_rate, order=5):
nyquist = 0.5 * sample_rate
normal_cutoff = cutoff_freq / nyquist
b, a = butter(order, normal_cutoff, btype='low', analog=False)
y = lfilter(b, a, data)
return y
usrp = uhd.usrp.MultiUSRP()
num_samps = 1000000
center_freq = 2.4e9
sample_rate = 1e7
gain = 2
duration = 0.25
order = 10
cutoff_frequency = 2.5e6
denoised_samples = butter_lowpass_filter(samples, cutoff_frequency, sample_rate, order)
usrp.set_rx_rate(sample_rate, 0)
usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(center_freq), 0)
usrp.set_rx_gain(gain, 0)
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
st_args.channels = [0]
metadata = uhd.types.RXMetadata()
streamer = usrp.get_rx_stream(st_args)
recv_buffer = np.zeros((1, 1000), dtype=np.complex64)
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
streamer.issue_stream_cmd(stream_cmd)
samples = np.zeros(num_samps, dtype=np.complex64)
for i in range(num_samps // 1000):
streamer.recv(recv_buffer, metadata)
samples[i * 1000:(i + 1) * 1000] = recv_buffer[0]
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
streamer.issue_stream_cmd(stream_cmd)
denoised_samples = butter_lowpass_filter(samples, cutoff_frequency, sample_rate)
print(len(denoised_samples))
print(denoised_samples[0:10])
plt.specgram(denoised_samples, NFFT=int(duration * sample_rate), Fs=sample_rate, noverlap=int(duration * sample_rate * 0.9), cmap='viridis')
plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.title('Spectrogram aver filter pass-bas 2')
cbar = plt.colorbar()
cbar.set_label('Intensity (dB)')
plt.show()
This is What I get:
This is my objective:
Here's an example of my code that I used to get a signal similar to the one you're trying to get
import uhd
import numpy as np
import matplotlib.pyplot as plt
import scipy
usrp = uhd.usrp.MultiUSRP()
num_samps = 1000 * 1000 # number of samples received
num_samps_h = 2000 # number of samples received
num_samps_w = 2000 # number of samples received
center_freq = 2422e6 # Hz
sample_rate = 15e6 # Hz
gain = 50 # dB
usrp.set_rx_rate(sample_rate, 0)
usrp.set_rx_bandwidth(20e6)
usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(center_freq), 0)
usrp.set_rx_gain(gain, 0)
print("bandwidth", usrp.get_rx_bandwidth())
# Set up the stream and receive buffer
st_args = uhd.usrp.StreamArgs("fc32", "sc16")
st_args.channels = [0]
metadata = uhd.types.RXMetadata()
streamer = usrp.get_rx_stream(st_args)
recv_buffer = np.zeros((1, num_samps_w), dtype=np.complex64)
# Start Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont)
stream_cmd.stream_now = True
streamer.issue_stream_cmd(stream_cmd)
# Receive Samples
samples = np.zeros((num_samps_h, num_samps_w), dtype=np.complex64)
for i in range(num_samps_h):
streamer.recv(recv_buffer, metadata)
samples[i] = scipy.fft.fft(recv_buffer[0])
# Stop Stream
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.stop_cont)
streamer.issue_stream_cmd(stream_cmd)
print(len(samples))
print(samples[0:10])
abs_samples = np.absolute(samples)
print(abs_samples.max(), abs_samples.mean(), abs_samples.std())
max_display_value = abs_samples.mean() + 2 * abs_samples.std()
abs_samples[np.where(abs_samples > max_display_value)] = max_display_value
plt.imshow(abs_samples)
plt.show()
As a result, I managed to get waterfall images of the spectra, as in the attached pictures. Horizontal frequency, vertical time enter image description here