风筝
发表于: 2022-6-21 11:51:42 | 显示全部楼层

如果能让两个或多个Arduino开发板彼此之间无线通信,就可以产生很多的应用,例如远程监控传感器数据、控制机器人、家庭自动化等。对于经济实惠但可靠的RF解决方案,没有比Nordic Semiconductor公司的nRF24L01+收发器模块做得更好的了。


nRF24L01+模块通常可以在网上以不到2美元的价格获得,使其成为您能找到的最实惠的数据通信方式之一。并且这些模块尺寸非常小,允许您将无线连接集成到几乎任何项目中。


硬件概述

无线电频率

nRF24L01+模块设计用于在全球ISM频段2.4 GHz下运行,并使用GFSK调制进行数据传输。数据传输速率是可配置的,可以是250kbps、1Mbps和2Mbps。


2.4 GHz频段是国际上为无需许可的低功率设备保留的工业、科学和医疗 (ISM) 频段之一。诸如无绳电话、蓝牙设备、近场通信 (NFC) 设备和无线计算机网络 (WiFi) 等设备都使用ISM频率。


电源

该模块的工作电压范围为1.9至3.6V,但好消息是逻辑引脚可承受 5V 电压,因此您可以放心地将其与您最喜欢的 3.3V 或 5V 微控制器一起使用。


该模块支持可编程输出功率,即 0 dBm、-6 dBm、-12 dBm 或 -18 dBm。在 0 dBm 时,模块在传输期间仅消耗 12 mA,低于单个LED灯的消耗。另外它在待机模式下消耗 26 µA,在断电模式下消耗 900 nA。这就是为什么它是低功耗应用的首选无线设备。


SPI接口

nRF24L01+ 通过 4 针 SPI(串行外设接口)进行通信,最大数据速率为 10Mbps。频率通道(125 个可选通道)、输出功率(0 dBm、-6 dBm、-12 dBm 或 -18 dBm)和数据速率(250kbps、1Mbps 或 2Mbps)等所有参数都可以通过 SPI 接口进行配置。


SPI 总线使用主从的概念。在我们的大多数项目中,Arduino 是主机,nRF24L01+ 模块是从机。


与 I2C 总线不同,SPI 总线的从机数量有限。这就是为什么您可以在一个Arduino 上使用最多两个 SPI 从设备,即两个 nRF24L01+ 模块。


技术规格

以下是完整的规格:

●    频率范围:2.4 GHz ISM 频段

●    最大空中数据速率:2 Mb/s

●    调制格式:GFSK

●    最大输出功率: 0 dBm

●    工作电源电压:1.9 V 至 3.6 V

●    最大工作电流:13.5mA

●    电流(待机模式):26µA

●    逻辑输入:5V 容限

●    通信范围: 800+ m


nRF24L01+ 模块与nRF24L01+ PA/LNA模块

市场上有多种基于 nRF24L01+ 芯片的模块。以下是两个最受欢迎的版本。


nRF24L01-Wireless-Transceiver-Module.jpg


第一个版本使用板载天线,允许更紧凑的分支版本。然而,更小的天线也意味着更短的传输范围。


使用此版本,您将能够在100米的距离内进行通信。当然,那是在户外的空旷地方。它的范围在房子内变得有点弱。


nRF24L01-PA-LNA-External-Antenna-Wireless-Transceiver-Module.jpg


第二个版本带有一个 SMA 连接器和一个鸭形天线,但这不是唯一的区别。它带有一个特殊的RFX2401C范围扩展芯片,集成了PA、LNA和收发切换电路。该芯片帮助模块实现更大的传输范围,可达 1000 米。


除了这个区别,两个模块都是兼容的。这意味着,如果您使用其中一个构建项目,您可以简单地拔下它并使用另一个,而无需对系统进行任何更改。


什么是PA和LNA?

PA代表功率放大器。它只会放大从 nRF24L01+ 芯片传输的信号强度。而LNA代表低噪声放大器,其功能是从天线获取极弱的信号(通常低于微伏或 -100 dBm)并将其放大到更有用的电平(通常约为 0.5 至 1 V)。

