Processing data out of GNURadio

本文围绕GNURadio软件展开,介绍了从该软件导出数据并进行进一步处理的方法。首先需安装GNURadio和Python绘图库,接着创建特定流图并生成Python脚本,再编写自己的Python程序调用该脚本获取数据并处理,最后连接设备运行脚本可看到不同绘图结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Processing data out of GNURadio

While working on software defined radio (SDR), I have always worked on GNURadio software which provide a graphical interface. I have to drag and drop various blocks to create flow graphs which perform the functionality I need. It's time to escape the barriers of GNURadio and do further thing out of it. Finally I found the way to do it. We can start with GNURadio flow graphs and transfer data from it to our own python scripts where we have the freedom to do whatever we want with our program codes. I found some good resources from where I learnt it and those things are mentioned under the references section.

 

First of all to try these things, we need to have installed some software. GNURadio should be there as obvious. Additionally we need a python plotting library which we will be using. Install it as follows.

 

sudo apt-get install python-matplotlib

 

Let's clearly understand what we are going to do now. When we run a flow graph created using GNURadio, it will acquire the data from wherever we specified and will process it inside. Resulting data can be visualized as different plots provided as blocks within the flow graph or sometimes we can save data in to a file. Every kind of processing I have done so far are within the flow graph. Now, what we are going to achieve is creating a flow graph which has some special blocks. Instead of running the flow graph straightforwardly, we just generate a python script using GNURadio that represent the flow graph. Then we write a our own python program which will use that GNURadio generated python script as a module to acquire data and then do further processing of data inside our own python script.

 

It's time for action. Open gnuradio-companion tool and create the following flow graph. It will acquire data from a HackRF device and apply a fast fourier transform (FFT) operation on the data stream. Finally it turns that FFT data in to message block which are ready to be sent out of the flow graph though a special block. I saved this flow graph as fft_data.grc and clicked on the 'generate flow graph' button to generate the python script which implements this flow graph is code. It generates the script called top_block.py automatically.

 

 

Once this is done,  we have a python script which will acquire data and provide us FFT data. Let's use it in a our own python script. For this purpose, create a new python program with the name fft_plotter.py and add the content shown below. It should be understandable that we have two functions there. First one draws the FFT for the considered frequencies while the second one draws the variation of signal power of a particular frequency over time. Depending on what we want to plot, we can uncomment the relevant line.

 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import grcconvert
import struct
grcconvert.main("top_block.py")
import top_block
import matplotlib.pyplot as plot
import os
from collections import deque

def plot_fft(with_this):

 #Asanka: trying to play with this
 os.system('clear')
 print "------------------------------"
 print "length       =", len(with_this)
 print "start point  =", with_this[0][0], "dB"
 print "center point =", with_this[len(with_this)/2][0], "dB"
 print "end point    =", with_this[len(with_this)-1][0], "dB"
 print "------------------------------"

 plot.clf()
 # it seems logpwrfft exchanges the first and second part of the FFT output, we correct it:
 plot.plot(with_this[len(with_this)/2:]+with_this[:len(with_this)/2]) 
 plot.draw()

def plot_power(data_array):

 os.system('clear')
 print '\n\n'
 print "signal strengh at the center:", data_array[len(data_array)/2][0],"dB"
 
 a1.appendleft(data_array[len(data_array)/2][0])
 datatoplot = a1.pop()
 line.set_ydata(a1)
 plot.draw()
 plot.pause(0.00001)


plot.ion()
tb=top_block.top_block()
tb.start()

#Asanka: experiment
a1 = deque([0]*100)
ax = plot.axes(xlim=(0, 100), ylim=(-100, 0))
ax.grid(True)
line, = plot.plot(a1)
plot.ylim([-150,0])
plot.show()

