arduino笔记33:nRF24l01模块使用 FSK 波特率 通信方式 PTX PRX
最近再arduino中文社区看到了一篇介绍nrf24l01基本原理的帖子,内容感觉蛮不错的,学习一下,记录一下学习笔记。
大部分内容都是Arduino中文社区的帖子,附上自己的一点点体会。
目录
一、数据传输
FSK(Frequency Shift Keying)
波特率
可用频道
二、传输机制
一、数据传输
FSK(Frequency Shift Keying)
我们的数据其实就是一长串0和1的组合,无线传输就是想办法将0/1信号通过电磁波发送出去,专业的词汇叫信号调制,怎么做呢?
nrf2401使用的技术叫FSK(Frequency Shift Keying 直译过来叫频移键控,我认为翻译成键控频移更合适)。
说人话就是:以某个固定频率为基准(也叫载波),通过改变电磁波的频率来传递0或1,即在载波频率的基础上,发0时让频率高一点,发1时让频率低一点,接收端通过持续监测这种频率变化,从而识别出0或1,接收端的这个识别过程叫检波。
从度娘那里搞来一张图:
上面这张图就是FSK的基本原理简图,不过大家不要被这张图的某个细节所误导,即传递1的时候并不是一个正弦波就完事儿了,同样0也不是两三个正弦波就完事了,要准确地传递一个bit,对应的频率信号必须要稳定地持续一段时间,这样接收端才能准确的判断出这是一个有效的bit。
波特率
我们假设这个时间是T,(1/T)是啥呢?波特率!是不是很眼熟啊.
其实对于nrf2401来说,上文中的波特率准确的名字应该叫空中波特率(air-data-rate),就FSK的原理上来说,波特率可以是任意值,但nrf2401做了大幅简化,只允许使用3种固定的波特率,分别是 250Kbps/1Mbps/2Mbps,nrf2401允许我们在使用时给它指定一个波特率,3选1。
需要注意的是!!当nrf2401正处于接收数据或发送数据的工作状态时,不要修改波特率,你修改了,就破坏了当前这份数据的接收/发送规律,必然导致通信失败。
科普完了FSK的原理,有些问题自然而然就明了了:
(1)记得刚才说的"载波频率"吧,nrf2401把它叫做啥呢?"RF Channel frequency"!在nrf2401这里,载波频率是可调的,通过修改nrf2401内部相关寄存器的配置进行调节,既然是由寄存器来决定载波频率,那频率取值肯定是不连续了,以2400MHz为起始值,每隔1MHz取一个频率点,最大一直到2525MHz(设定频率的时候记得避开WiFi干扰),一共126个取值,nrf2401把这些值叫做 RF Channel。 和波特率一样的问题,收发数据的时候不要修改。
(2)由FSK的原理可知,两个模块一收一发,想要正常通信,双方必须使用同样的载波频率,也就是两边RF Channel的值必须相同
(3)由FSK的原理可知,当nrf2401在某载波频率上发送数据时,会占用一个窄窄的、以载波频率为为中心左右延伸的频带。承载bit信息的频率离载波频率越远,接收端越容易识别出这个bit,但坏处是会占用更宽的频带(这个道理应该不难理解吧?)。前面说了,RF Channel的频率间隔是1MHz,如果频带宽度超过了1MHz,那么相邻的两个RF Channel在频带上就会重叠,会相互干扰,这俩Channel就一起废了。
可用频道
当nrf2401的波特率是250Kbps或1Mbps时,可以做到频带宽度小于1MHz,这样就能保证126个RF Channel互不影响,也就是说,我们共有126个Channel可用,很完美。
但是当波特率是2Mbps的时候,情况出现了变化,频带宽度小于1MHz搞不定,只能做到让频带宽度小于2MHz,也就是说我们只有一半的Channel可以用了。
这是啥原理呢?
还记得前面说的那个时间T么?2Mbps时这个T只有500纳秒,即接收端在接收数据时只有500纳秒的时间来识别每个bit,如果承载bit信息的频率离载波频率太近,就无法保证可靠的识别,那只有加宽频带才能解决这个问题了。
以频带换时间。
二、传输机制
根据FSK的实现原理可以很明显的看出,这是串行传输模式。和串口传输几乎是一样的,唯一不同的是串口有TX RX两根线,通信两端可以同时接收/发送,互不影响。而反观nrf2401,它内部只有一个射频模块,任意时刻,射频模块只能在【关机/发射信号/接收信号】这3种工作状态中3选1,也就是nrf2401要么只能对外发送数据,要么只能接收数据。
来点儿专业词汇:
单工通信 | 两个通信节点,数据只能从本端传输到对端而不能反着来 |
双工通信 | 本端可以发数据给对端,对端也可以发数据给本端 |
全双工通信 | 本端随时可以发数据给对端,对端也可以随时发数据给本端,互不影响 |
半双工通信 | 虽然两端可以互传数据,但我发的时候你只能收不能发,同样你发的时候我也只能收不能发 |
综上可知,串口属于全双工通信,nrf2401属于半双工通信。
当我们使用nrf2401进行双向通信的时候,根据项目的不同应该会遇到各种各样的通信场景,我们讨论一下最复杂的情况:
两个无线节点互相通信,某一时刻,两边都有大量的数据想要尽快传送给对方。半双工的特性决定了肯定无法同时互相传输,应该怎么制定传输方案呢?
最简单的方法,我先发你收着,等我这边的数据发完了你再给我发。
这个方法原理上可行,但不合适:
1. 实时性差。 波特率不变时,数据量越大,传输耗时越长,我这边发给你的数据越多,开始收取你那边数据的时间就越靠后。
2. 不可靠。相比有线传输,无线传输从原理上就天然的不可靠,很容易受周围空间中其他电磁波的干扰。
巴拉巴拉传了一长串,万一中间某个地方干扰了一下,哪怕只导致一个bit解析出错,那对方收到的整份数据就是错误的。
现在换一种方法:
(1)我们双方约定好,公平使用传输通道,我让让你,你可以先发数据。但有个条件,不管你有多少数据要发给我,发数据的时候,每次发的字节数量不能超过某个固定长度,我们这里假设是32字节。发少了可以,发多了不行。
(2)你那边发完了这32字节数据之后,要立即转入接收状态。
此外,我对你还有个要求,一旦你进入了接收状态,不要一直死等,如果过了一段时间你没收到我发给你的数据,请切换到发送状态,把刚才发我的那段数据再发一遍。
(3)我收到你的数据之后,如果检查没错误,我会立即转入发送状态,把我这边的数据发给你,同样我也会遵守单次发送最大长度32字节的约定。
(4)如果我收到数据后检查发现有错误,那不好意思,就算我有数据要发给你,但因为你给我的数据是错误的,所以我不搭理你,等着你再给我发一遍。
(5)还有一种特殊情况:经检查你发的数据没问题,但我没什么数据要发给你,这时候,为了不让你在接收状态死等下去,我会简单发你一个"恩,收到了"之类的无意义回复。
(6)给你发完回复之后,我不关心你有没有收到,我会接着退出发送状态,进入接收状态继续等待。
(7)你在接收状态收到了我发给你的数据,知道了"我已收到你的数据",然后你就可以再次转入发送状态,将第二段数据发给我,继续重复前面的过程。
(8)如果你在接收状态下一直没收到我的回复,导致等待超时了,那说明刚才的交流某个环节出了问题。也许是我根本没收到你的数据,也许你的数据被我检查出错误来了,也许是我发你的回复你没收到。所以,你需要重新发送一次刚才发过的数据。
(9)某些极端情况下,你可能一遍遍的重发同样的数据,我一直没搭理你。然后,你怒了,能咋办?回家告状去呗!
以上的描述就是nrf2401实现可靠双向通信的基本过程。
可以看出,上文中的"你"主动性更大,每次通信的时候,都是由"你"发起的,"我"只是被动的接收,
然后"我"通过"回复(ACK)"的方式变相的把"我"这边的数据回传给"你".
通信过程的异常控制也是有"你"这一端来掌控的,包括 超时控制 / 重发控制 / 重发失败足够次数之后终止通信并报错。
nrf2401把行为如"你"的这一端叫做"主发送端"(Primary Transmitter,简称PTX),
把行为如"我"的这一端叫做"主接收端"(Primary Receiver,简称PRX),
以后讨论时我们只使用 PTX / PRX 这两个简写,大家记一下。
还有一点需要特别强调:
PTX虽然叫PTX,但PTX可以进入"发送模式"发送数据,也可以进入"接收模式"接收数据;
PRX同样既可以进入"发送模式"发送数据, 也可以进入"接收模式"接收数据;
PTX/PRX指的是控制逻辑;"发送/接收模式"指的是射频部分的工作状态,切记两者不要混淆。
我们计算一下,单次发送32字节数据,需要多长时间:
2Mbps 波特率: 32*8/2000000 = 128 微秒
1Mbps 波特率: 32*8/1000000 = 256 微秒
250Kbps波特率: 32*8/250000 = 1024 微秒 1毫秒多一点点
可以看出这个时间是很短的,在此基础上,把时间轴拉长,从宏观上看,可以近似看做两端是在同时、双向通信。
这种方案本质上是将时间划分为多个很小的片段,随着时间片的向前推进,通信双方交替使用唯一的信号通道向对端发送数据。
专业的词汇叫: 时分复用(Time Division Multiplexing,TDM)
【关于上面那一长段你我交互的过程,大家仔细看看,确保弄清各个环节,对于后面理解更细致的通信过程有很大帮助。】
来源:
https://www.arduino.cn/forum.php?mod=viewthread&tid=86275&extra=&authorid=175094&page=1
arduino笔记33:nRF24l01模块使用 FSK 波特率 通信方式 PTX PRX相关推荐
- 开源自制6通道航模遥控器,Arduino Pro Mini NRF24L01模块
前言 前段时间跟着LOLI大神的教程制作了LOLI三代控,效果很好.但是,由于LOLI三代控的接收机带有数据回传功能,也就是接收机的无线模块也承担了发射数据功能,所以接收机也要使用带有功率放大芯片的N ...
- Arduino笔记-9110风扇模块的使用
图是这样的: 这个模块是这样的: 在这个项目中9110风扇模块GND接地,VCC接Arduino的5V,INA为低,INB为高时,正转,INA为高,INB为低就反转, 这里我把INB接到9号口,INA ...
- Arduino笔记实验(初级阶段)—继电器模块
Arduino笔记实验(初级阶段)-继电器模块 文章目录 Arduino笔记实验(初级阶段)-继电器模块 前言 一.电路图 二.继电器模块实验 代码 实验效果展示 三.继电器模块 实验总结 前言 自学 ...
- 【STM32】NRF24L01模块的收发调试
NRF24L01 发送端.c文件 发送端.h文件 接收端.c文件 接收端.h文件 接收端main函数 总结: 这里我是用了两块板子来做通信实验,这里我就直接贴发送端和接收端的.c.h文件,一个是用标准 ...
- 【STM32CubeMX】NRF24L01模块实现“1对1“及“1对多“无线通信
大家好,我是小政.本篇文章我将针对NRF24L01模块实现"1对1"及"1对多"无线通信的STM32CubeMX配置过程进行详细的讲解,让准备学习HAL库的 ...
- 笔记33 笨办法学python练习40之二:类和对象
笔记33 笨办法学python练习40之二:类和对象 类和模块差不多么?把这个练习继续往下做,看是否真有如此结果.刚刚对模块有了点感觉,加上这个类class也是要创建,但这个练习所创建的class M ...
- Arduino与LU-ASR01语音识别模块的双向串口通信实现
之前我写了一篇<Arduino的智能语言输入实现>,讨论了Arduino与LU-ASR01之间通过串口通信实现Arduino的中文语音输入,不过那个通信是不完整的,因为LU-ASR01的串 ...
- 【Arduino笔记】超声波传感器的使用
这里使用:超声波传感器HC-SR04型号,搭配SG90舵机. 超声波简介 测量距离:2 ~ 400cm 分辨率:0.3cm 测量频率:40Hz 测量角度:15° 工作电压:4.5 ~ 5.5V 工作电 ...
- Arduino使用HC05蓝牙模块与手机连接
通过本文,可以了解到以下内容: 进入 AT 模式进行蓝牙基本参数设置 Arduino 蓝牙控制 LED 电路设计以及代码编写 利用 Andorid 蓝牙串口调试软件测试功能 进入 At 模式进行蓝牙基 ...
最新文章
- 《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(六)图像修补
- 【号外号外:微软收购 .NET 的开源实现 Xamarin 项目的公司】
- 想知道你在网上的发言,被怎么分析么?
- TP5:验证器的封装——5
- Android之父深入解析Android
- [SVN] 分支同步、合入主干操作分享
- MLNC – Machine Learning Neural Computation
- dwg格式的计算机图,例举电脑dwg文件怎么打开
- 【MATLAB数据分析】01数据的均值、变异度、偏度和峰度
- NOI2014 起床困难综合症
- 1054 The Dominant Color(20 分)
- 怎样批量修改文件名不要括号?
- NCRE公共基础知识(一) 计算机系统
- 前端的扁平化是什么意思
- python语言程序设计——蒙特·卡罗方法求圆周率
- 多彩M618XSD垂直立式人体工学鼠标拆解
- html界面——button设置样式
- vscode EIDE 使用手册
- 雷达监控与视频监控性能对比分析
- 隐私泄露、AI换脸存风险 11家企业被约谈