nRF24L01-RF-PA-LNA-Power-Amplifier-Low-Noise-Amplifier-Block-Diagram.jpg


接收路径的低噪声放大器 (LNA) 和发射路径的功率放大器 (PA) 通过双工器连接到天线,将两个信号隔离,防止相对强大的 PA 输出使敏感的 LNA 输入过载。


nRF24L01+ 模块如何工作?

nRF24L01+ 模块在称为信道的特定频率上发送和接收数据。要让两个或多个模块相互通信,它们必须在同一信道上。该信道可以是 2.4 GHz ISM 频段中的任何频率,或者更准确地说,它可以在 2.400 到 2.525 GHz(2400 到 2525 MHz)之间。


每个信道占用不到 1MHz 的带宽。这为我们提供了 125 个可能的信道,间隔为 1MHz。


这意味着 nRF24L01+ 可以使用 125 个不同的信道,允许您在一个地方创建一个由 125 个独立工作的调制解调器组成的网络。

nRF24L01-Wireless-Transceiver-2.4GHz-125-RF-Channels-1MHz-Spacing.jpg


该信道在250kbps和1Mbps空中数据速率下占用小于 1MHz 的带宽。然而,在 2 Mbps 的空中数据速率下,需要 2MHz 的带宽(大于 RF 通道频率设置的分辨率)。因此,在 2 Mbps 模式下,您应该在两个信道之间保持 2MHz 的间隙,以确保信道不重叠并减少串扰。


您选择的信道的频率根据以下公式确定:

频率(选定)= 2400 + CH(选定)


例如,如果您选择 108 作为您的数据传输通道,则您的通道的 RF 通道频率将为 2508 MHz (2400 + 108)。


nRF24L01+ 多接收器网络

nRF24L01+ 具有称为 Multiceiver 的功能。它是Multiple Transmitter Single Receiver的缩写。


在多接收机网络中,每个RF通道在逻辑上分为6个并行数据通道,称为数据管道。换言之,数据管道是单个物理射频通道中的六个逻辑通道之一。每个数据管道都有自己唯一的地址,称为数据管道地址。一次只能有一个数据管道接收一个数据包。


多接收机网络可以描述如下。

nRF24L01-Wireless-Multiceiver-Network-Multiple-Transmitters-Single-Receiver.jpg


要了解多服务器网络,请想象主接收器充当集线器接收器,同时从 6 个不同的发送器节点收集信息。集线器接收器可以随时停止收听并充当发送器。


增强型 ShockBurst 协议

nRF24L01+ 使用称为增强型 ShockBurst 的数据包结构。这个简单的数据包结构分为 5 个不同的字段,如下所示。

nRF24L01-Wireless-Transceiver-Enhanced-ShockBurst-Packet-Structure.jpg


最初的Shockburst 结构只包括Preamble、Address、Payload 和Cyclic Redundancy Check (CRC) 字段。增强型 Shockburst 使用新引入的数据包控制字段 (PCF) 为更高级的通信带来了更多功能。


这种新结构之所以很棒,有几个原因。

●    首先,它允许带有有效载荷长度说明符的可变长度有效载荷,这意味着有效载荷可以在 1 到 32 字节之间变化。

●    其次,它为每个发送的数据包分配一个数据包 ID,这允许接收设备确定消息是新消息还是已重传。

●    最后,也是最重要的一点,每条消息都可以请求接收者在收到消息后发送确认。


nRF24L01+ 自动数据包处理

让我们讨论三个场景,以更好地了解两个nRF24L01+模块如何相互交互。


●    带有确认的事务

这是一个主动情景的例子。在这里,发送器通过向接收器发送数据包来启动通信。一旦数据包被发送,它会等待大约 130 µs 以接收确认数据包(ACK 数据包)。当接收器接收到数据包时,它会向发送器发送 ACK 数据包。当发送方收到 ACK 数据包时,事务结束。

nRF24L01-Transceiver-Working-Packet-Transmission-Acknowledgement-Lost.gif


●    丢失数据包的事务