while True:
 fft=tb.msgq_out.delete_head().to_string() # this indeed blocks
 floats=[] 
 for i in range(0,len(fft),4):
  floats.append(struct.unpack_from('f',fft[i:i+4]))
 print "got",len(floats), "floats; FFT size is", tb.fft_size
 i=0
 while i<len(floats): # gnuradio might sometimes send multiple vectors at once
  pack=floats[i:i+tb.fft_size-1]
  #plot_fft(pack)
  plot_power(pack)
  i+=tb.fft_size
  

 

This python script and the gnuradio-companion generated python script should be there in the same directory. Finally we need one more python script before we can try running this code. It can be obtained from here and saved into the same directory. It's written by Andras Retzler and I got the code from an example he provided in github.

 

Now I think we are good to go. Connect HackRF device into a USB port of the computer and run our python script with root privileges.

sudo python fft_plotter.py

Depending on the function we call within our script (we cannot call both at the same time), we will be able to see two different plots as follows.
 


 


That's it for the moment!

 

References:

 

[1] https://github.com/simonyiszk/gr_messagesink_tutorial

[2] http://ha5kfu.sch.bme.hu/node/123

### USRP UHD Signal Modulation Implementation For implementing signal modulation using the Universal Software Radio Peripheral (USRP) with the UHD driver, one can utilize GNU Radio's Python API to create a flowgraph that includes various blocks such as modulators and demodulators along with the USRP sink/source block. To observe or manipulate data post-processing without exclusively relying on `file_sink` modules, integrating custom Python scripts directly within the GNU Radio Companion (GRC) environment is feasible. A typical setup involves creating a transmitter chain where signals are generated, processed through different stages including modulation schemes like QPSK or BPSK before being sent out via the USRP device configured by specifying parameters related to frequency, gain, sample rate among others[^1]. Below demonstrates an example of how this might be achieved programmatically: ```python from gnuradio import gr from gnuradio.uhd import usrp_source, usrp_sink from gnuradio.digital import packet_encoder, packet_decoder import numpy as np class MyTopBlock(gr.top_block): def __init__(self): super(MyTopBlock, self).__init__() # Define variables for configuration samp_rate = 1e6 carrier_freq = 900e6 # Create USRP Sink instance uhd_args = "addr=192.168.10.2" usrp_tx = usrp_sink( device_addr=uhd_args, stream_args=gr.stream_args('fc32') ) # Set properties for transmission usrp_tx.set_samp_rate(samp_rate) usrp_tx.set_center_freq(carrier_freq) # Generate some test waveform here; replace with actual modulation code. src_data = np.exp(2j * np.pi * 1000 * np.arange(int(samp_rate)) / float(samp_rate)) # Connect source to USRP sink throttle_blk = gr.throttle(itemsize=gr.sizeof_gr_complex*1, samples_per_sec=samp_rate) self.connect((throttle_blk, 0), (usrp_tx, 0)) # Add more components like encoders/decoders/modems etc., depending upon application needs. if __name__ == '__main__': tb = MyTopBlock() try: tb.start() # Start processing input("Press Enter to stop...") finally: tb.stop() tb.wait() ``` This script sets up a basic framework for transmitting complex baseband IQ data over-the-air using a specified USRP hardware address (`uhd_args`). The placeholder generation function should be replaced according to specific requirements regarding which type of modulation scheme will be employed during experimentation. To interactively pause execution at any point allowing inspection or modification of internal states while running inside GRC, similar techniques shown in another context could apply but adapted appropriately for compatibility reasons[^2]: ```python import os print(os.getpid()) input('Attach debugger and press enter') ``` However, note that embedding direct calls to system functions may not always work seamlessly across all platforms due to differences between operating systems' implementations. --related questions-- 1. How does changing the sampling rate affect transmitted signal quality? 2. What considerations must be taken into account when selecting appropriate frequencies for wireless communications experiments? 3. Can you provide guidance on constructing custom digital communication protocols utilizing GNU Radio tools? 4. Are there alternative methods besides file sinks/sources for real-time monitoring of intermediate results within GNU Radio workflows?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值