MATLAB的RTL-SDR硬件支持包使用教程

本文已授权开源SDR实验室转载,csdn链接

前言

matlab在R2013b版本以后支持了调用RTL-SDR的硬件支持包,但是相关资料很少;中文互联网上的教程关于如何使用的教程几乎是空白。在这里我尝试将我的使用过程总结一下以抛砖引玉,希望能够帮助到其他的无线爱好者更方便的使用RTL-SDR~
RTL-SDR是Realtek的一款电视棒,后来被人hack以后能够开启2.2GHz以内频段的接收(最大是2.2G,这和你购买的sdr所使用的前端调谐器有关),理论采样率为3.2MHz,但是在实际使用中我推荐设置为2.4MHz以下可以无失真的接收。下面是常见的RTL-SDR调谐器的型号以及对应的频率范围:


本文大概有以下几个部分:
1.RTL-SDR驱动安装
2.安装matlab RTL-SDR硬件支持包
3.支持包的相关使用函数和例程

RTL-SDR驱动安装

在拿到RTL-SDR这个地球上最便宜的sdr设备后(京东上100r,淘宝5 60r左右。我用的是RTL2832U),需要用Zadig软件安装一下RTL-SDR的驱动。Zadig请自行下载~一般京东或淘宝的店家会有RTL-SDR的软件包,包括Zadig和各种版本的SDRSharp软件(一个很方便观察无线频谱的软件),以及飞机追踪的套件(很多无线电爱好者喜欢用它尝试接收1090MHz的民航轨迹信号)。

RTL-SDR电视棒

安装驱动前,需要将RTL插在电脑的USB口。然后打开Zadig,在Options下点击List All Devices,并且勾选上Ignore Hubs or Composite parents,注意这里一定要勾选Ignore这个选项,如果不勾选则安装的驱动(会出现USB开头的)虽然可以让RTL-SDR在SDRSharp等软件上使用,但是无法在MATLAB平台上识别到设备。


接下来在下面的选择框中选择RTL开头的驱动,点击安装等待即可。

安装matlab RTL-SDR硬件支持包

安装好RTL的驱动后,在matlab的附加功能-获取硬件支持包里找到RTL的支持包Communications Toolbox Support Package for RTL-SDR Radio

安装这个支持包后,按照指示一步步完成第一次的设备识别


注意,此时RTL需要一直插在电脑上。

</center >
等待识别成功后,在matlab的work space输入sdrinfo,观察是否能够正常识别到RTL设备。
</center >
## 在MATALB上使用RTL-SDR
先说一下,RTL-SDR硬件支持包的官方网站 在这个官网上有一本674页的图书,里面有详细的文档,不过目前只有英文原版,同样是在中文互联网上没有更多的信息…
首先尝试一下RTL-SDR连接MATLAB正常接收无线信号,对在matlab上调用rtl有一个直观感受。运行以下代码观察频域是否能接收附近的无线信号,通常我会用FM频段(在中国FM频段为87-108MHz)的信号测试SDR的情况,这里我测试接收91.6MHz处的FM广播信号:

fc   = 91.4e6; % Center frequency (Hz)
FrontEndSampleRate = 1e6;     % Samples per second
FrameLength        = 256*20;  % Frame length

% Create receiver and spectrum analyzer System objects  
hSDRrRx = comm.SDRRTLReceiver(...
    'CenterFrequency', fc, ...
    'EnableTunerAGC',  true, ...
    'SampleRate',      FrontEndSampleRate, ...
    'SamplesPerFrame', FrameLength, ...
    'OutputDataType',  'double');

hSpectrum = dsp.SpectrumAnalyzer(...
    'Name',             'Passband Spectrum',...
    'Title',            'Passband Spectrum', ...
    'Method',           'Welch', ...
    'SpectrumType',     'Power density', ...
    'FrequencySpan',    'Full', ...
    'SampleRate',       FrontEndSampleRate, ...
    'SpectralAverages', 50, ...
    'FrequencyOffset',  fc, ...
    'YLimits',          [-80,10], ...
    'YLabel',           'Magnitude-squared, dB', ...
    'Position',         figposition([50 30 30 40]));

%% Stream processing
% View spectrum.  While the spectrum analyzer is running, you can measure
% peaks, occupied bandwidth, and other properties of the signal.
if ~isempty(sdrinfo(hSDRrRx.RadioAddress))
    for count = 1 : 5000
        [data, ~] = step(hSDRrRx);  % no 'len' output needed for blocking operation
        data = data - mean(data);  % remove DC component
        step(hSpectrum, data);
    end
else
    warning(message('sdrbase:sysobjdemos:MainLoop'))
end

% Release all System objects
release(hSDRrRx);
release(hSpectrum);

版权声明:这段代码修改自Mathworks的官方例程
如果可以观察到正确的FM信号,则证明可以使用了:

