风筝
发表于: 2018-11-11 21:41:50 | 显示全部楼层

在本篇文章中,我们将学习如何使用NRF24L01收发器模块在两个Arduino开发板之间进行无线通信。为了说明无线通信,我们将举两个例子,第一个是从一个Arduino开发板向另一个发送简单的“Hello World”消息,在第二个例子中,我们将在Arduino开发板之间进行双向通信,其中我们使用在第一个Arduino开发板的操纵杆,控制在第二个Arduino开发板的伺服电机,反之亦然,使用第二个Arduino开发板的按钮,我们将控制第一个Arduino开发板的LED灯。

Arduino-and-NRF24L01-Tutorial-Example-2.jpg


NRF24L01收发器模块

让我们来看看NRF24L01收发器模块。它使用2.4 GHz频段,可以在250 kbps到2 Mbps的波特率下运行。如果在开放空间中使用且波特率较低,其范围可达100米。

NRF24L01-Transceiver-Module.jpg

该模块可以使用125个不同的通道,可以在一个地方拥有125个独立工作的调制解调器网络。每个通道最多可以有6个地址,或者每个单元可以同时与多达6个其他单元通信。

NRF24L01-Working-Principles-of-Channels-and-Addresses.png

在传输过程中,该模块的功耗仅为12mA左右,甚至低于单个LED。该模块的工作电压范围为1.9至3.6V,但好处是其他引脚可以容忍5V逻辑,因此我们可以轻松地将其连接到Arduino而无需使用任何逻辑电平转换器。

NRF24L01-Transceiver-Module-Pinouts-Connections.jpg

其中三个引脚用于SPI通信,它们需要连接到Arduino的SPI引脚,但请注意每个Arduino开发板都有不同的SPI引脚。引脚CSN和CE可以连接到Arduino板的任何数字引脚,它们用于将模块设置为待机或活动模式,以及用于在发送或命令模式之间切换。最后一个引脚是一个不必使用的中断引脚。


因此,一旦我们将NRF24L01模块连接到Arduino开发板,我们就可以为发射器和接收器制作代码了。

NRF24L01-and-Arduino-Tutorial-Circuit-Schematic.png

示例所需的组件如下:

●    NRF24L01收发器模块

●    Arduino开发板

●    面包板和跳线


Arduino代码

首先,我们需要下载并安装RF24库,这使得编程变得简单。

以下是无线通信的两个代码,在代码下面是对它们的解释。

发射机代码

  1. /*
  2. * Arduino Wireless Communication Tutorial
  3. *     Example 1 - Transmitter Code
  4. *               
  5. * by Dejan Nedelkovski, www.HowToMechatronics.com
  6. *
  7. * Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
  8. */
  9. #include <SPI.h>
  10. #include <nRF24L01.h>
  11. #include <RF24.h>
  12. RF24 radio(7, 8); // CE, CSN
  13. const byte address[6] = "00001";
  14. void setup() {
  15.   radio.begin();
  16.   radio.openWritingPipe(address);
  17.   radio.setPALevel(RF24_PA_MIN);
  18.   radio.stopListening();
  19. }
  20. void loop() {
  21.   const char text[] = "Hello World";
  22.   radio.write(&text, sizeof(text));
  23.   delay(1000);
  24. }
复制代码

接收机代码

  1. /*
  2. * Arduino Wireless Communication Tutorial
  3. *       Example 1 - Receiver Code
  4. *               
  5. * by Dejan Nedelkovski, www.HowToMechatronics.com
  6. *
  7. * Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
  8. */
  9. #include <SPI.h>
  10. #include <nRF24L01.h>
  11. #include <RF24.h>
  12. RF24 radio(7, 8); // CE, CSN
  13. const byte address[6] = "00001";
  14. void setup() {
  15.   Serial.begin(9600);
  16.   radio.begin();
  17.   radio.openReadingPipe(0, address);
  18.   radio.setPALevel(RF24_PA_MIN);
  19.   radio.startListening();
  20. }
  21. void loop() {
  22.   if (radio.available()) {
  23.     char text[32] = "";
  24.     radio.read(&text, sizeof(text));
  25.     Serial.println(text);
  26.   }
  27. }
复制代码

代码描述:

我们需要包含基本SPI和新安装的RF24库,并创建一个RF24对象。这里的两个参数是CSN和CE引脚。

  1. RF24 radio(7, 8); // CE, CSN
复制代码

接下来,我们需要创建一个字节数组,它将代表地址,或两个模块通过的所谓管道。

  1. const byte address[6] = "00001";
复制代码

我们可以将此地址的值更改为任意5个字母的字符串,这样就可以选择我们要说话的接收器,因此在本例中,我们将在接收器和发送器上具有相同的地址。


