世界的本质是旋转(5)-在复平面上驱动软件无线电SDR发射BPSK波形

在上一篇文章中,我们介绍了复平面、拍照采样的一些思维实验。从本节开始,转入现实应用,通过控制复平面向量的位置,实现一个完整的BPSK全双工通信通道。

发射方:通过控制复平面向量在各个时刻的位置来携带信息的技术,属于通信原理中调制的概念。
接收方:从采样(拍照)结果找回信息经历的计算,是通信原理中解调的概念。

本文基于C语言SDR实验平台taskBus开展实验。文章从复平面向量的旋转起步,以图、代码为主,并没有严谨专业的理论推导。一些工程方法比起专业的通信技术而言是非常单薄且作坊的,俗称野路子、小高炉炼钢铁,希望读者仅仅以娱乐或者批判的眼光看待本文。SDR是成人的大玩具,我们的口号是娱乐至上!

完整的工程参考taskbus_course的a2课程,可执行包参考taskBus的Release版本。

1. 通用软件无线电的特点

在开始本文前,笔者已经花了4天左右的时间,利用USRP B200min构造了稳健的BSPK/QPSK双工通道,用自己的思路和直接的纯C代码实现了调制解调,体会到软件无线电实现BPSK一些有趣的不同:

  1. 传统通过电路实现的解调器感觉复杂的部分,在计算机上一个 atan 就解决了。
  2. 符号时钟同步、载波同步的环路,就是一个角度变量的更新和迭代,使得相机的旋转与残频的旋转同步,类似旋转打地鼠
  3. BPSK只判断相位符号,不测量向量长度,因而在多径衰落下,影响也不大。
  4. USRP自带一个滤波器,即使没有成型,也不会频谱泄露。
支持BPSK/QPSK的SDR范例带有残差频率的BPSK地鼠机
BPSKBSPK地鼠机

通用计算机的优势,使得调制解调代码出奇的短,并非常直接,易于理解。后面的例子以BPSK讲述,QPSK的算法原理完全一样,通过阅读源码很容易推广。

2. 调制:使用向量的位置携带信息驱动USRP B210

在前文中,我们观察的是简单的向量转动的叠加。如果把叠加后向量的位置看做一个质点,显然每次拍照时,质点都会在复平面留下影像。如果我们通过设置质点的位置,让每 Ts 秒质点必然出现在某些特定的位置上,则可以用这种时间:位置的对应关系,来表征信息。

比如,希望质点位于(0,1)时表示二进制信息1,位于(0,-1)时表示二进制信息0,则可以携带二进制信息。下图携带的信息是 1 0 1 1 0 1 1 0 1 0 0 0 0 0

raw
USRP B210/B200mini 只要输入上述复平面的 x,y坐标,就能实现发射(USRP板卡自带BW设置,可以抑制带外旁瓣,相当于成型滤波)。这种复平面上的 x,y坐标数组构成的数据流被称为“基带信号”,表示为一组整数。SDR硬件会帮助我们进行DUC(上变频)与DA转换,驱动模拟电路产生无线电波。

对USRP B210来说,可以直接在当前采样率(拍照速率)下给出上述波形,接收的时候,注意以2倍以上的速率接收即可. 从比特生成USRP IQ 发射波形的代码:

std::vector<short> emit_one_pack(std::vector<char> bits)
{std::vector<short>  signal;for (int i=0;i<bits.size();++i){signal.push_back((packagedta[i]==1?1:-1) * 8192);signal.push_back(0);}return signal;
}

此时,采样率设置多大,调制速率就是多少波特。如250KHz的发射采样率,则调制速率就是250KBd。在我们的范例工程里,注意要把模块“a2psk_mod”的“shaping_filter”开关关闭,则实现的就是上述功能。

成型滤波设置

3 空中波形的实际情况

虽然我们递交给USRP 小盒子的是离散的坐标,但一定要有概念,就是发射到空中的是连续的电磁信号。同时,所有的SDR设备都是带限的。这种阶跃的状态最终生成的是连续的波形。就像您用力甩一个长绳子,绳子上的各个质点的纵向轨迹也是连续的行为。