这是由于传输的数据包丢失而需要重新传输的被动示例。数据包发送完毕后,发送方等待接收 ACK 数据包。


如果发送器在自动重传延迟 (ARD) 时间内没有收到它,它会重传数据包。当接收方接收到重传的数据包时,它会发送 ACK 数据包,从而终止事务。

nRF24L01-Transceiver-Working-Packet-Transmission.gif

●    确认丢失的事务

这又是一个负面情况,其中由于ACK数据包丢失而需要重新传输。这里即使接收者自己在第一次尝试中已经收到了数据包,但由于ACK数据包丢失,发送者认为接收者没有收到数据包。


因此,在 Auto-Retransmit-Delay 超时后,发送器重新传输数据包。现在,当接收方收到与之前相同ID的数据包时,它会丢弃它并再次发送ACK数据包。当发送方收到ACK数据包时,事务结束。


nRF24L01-Transceiver-Working-Packet-Transmission-Data-Lost.gif


整个数据包处理由 nRF24L01+ 芯片自动完成,无需微控制器参与。

跳转到指定楼层
风筝
发表于: 2022-6-21 14:59:44 | 显示全部楼层

nRF24L01+模块的引脚

让我们来看看这两个版本的nRF24L01+模块的引脚排列。

Pinout-nRF24L01-Wireless-Transceiver-Module.jpg


Pinout-nRF24L01-PA-LNA-External-Antenna-Wireless-Transceiver-Module.jpg


GND 是接地引脚。它标有一个正方形,以将其与其他引脚区分开来。

VCC 为模块供电。它可以在1.9到3.9V之间的电压。您可以将其连接到Arduino的3.3V输出。请记住,将其连接到5V引脚可能会破坏nRF24L01+模块!

CE(芯片使能)是一个高电平有效引脚。选择后,nRF24L01 将根据当前所处的模式发送或接收。

CSN(非芯片选择)是低电平有效引脚,通常保持高电平。当此引脚变为低电平时,nRF24L01开始侦听其SPI端口上的数据并相应地对其进行处理。

SCK(串行时钟)接收SPI总线主机提供的时钟脉冲。

MOSI (Master Out Slave In) 是nRF24L01模块的SPI输入。

MISO (Master In Slave Out) 是nRF24L01模块的SPI输出。

IRQ 是一个中断引脚,当有新数据可供处理时,它可以提醒主机。


将 nRF24L01+模块连接到Arduino

现在我们已经完全了解了nRF24L01+模块的工作原理,我们可以开始将它连接到Arduino!


首先,将模块上的VCC引脚连接到3.3V,将GND引脚连接到Arduino的GND。引脚CSN和CE可以连接到Arduino上的任意数字引脚。在例子中,它们分别连接到数字引脚#8 和#9。现在我们介绍用于SPI通信的引脚。


由于nRF24L01+模块需要大量数据传输,因此当连接到微控制器上的硬件SPI引脚时,它会提供最佳性能。请注意,每个Arduino开发板都有不同的SPI引脚,必须相应地连接。检查下表以快速了解。

MOSI
MISO
SCK
Arduino Uno
11
12
13
Arduino Nano
11
12
13
Arduino Mega
51
50
52

如果您使用的Arduino与上述板子不同,请在继续之前查看Arduino的官方文档


请记住,您需要制作两个这样的电路。一个将充当发射器,另一个充当接收器。两者具有相同的接线。

Arduino-Wiring-Fritzing-Connections-with-nRF24L01-Wireless-Transceiver-Module.jpg


Arduino-Wiring-Fritzing-Connections-with-nRF24L01-PA-LNA-External-Antenna-Wirele.jpg


一切连接完成后,你就可以开始代码了!


安装库文件

连接nRF24L01+模块需要做很多工作,但幸运的是我们有很多库可供使用。其中比较流行的库是 RF24。这个库已经存在很多年了。它对初学者来说很容易使用,但仍然为高级用户提供了很多功能。这是我们将在示例中使用的库。


您可以在RF24 GitHub存储库下载最新版本的库:https://github.com/nRF24/RF24