## RTL-SDR硬件支持包的函数
调用rtl需要先用 comm.SDRRTLReceiver 创建RX对象。具体语法包括:

RXobj = comm.SDRRTLReceiver
RXobj = comm.SDRRTLReceiver(Name,Value)
RXobj = comm.SDRRTLReceiver(RadioAddress,Name,Value)

但是在实际使用中,如上一节所写的一样,我们需要指定RX对象的各种参数,包括中心频率、采样率、自动增益控制等等。这个函数所支持的参数有:
RadioAddress — 指定使用哪个USB口的RTL-SDR设备。默认是0。这个值可以用 sdrinfo 来查看。
CenterFrequency — 指定RTL接收无线信号的中心频率,单位为Hz。默认为102.5MHz。
EnableTunerAGC — 指定是否打开自动增益控制。默认为true。
TunerGain — 指定调谐器的增益。单位为dB。默认为0。注意,如果要手动指定增益,需要将EnableTunnerAGC设置为false。
SampleRate — 指定RTL的采样率。在matlab上这个支持包上支持的范围是225~300kHz和900~3200kHz,官方建议设置小于等于2560kHz可以避免失真。
OutputDataType — 指定输出的数据类型。可选类型有 int16 | double | single 。当选择输出int16数据类型时,输出的是原始的16位IQ数据。默认为int16。
SamplesPerFrame — 指定每帧的采样数。默认为1024。 这里值得多说一下的是,RTL的RX对象对于每次采样是采集到到指定的每帧采样数后完成本次采样。所以,在实际的连续采样时,我们需要连续多次调用RX对象进行采样。那么,每一次采样的真实时间为:

FrameTime = SamplesPerFrame / SampleRate

所以在实际的连续采样中我们可以设置一个runTime作为计时器并不断更新来控制接收时间。
FrequencyCorrection — 指定频偏矫正。默认为0,单位为ppm。支持的矫正范围为-1e4 ~ 1e4。值得注意的是,据我所知,市面上售卖的RTL-SDR的晶振有一些是不带温度补偿(TCXO)的。
EnableBurstMode — 指定是否开启突发模式。默认为true。(这个我不太了解具体是什么,尝试打开和关闭好像没发现有什么区别…)
NumFramesInBurst — 指定连续突发的帧数。默认为10(同样不太了解应该在什么情况下使用…)
声明RX对象例子:

rx = comm.SDRRTLReceiver(...
    'CenterFrequency', 120e6, ...
    'EnableTunerAGC',  true, ...
    'SampleRate',      2.4e6, ...
    'SamplesPerFrame', 2048, ...
    'OutputDataType',  'int16');

其他参数没有特殊声明都是默认值。

调用RX对象的语法包含:

rxdata = RXobj()
[rxdata,len] = RXobj()
[rxdata,len,lost] = RXobj()
[rxdata,len,lost,late] = RXobj()

这里的RXobj为前面声明的RX对象名称,调用时将RXobj替换成你所声明的对象名称即可。
对于输出参数:
rxdata — 采样的数据值。数据类型、数据长度等与RX对象里的参数设置一致。
len — 返回有效采样数据的长度。如果没有采集到数据,则返回0。
lost — 返回丢失的采样数据长度。如果是正常运行,则lost返回值为0。
late — 返回帧延迟数量。
对于进行无线实验,录制一段信号,我们关注的是rxdata原始数据,所以让其返回int16类型即可(IQ原始数据)。len、lost、late一般会用于观察RTL的实时性能,如果出现了数据丢失或者延迟,说明RTL实时运行可能存在问题,这有可能和所使用电脑的CPU、内存、硬盘性能有关。

RX对象函数包含:
step 运行采集数据算法
release 释放资源,用于修改已有的RX对象的参数
reset 重置RX对象内部状态

录制无线信号测试

在实际采集数据时,我们可以这样写:

recordData = [];
for FrameNum = 1 : 100 %想要采集多少帧按照自己的需求
    recordData = [recordData RXobj()]; % 或者可以写成step(RXobj),或是RXobj.step()
end

然而,在前面也提到了我们通常录制一段无线信号更偏向以时间为单位,例如录制多少秒,以上面这种按帧的方式不便于理解和计时,因此,我们可以这样写:

RunTime = 0; % 计时器
DurTime = 10; % 这里我假设需要录制10秒
recordData = [];
FrameTime = RXobj.SamplesPerFrame / RXobj.SampleRate;
if ~isempty(sdrinfo(hSDRrRx.RadioAddress))
    while Runtime < DurTime
        recordData = [recordData RXobj()]; % 这里我将原始数据完全的保存到变量里了,这样做其实很费性能...
        RunTime = Runtime + FrameTime;
    end
 else
    warning(message('sdrbase:sysobjdemos:MainLoop'))
end

