最近再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