要安装该库文件,请打开 Arduino IDE,转到 Sketch > Include Library > Add .ZIP Library,然后选择刚刚下载的 RF24-master 文件。如果您需要有关设置库的更多信息,请访问安装Arduino库教程

回复

使用道具 举报

风筝
发表于: 2022-6-21 15:40:03 | 显示全部楼层

Arduino示例代码 - 发射器

以下是我们用于发射器的代码。它仅向接收器发送“Hello World”消息。

  1. //Include Libraries
  2. #include <SPI.h>
  3. #include <nRF24L01.h>
  4. #include <RF24.h>

  5. //create an RF24 object
  6. RF24 radio(9, 8);  // CE, CSN

  7. //address through which two modules communicate.
  8. const byte address[6] = "00001";

  9. void setup()
  10. {
  11.   radio.begin();
  12.   
  13.   //set the address
  14.   radio.openWritingPipe(address);
  15.   
  16.   //Set module as transmitter
  17.   radio.stopListening();
  18. }
  19. void loop()
  20. {
  21.   //Send message to receiver
  22.   const char text[] = "Hello World";
  23.   radio.write(&text, sizeof(text));
  24.   
  25.   delay(1000);
  26. }
复制代码

草图首先包含所需的库。 SPI.h库处理SPI通信,而nRF24L01.h和RF24.h控制模块。

  1. //Include Libraries
  2. #include <SPI.h>
  3. #include <nRF24L01.h>
  4. #include <RF24.h>
复制代码

接下来我们新建一个RF24对象。该对象的构造函数接受两个引脚号作为连接CE和CSN信号的参数。

  1. //create an RF24 object
  2. RF24 radio(9, 8);  // CE, CSN
复制代码

接下来,我们创建一个字节数组,表示两个nRF24L01+模块将通过该信道地址进行通信。

  1. //address through which two modules communicate.
  2. const byte address[6] = "00001";
复制代码

信道地址不必一定是“00001”,可以是“node1”等任意5个字符的字符串,只要发送方和接收方使用相同的地址即可。如果您的网络中的模块很少,您可以选择一个特定的模块并在该信道与之通信。


setup()函数中,我们首先调用 begin() 函数来初始化radio对象,然后调用 openWritingPipe() 函数来设置发送器地址。

  1. radio.begin();

  2. //set the address
  3. radio.openWritingPipe(address);
复制代码

最后,我们使用 stopListening() 函数将模块设置为发送器。

  1. //Set module as transmitter
  2. radio.stopListening();
复制代码

在loop()函数中,首先我们创建一个字符数组并将消息“Hello World”给它赋值。


我们使用 write() 函数将该消息发送给接收器。此函数接受两个参数,第一个是您要发送的消息,第二个是它包含的字节数。

  1. const char text[] = "Hello World";
  2. radio.write(&text, sizeof(text));
复制代码

请注意,您一次最多可以发送32个字节的消息,因为这是nRF24L01+可以处理的最大数据包大小。


如果您需要确认接收方已收到数据,则write()方法会返回一个bool值。当数据到达接收器时返回TRUE,如果数据丢失则返回FALSE。请注意,write() 函数会阻塞程序,直到它收到确认或用完所有重传尝试。


Arduino 示例代码 - 接收器

以下是我们用于接收器的草图代码。

  1. //Include Libraries
  2. #include <SPI.h>
  3. #include <nRF24L01.h>
  4. #include <RF24.h>

  5. //create an RF24 object
  6. RF24 radio(9, 8);  // CE, CSN

  7. //address through which two modules communicate.
  8. const byte address[6] = "00001";

  9. void setup()
  10. {
  11.   while (!Serial);
  12.     Serial.begin(9600);
  13.   
  14.   radio.begin();
  15.   
  16.   //set the address
  17.   radio.openReadingPipe(0, address);
  18.   
  19.   //Set module as receiver
  20.   radio.startListening();
  21. }

  22. void loop()
  23. {
  24.   //Read the data if available in buffer
  25.   if (radio.available())
  26.   {
  27.     char text[32] = {0};
  28.     radio.read(&text, sizeof(text));
  29.     Serial.println(text);
  30.   }
  31. }