将原始数据保存到变量里再做计算是一个非常费性能的操作,以我的Envy 13笔记本为例,CPU为i7-8550U,内存为8G,想要绘制带宽为2MHz几秒钟的无线信号的瀑布图要等待数十秒……下面是绘制一段91.6MHz的FM信号,时间长为3.5秒的频谱图的结果。绘制这张图让我的matlab卡了大概20多秒,想要再修改一下坐标轴直接卡死…所以只截图了不带坐标轴的地方…(我都玩rtlsdr了 还指望我能用上什么好电脑-.-)

连续扫频测试

虽然RTL的带宽很小,但是这个支持包的开发者提供的样例程序里给出了一个从25MHz到1750MHz的扫频代码…我尝试运行了一下,确实能扫频…只能说一句牛逼了
我在房屋内进行了两次25MHz~1750MHz的扫频测试,下面分别是两次的扫频结果:

 


在这两次测试中,RTL的采样率设置为2.8MHz,FrameLength为4096,Tuner的增益为40dB。由于带宽实在是太低了,两次测试的实际运行时间分别为287.4292s和411.5904s。第二次可能是因为我调用了matlab的代码追踪,让整体的运行时间更加长了-.-
关于扫频的代码,由于我几乎没有修改原作者的代码,就不便放上来了,感兴趣的同学可以在开发团队的官网下载,具体位置在../Software_Defined_Radio_using_MATLAB_Simulink_and_the_RTL-SDR___book_and_support_files/spectrum/sweep下的rtlsdr_rx_specsweep.m文件。

最后

RTL-SDR这个地球上最便宜没有之一的软件无线电设备,是很多人接触、入门无线领域的第一个设备,我个人认为从RTL开始接触学习无线通信&无线安全等方面是一个非常好的选择,在一些情况下用RTL会比用usrp更容易携带和随时测试(当然,RTL是不可能碰瓷usrp的高性能的)。从安全角度,很多无线窃听的攻击需要无线设备的隐蔽性和可携带性,例如TEMPEST窃听和GSM窃听等,RTL是一个很好的选择(!我不是推荐实施恶意攻击0.0 只是看到很多这么做实验的…)
写这篇教程的想法是因为在折腾RTL的时候,一直用的是HDSDR,SDR#,GNU Radio这些软件。但是我个人的一些实验需求需要在matlab进行一些计算,从其他软件上录制后再导入到matlab进行计算实在麻烦(虽然似乎可以单独开一个端口传输采集的数据),就考虑直接在matlab上控制RTL来采集信号和计算了。然而在网上能看到的教程少之又少,matlab官网关于这个支持包也只给出了基本的函数描述,中文互联网上没有更多的资料了,就把我踩过的坑写写以抛砖引玉~ 有一说一这个硬件支持包的坑还是有点的,比如每次采集数据是按照每帧大小采集的,matlab的官网上的描述又没有给出如何采集确定秒数的数据等。
在折腾这个RTL-SDR硬件支持包中,很多资料来源于原开发团队的官方图书《Software Defined Radio using MATLAB® & Simulink® and the RTL-SDR》,这本图书在官网有电子版下载,以及他们给出的很多例程代码,都是可以免费下载的。纸质版图书在淘宝上有卖800+多块钱一本的店铺。。。这个我确实是暂时没有金钱能力支持作者…
关于RTL-SDR在matlab上的使用我还参考了一些其他但不限于以下的资料:
* matlab官方文档
* RTL-SDR在matlab上解码无线信号白皮书
* desktopSDR-paper这是原作者团队于2015年发表在IEEE Communications Magazine上的一篇关于这个支持包的文章
* desktopSDR官网

2021.9.28修正

第一点想说的是最近在做信号对齐的时候才发现RTL在matlab上采集时,CenterFrequency的频率实际上是采用的左对齐方式。意即如果一个单频信号的中心频率为100M,带宽为1M,那么想要完整采集到这个信号,RTL的CenterFreFrequency应该设置为100 – 1 / 2 = 99.5M。这一点好像没有在官方手册里提到(可能不明显,我没找到)
另外,最近在做用RTL做接收Chirp,不知道是我手里这个RTL硬件有问题还是其他什么问题,当我在matlab开始采集信号时,在采样率的大约后60%的范围内总是失真。例如,我的信号带宽为1M时,如果我的采样率设置为1M,会在中心频率的0.4~0.5M之后都失真了,但是在末尾的10%~20%的范围又可以收到,这个问题之前没有遇到过。我现在的方案是将采样率设置为信号带宽的4到5倍,让信号能够在不失真的范围内采集,只是一个没办法的办法。并且由于RTL的极限采样率只有3.2M,所以没办法做更大带宽的信号采集…..

2021.10.9修正

刚刚换了台式机再试了下发现失真问题是我的笔记本不行。。。可能是由于吞吐处理不过来导致大量采样点失真。。。说明一下我的笔记本是Envy 13,i7-8550u,8g内存,USB2.0的口。



Add a Comment

邮箱地址不会被公开。 必填项已用*标注