另一方面,为了降低对带外其他频率的干扰,一般会使用成型滤波抑制带外频谱分量,导致更为平缓的过度。比如,我们在4倍采样率下,看到的中间状态是这样的,红色的点是我们的信息点,蓝色的圈圈是中间状态:

带限
观察上述现象的octave代码如下。代码里,使用成型滤波模拟了 USRP B210设备帮助我们做的事情。蓝色的点的坐标,也是导致4倍采样率下上文的地鼠会朝向原点运动到对面的情况。地鼠不可能阶跃过去,我们的向量(地鼠)在状态之间的迁移是连续的。

mulrate = 4;
symlen = 1000;
dta1_bits = randint (1, symlen, 2);
dta2_symbols = pskmod (dta1_bits, 2, 0, "gray");
dta3_sig = zeros(1,symlen*mulrate);
dta3_sig(1:mulrate:end) = dta2_symbols;
[fir_rcos]=rcosfir(0.25,[-3,3],mulrate,1,'sqrt');
dta4_baseband = conv(dta3_sig,fir_rcos,'same');
f = figure();
filename = 'output.gif';
dta4_draw = imag(dta4_baseband)+1j*real(dta4_baseband);
hold on;
DelayTime = 0.5;
plot([0,1],[0,0],'k');
plot([0,0],[-1,1],'k');
for t = 1:100plot([t-1,t],[0,0],'k');if mod(t - 1,mulrate)==0plot(dta4_draw(t),'r*');endifif t>1plot([t-1,t],[real(dta4_baseband(t-1)),real(dta4_baseband(t))],'r');if mod(t - 1,mulrate)==0plot([t],[real(dta4_baseband(t))],'r*');elseplot([t],[real(dta4_baseband(t))],'bo');endifendxlim([0,t]);pause(DelayTime );drawnow% 存为Gifframe = getframe(f);im = frame2im(frame);[imind,cm] = rgb2ind(im);if t == 1;imwrite(imind,cm,filename,'gif','DelayTime', DelayTime , 'Compression' , 'lzw');elseimwrite(imind,cm,filename,'gif','WriteMode','append','DelayTime', DelayTime , 'Compression' , 'lzw');end
end
hold off

一些感性的认识是:

  1. 复平面上质点的运动是连续的。质点不可能从一个位置“阶跃”到另一个位置。
  2. 由于带宽限制,运动轨迹很平滑,看起来像是一些余弦的叠加。
  3. 滤波使得原本恰好为正负1的y坐标分散了,在各个定时时刻上无法恰巧等于1或者-1.

4. 用C语言实现1/4速率成型滤波(非必须)

上文从0,1序列生成基带波形的 C语言代码非常直接,下文把成型滤波也加进去了,以对带宽进行限制,同时实现了4倍速率插值。完整的代码要参考文章开头的git代码库。注意的是使用自定义的滤波器提高了波形质量,但同样的采样率下,生成的调制速率降低了4倍。因此,要像上文驱动一个250KBd的BPSK波形,需要 1MHz的TX采样率。因此实际应用中,自己做不做成型,还是交给USRP的硬件滤波器来限制带宽,取决于连接SDR设备的网速,以及对码间串扰等滤波器特性的要求。