在设置部分,我们需要初始化无线电对象,并使用radio.openWritingPipe()函数设置我们将发送数据的接收器的地址,即我们之前设置的5个字母的字符串。

  1. radio.openWritingPipe(address);
复制代码

另一方面,在接收器处,使用radio.setReadingPipe()函数,我们设置相同的地址,并以此方式启用两个模块之间的通信。

  1. radio.openReadingPipe(0, address);
复制代码

然后使用radio.setPALevel()函数设置功率放大器电平,在我们的例子中,我将其设置为最小值,因为我的模块彼此非常接近。

  1. radio.setPALevel(RF24_PA_MIN);
复制代码

请注意,如果使用更高的电平,建议在GND和3.3V模块之间使用旁路电容,以便在工作时具有更稳定的电压。


接下来我们有了radio.stopListening()函数,它将模块设置为发送器,另一方面,我们有radio.startListening()函数,它将模块设置为接收器。

  1. // at the Transmitter
  2. radio.stopListening();
复制代码
  1. // at the Receiver
  2. radio.startListening();
复制代码

在发送器的loop函数中,我们创建了一个字符数组,并为其分配消息“Hello World”。使用radio.write()函数,我们将该消息发送给接收器。这里的第一个参数是想要发送的变量。

  1. void loop() {
  2. const char text[] = "Hello World";
  3. radio.write(&text, sizeof(text));
  4. delay(1000);
  5. }
复制代码

通过在变量名之前使用“&”,我们实际上设置了一个指示存储我们想要发送的数据的变量,并使用第二个参数设置了我们想要从该变量中获取的字节数。在这种情况下,sizeof()函数获取字符串“text”的所有字节。在程序结束时,我们将增加1秒的延迟。


另一方面,在接收器,在loop()函数部分中,通过使用radio.available()函数,我们检查是否有要接收的数据。如果有数据,首先我们创建一个由32个元素组成的数组,每个元素称为“text”,我们将在其中保存传入的数据。

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

通过使用radio.read()函数,我们读取数据并将其存储到变量“text”中。最后,我们只在串口监视器上打印文本。因此,在我们上传了两个程序之后,就可以在接收器上运行串口监视器,我们会注意到每秒打印一条消息“Hello World”。

跳转到指定楼层
风筝
发表于: 2018-11-11 22:00:34 | 显示全部楼层

Arduino无线双向通信

让我们看看第二个例子,在两个Arduino开发板之间的双向无线通信。以下是电路原理图:

Arduino-Wireless-Communication-NRF24L01-Circuit-Schematic-Tutorial.png


以下是示例所需的组件:

●    NRF24L01收发器模块

●    Arduino开发板

●    操纵杆模块

●    伺服电机

●    按钮

●    LED指示灯


源代码

以下是两个代码,以及对它们的描述。


发射机代码

  1. /*
  2. * Arduino Wireless Communication Tutorial
  3. *     Example 2 - Transmitter Code
  4. *               
  5. * by Dejan Nedelkovski, www.HowToMechatronics.com
  6. *
  7. * Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
  8. */
  9. #include <SPI.h>
  10. #include <nRF24L01.h>
  11. #include <RF24.h>
  12. #define led 12
  13. RF24 radio(7, 8); // CE, CSN
  14. const byte addresses[][6] = {"00001", "00002"};
  15. boolean buttonState = 0;
  16. void setup() {
  17.   pinMode(12, OUTPUT);
  18.   radio.begin();
  19.   radio.openWritingPipe(addresses[1]); // 00001
  20.   radio.openReadingPipe(1, addresses[0]); // 00002
  21.   radio.setPALevel(RF24_PA_MIN);
  22. }
  23. void loop() {
  24.   delay(5);
  25.   radio.stopListening();
  26.   int potValue = analogRead(A0);
  27.   int angleValue = map(potValue, 0, 1023, 0, 180);
  28.   radio.write(&angleValue, sizeof(angleValue));
  29.   delay(5);
  30.   radio.startListening();
  31.   while (!radio.available());
  32.   radio.read(&buttonState, sizeof(buttonState));
  33.   if (buttonState == HIGH) {
  34.     digitalWrite(led, HIGH);
  35.   }
  36.   else {
  37.     digitalWrite(led, LOW);
  38.   }
  39. }
复制代码