复制代码

此代码与发射器的代码非常相似,只需要有一些更改。


在setup()函数中,我们启动串口通信。之后使用 openReadingPipe() 函数,我们设置与发射器相同的地址。通过这种方式,我们实现了发射器和接收器之间的通信。

  1.   //set the address
  2.   radio.openReadingPipe(0, address);
复制代码

openReadingPipe() 函数的第一个参数是流的编号。我们只为流#0 创建了地址,但是您最多可以创建六个响应不同地址的流。第二个参数是流将响应以收集数据的地址。


下一步是将模块设置为接收器并开始接收数据。为此,我们使用 startListening() 函数。从这一刻起,调制解调器开始等待发送到指定地址的数据。

  1. //Set module as receiver
  2.   radio.startListening();
复制代码

loop()函数中的代码使用 available() 方法检查地址是否有任何数据已到达。当缓冲区中有可用数据时,此函数返回TRUE。

  1. if (radio.available())
  2.   {
  3.     char text[32] = {0};
  4.     radio.read(&text, sizeof(text));
  5.     Serial.println(text);
  6.   }
复制代码

当数据可用时,将创建一个由32个字符组成的以零填充的数组。然后我们使用 read(& text, sizeof (text)) 方法从缓冲区中读取数据并将其存储在我们的字符数组中。


最后,我们在串口行监视器上打印收到的消息。如果一切正常,您应该在串口监视器中看到类似的内容。

nRF24L01-Transceiver-RF24-Library-Sketch-Output-on-Serial-Monitor.png


提高nRF24L01+模块通信范围的方法

无线通信系统的一个关键参数是通信范围。在许多情况下,这是选择射频解决方案的决定性因素。因此,让我们讨论一下我们可以做些什么来为我们的模块获得更好的范围。


降低电源噪声

产生射频 (RF) 信号的射频电路对电源噪声非常敏感。如果不加以控制,电源噪声会显着降低您可以达到的范围。


除非电源是独立电池,否则很有可能存在与电源输出相关的噪声。为防止这种噪声进入系统,建议在电源线上放置一个10 µf滤波电容,尽可能靠近 nRF24L01+ 模块。


另一种最简单方法是为 nRF24L01+ 模块使用非常便宜的适配器。

nRF24L01-5V-Power-Adapter.jpg


该适配器有一个8针排母,可让您插入nRF24L01+模块。它可以容纳我们之前讨论的 nRF24L01+ 模块的两个版本——一个带有集成天线,另一个带有外部天线 (PA/LNA)。它还有一个用于SPI和中断连接的6针排针,以及一个用于电源输入的2针连接器。


适配器自带3.3V稳压和滤波电容,用5V电源供电即可,不用担心。


更改信道频率

RF电路的另一个潜在噪声源是外部环境,尤其是当您将相邻网络设置在同一通道上时。


由于WiFi主要使用较低频率的通道,因此建议使用您的nRF24L01+的最高25个通道,以防止这些信号造成问题。


使用较低的数据速率

nRF24L01+以250Kbps的速度提供最高的接收器灵敏度,即 -94dBm。然而,在2MBps数据速率下,接收器灵敏度下降到-82dBm。这意味着接收器在250kbps时的灵敏度是2Mbps时的10倍。换句话说,在250kbps时,接收器可以解码10倍弱的信号。


因此,降低数据速率可以显着提高您可以达到的范围。加上250kbps的速度对于我们的大多数项目来说已经绰绰有余了。接收器灵敏度是接收器可以检测到射频信号的最小功率电平。负数的绝对值越大,接收机的灵敏度越好。例如,-94dBm 的接收器灵敏度比-82dBm 的接收器灵敏度高12dB。


使用更高的输出功率

设置最大输出功率也可以提高通信范围。 nRF24L01+ 让您可以选择不同的输出功率选项,例如 0dBm、-6dBm、-12dBm 或 -18dBm。选择0dBm输出功率会以更高的功耗为代价将更强的信号发送到空中。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1483



手机版|

GMT+8, 2024-5-13 20:39 , Processed in 0.044570 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表