std::vector<short> emit_one_pack(std::vector<char> bits)
{static const double fir_rcos_q25[25] = {-0.018773,0.0030136,0.032677,0.047094,0.02655,-0.027522,-0.085225,-0.099447,-0.032147,0.11904,0.31118,0.472,0.53463,0.472,0.31118,0.11904,-0.032147,-0.099447,-0.085225,-0.027522,0.02655,0.047094,0.032677,0.0030136,-0.018773};static double fir_cache[25] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};static unsigned long long fir_clock = 0;std::vector<short> signal;for (int i=0;i<bits.size();++i){for (int sym = 0; sym< 4;++sym){//环状滤波器滤波成型fir_cache[fir_clock % 25] = sym==0?(bits[i]==1?1:-1):0;double fval = 0;for (int f=0;f<25;++f)fval += fir_cache[(fir_clock + 1 + f) % 25] * fir_rcos_q25[f];++fir_clock;//X,Ysignal.push_back(fval * 8192);signal.push_back(0);//BPSK Y (Q路)是0.}}return signal;
}

5. 下节预告:噪声背景下的接收

至此,已经可以把一串010101发到空中啦。下一节,我们会看到噪声叠加后,上述波形的取值进一步分散了,波形抖动的很厉害,只能大概看到各个点的符号, 而且其X坐标也不再是0,原本在Y轴上的点产生了位移:

recv

不仅如此,接收机接收到的坐标与发射机的坐标之间,存在着细微的偏差。首先是红色坐标位置生成的速率有误差,而后,上下变频有误差。接收机解决的主要问题都是围绕这些误差的同步来开展的。

  1. 时钟误差导致收发双方生产、消费红色样点的速率有差别。发射机生产10000个点,接收机相同时间消费9990个点。
  2. 频率误差,导致整体坐标系以一个很低的转速发生旋转。
  3. 初始相位差,使得接收机看到的点x,y坐标都不是0.

下一节我们看看收到的数据是如何处理的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/728576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Axure RP 10:让原型设计更快、更直观、更智能 mac版

Axure RP 10是一款强大的原型设计工具&#xff0c;它能够帮助设计师快速创建高保真、交互式的原型&#xff0c;从而更好地展示和测试设计方案。这款软件凭借其直观易用的界面和丰富的功能&#xff0c;已经成为了许多设计师的首 选工具。 Axure RP 10 for Mac版软件获取 首先&a…

AI论文速读 | 【综述】城市计算中跨域数据融合的深度学习:分类、进展和展望

题目&#xff1a;Deep Learning for Cross-Domain Data Fusion in Urban Computing: Taxonomy, Advances, and Outlook 作者&#xff1a;Xingchen Zou, Yibo Yan, Xixuan Hao, Yuehong Hu, Haomin Wen&#xff08;温皓珉&#xff09;, Erdong Liu, Junbo Zhang&#xff08;张钧…

进程之舞:操作系统中的启动、状态转换与唤醒艺术

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

解决QT cc1plus.exe: error: out of memory allocating

QT中增加资源文件过大时&#xff0c;会编译不过&#xff0c;报错&#xff1a; cc1plus.exe: out of memory allocating 1073745919 bytes 使用qrc资源文件&#xff0c;也就是在QT的工程中添加资源文件&#xff0c;就是添加的资源文件&#xff08;如qrc.cpp&#xff09;会直接被…

简明固体物理--晶体的形成与晶体结构的描述

简明固体物理-国防科技大学 chapter 1 Formation of Crystal Contents and roadmapQuantum Mechanics and atomic structureElectronsOld quantum theoryMethod of Quantum MechanicsDistributing functions of micro-particles BindingCrystal structure and typical crystal…

Go-Gin-example 第五部分 加入swagger

上一节链接 swagger 为什么要用swagger 问题起源于 前后端分离&#xff0c; 后端&#xff1a;后端控制层&#xff0c;服务层&#xff0c;数据访问层【后端团队】前端&#xff1a;前端控制层&#xff0c;视图层&#xff0c;【前端团队】 所以产生问题&#xff1a;前后端联调…

Keepalived+LVS构建高可用集群

目录 一、Keepalive基础介绍 1. Keepalive与VRRP 2. VRRP相关技术 3. 工作原理 4. 模块 5. 架构 6. 安装 7. Keepalived 相关文件 7.1 配置组成 7.2 全局配置 7.3 VRRP实例配置&#xff08;lvs调度器&#xff09; 7.4 虚拟服务器与真实服务器配置 二、Keepalived…

HTML静态网页成品作业(HTML+CSS)——花主题介绍网页设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

C语言:基于单链表实现的泊车管理系统

一、需求 &#xff08;1&#xff09;管理员方账号登录&#xff1b; &#xff08;2&#xff09;车位管理显示&#xff1a;车位状态&#xff1b; &#xff08;3&#xff09;收费管理&#xff1a;小轿车 5元/小时&#xff0c;面包车6元/小时&#xff0c;大货车或客车7元/小时&a…

ChatGPT提示技巧——零,一和少量示例提示

ChatGPT提示技巧——零&#xff0c;一和少量示例提示 ​ 零样本(zero-shot)、少样本(few-shot)和单样本(one-shot)提示是用于在最少或没有示例的情况下从ChatGPT生成文本的技巧。这些技巧用于当某个具体任务有限定数据的时候或者任务是新的并且没有很好的定义的时候。 提示格…

设计模式之——简单工厂模式

上图为简单工厂模式的架构图。 1&#xff0c;产品&#xff08;Product&#xff09; 将会对接口进行声明。 2&#xff0c;具体产品&#xff08;Concrete Products&#xff09;是产品接口的不同实现。 3&#xff0c;创建者&#xff08;Concrete Creators&#xff09;将会重写基…

TCP传输收发

TCP通信: TCP发端: socket connect send recv close TCP收端: socket bind listen accept send recv close 1.connect int connect(int sockfd, const struct sockaddr *addr, socklen_t ad…

20个Python函数程序实例

前面介绍的函数太简单了&#xff1a; 以下是 20 个不同的 Python 函数实例 下面深入一点点&#xff1a; 以下是20个稍微深入一点的&#xff0c;使用Python语言定义并调用函数的示例程序&#xff1a; 20个函数实例 简单函数调用 def greet():print("Hello!")greet…

css-vxe-form-item中输入框加自定义按钮(校验位置错误)

1.浮动错误效果 提示内容不对 2.不使用浮动&#xff0c;使用行内块元素 代码如下 <vxe-form-item title"yoyo:" field"assembleWorkNo" span"8"><template #default><vxe-input style"width:70%;display:inline-block;&quo…

全天候购药系统(微信小程序+web后台管理)

PurchaseApplet 全天候购药系统&#xff08;微信小程序web后台管理&#xff09; 传统线下购药方式存在无法全天候向用户提供购药服务&#xff0c;无法随时提供诊疗服务等问题。为此&#xff0c;运用软件工程开发规范&#xff0c;充分调研建立需求模型&#xff0c;编写开发文档…

Java输入和输出处理

一、Java I/O 文件、内存、键盘--->程序--->文件、内存、控制台 二、文件 相关记录或放在一起的数据的集合 思考&#xff1a; Java程序如何访问文件属性&#xff1f; 解答&#xff1a; Java API:java.io.File类 三、File类 File类的常用方法 方法名称说明boole…

maven项目结构管理统一项目配置操作

一、maven分模块开发 Maven 分模块开发 1.先创建父工程&#xff0c;pom.xml文件中&#xff0c;打包方式为pom 2.然后里面有许多子工程 3.我要对父工程的maven对所有子工程进行操作 二、解读maven的结构 1.模块1 <groupId>org.TS</groupId><artifactId>TruthS…

黑马点评-分布式锁业务

分布式锁原理和实现 分布式系统部署了多个tomcat&#xff0c;每个tomcat都有一个属于自己的jvm&#xff0c;那么假设在服务器A的tomcat内部&#xff0c;有两个线程&#xff0c;这两个线程由于使用的是同一份代码&#xff0c;那么他们的锁对象是同一个&#xff0c;是可以实现互…

2024 PhpStorm激活,分享几个PhpStorm激活的方案

文章目录 PhpStorm 公司简介我这边使用PhpStorm的理由PhpStorm 2023.3 最新变化AI Assistant 预览阶段结束 正式版基于 LLM 的代码补全测试代码生成编辑器内代码生成控制台中基于 AI 的错误解释 Pest 更新PHP 8.3 支持#[\Override] 特性新的 json_validate() 函数类型化类常量弃…

142.环形链表II

142.环形链表II 力扣题目链接(opens new window) 题意&#xff1a; 给定一个链表&#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 为了表示给定链表中的环&#xff0c;使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索引从 0…