接收机代码

  1. /*
  2. * Arduino Wireless Communication Tutorial
  3. *     Example 2 - Receiver Code
  4. *               
  5. * by Dejan Nedelkovski, www.HowToMechatronics.com
  6. *
  7. * Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
  8. */
  9. #include <SPI.h>
  10. #include <nRF24L01.h>
  11. #include <RF24.h>
  12. #include <Servo.h>
  13. #define button 4
  14. RF24 radio(7, 8); // CE, CSN
  15. const byte addresses[][6] = {"00001", "00002"};
  16. Servo myServo;
  17. boolean buttonState = 0;
  18. void setup() {
  19.   pinMode(button, INPUT);
  20.   myServo.attach(5);
  21.   radio.begin();
  22.   radio.openWritingPipe(addresses[0]); // 00002
  23.   radio.openReadingPipe(1, addresses[1]); // 00001
  24.   radio.setPALevel(RF24_PA_MIN);
  25. }
  26. void loop() {
  27.   delay(5);
  28.   radio.startListening();
  29.   if ( radio.available()) {
  30.     while (radio.available()) {
  31.       int angleV = 0;
  32.       radio.read(&angleV, sizeof(angleV));
  33.       myServo.write(angleV);
  34.     }
  35.     delay(5);
  36.     radio.stopListening();
  37.     buttonState = digitalRead(button);
  38.     radio.write(&buttonState, sizeof(buttonState));
  39.   }
  40. }
复制代码

与前一个示例的不同之处在于,我们需要为双向通信创建两个管道或地址。

  1. const byte addresses[][6] = {"00001", "00002"};
复制代码

在setup函数部分我们需要定义两个管道,并注意第一个Arduino的写地址需要是第二个Arduino的读地址,反之亦然,第一个Arduino的读地址需要是写地址。第二个Arduino。

  1. // at the Transmitter
  2. radio.openWritingPipe(addresses[1]); // 00001
  3. radio.openReadingPipe(1, addresses[0]); // 00002
复制代码

在loop函数中,使用radio.stopListening()函数,我们将第一个Arduino设置为发送器,读取并将操纵杆的值从0映射到180,并使用radio.write()函数将数据发送到接收器。

  1. radio.stopListening();
  2. int potValue = analogRead(A0);
  3. int angleValue = map(potValue, 0, 1023, 0, 180);
  4. radio.write(&angleValue, sizeof(angleValue));
复制代码

另一方面,使用radio.startListening()函数,我们将第二个Arduino设置为接收器,并检查是否有可用数据。当有数据可用时,我们将读取它,将其保存到“angleV”变量,然后使用该值旋转伺服电机。

  1. radio.startListening();
  2.   if ( radio.available()) {
  3.     while (radio.available()) {
  4.       int angleV = 0;
  5.       radio.read(&angleV, sizeof(angleV));
  6.       myServo.write(angleV);
  7.     }
复制代码

接下来,在发送器中,我们将第一个Arduino开发板设置为接收器,并使用空的“while”循环,我们等待第二个Arduino开发板发送数据,数据表示按钮状态是否被按下。如果按下按钮,LED将点亮。这些过程不断重复,并且两个Arduino开发板都不断发送和接收数据。

回复

使用道具 举报

1535749376
发表于: 2018-12-17 20:24:18 | 显示全部楼层

可以给我RF24.h这个库函数吗
我网上没有找到
回复

使用道具 举报

1535749376
发表于: 2018-12-17 22:13:18 | 显示全部楼层

1535749376 发表于 2018-12-17 20:24
可以给我RF24.h这个库函数吗
我网上没有找到

1535749376@qq.com
谢谢了
回复

使用道具 举报

wuyanbin
发表于: 2019-3-24 21:01:13 | 显示全部楼层

感谢楼主分享,只是第一个例子成功,第二个例子却一点应都没有,接线是没问题的,不知什么原因
回复

使用道具 举报

haiyang4060
发表于: 2019-4-4 12:42:31 | 显示全部楼层

我的也是 那个都不好使 下载别的 例子 也不好使 不知道为啥   我都换了 好几个NRF2401  了
回复

使用道具 举报

lala5
发表于: 2020-3-20 21:27:01 | 显示全部楼层

第一个例子实验通过了 ,但是第二个双向通信的却不行 我用的是两个NANO,供电用的是加强供电,所以不存在供电的问题! 是代码有问题么?
回复

使用道具 举报

lala5
发表于: 2021-3-24 22:09:18 | 显示全部楼层

试验通过了  找到原因了! 代码是没有问题的!!!!
回复

使用道具 举报

z01228
发表于: 2021-4-5 11:38:24 | 显示全部楼层

lala5 发表于 2021-3-24 22:09
试验通过了  找到原因了! 代码是没有问题的!!!!

什么问题哈?
回复

使用道具 举报

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

本版积分规则

主题 705 | 回复: 1492



手机版|

GMT+8, 2024-11-15 08:09 , Processed in 0.043055 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

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

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