Arduino无线网络具有多个NRF24L01模块

在本教程中,我们将学习如何构建由多个NR24L01收发器模块组成的Arduino无线网络。您可以观看以下视频或阅读下面的书面教程。

概述

例如,我做了一个由5个节点组成的网络,每个节点都可以与网络中的任何节点通信,同时它们也可以作为发射器和接收器。这个例子实际上解释了如何建立一个更大的网络,或者更准确地说,我们可以在一个射频信道上总共有3125个模块相互通信。让我们来看看它是如何工作的。betway

在我以前的教程中,我们已经学过了如何进行无线通信使用NRF24L01模块和RF24库之间的两个Arduino板之间。现在除了这个图书馆,我们将使用RF24Network库,以一种简单的方式启用,可以使用许多电路板构建Arduino无线网络。这是网络拓扑的作品。

一个NRF24L01模块可以同时主动侦听多达6个其他模块。

NRF24L01可以同时收听最多6个其他模块

RF24Network库利用这种能力来生成排列在树状拓扑结构中的网络,其中一个节点是基础节点,而所有其他节点都是该节点或另一个节点的子节点。每个节点最多可以有5个子节点,这可以深入5层,这意味着我们可以创建一个总共3125个节点的网络。每个节点都必须定义一个15位地址,它精确地描述了节点在树中的位置。

树拓扑无线Netowrk

我们实际上可以以八进制格式定义节点的地址。因此,主站或基础的地址是00,基本儿童地址为01至05,01节点儿童地址为011至051等等。

注意,如果节点011想要与节点02通信,则通信必须经过节点01和基本节点00,因此这两个节点必须一直处于活动状态,才能成功通信。

Arduino无线伺服电机控制使用rf24网络库

在我们解释本教程的主要示例之前,为了更好地理解库的工作原理,让我们做一个简单的示例,两个Arduino板相互通信。这是这个例子的电路图。

Arduino无线伺服电机控制电路图.png

您可以从下面的链接获取此Arduino教程所需的组件:

必威外围提钱披露:这些是联盟链接。作为亚马逊助理,我从合格购买中获得。

因此,在第一个Arduino使用电位器,我们将控制第二个Arduino的伺服电机。我们现在看看源代码。

这里是电位器端的代码:

/ * Arduino无线网络——多个NRF24L01教程= =例子00 - 01 -伺服控制/节点电位计,德扬= = www.HowToMechatronics.com库:nRF24 / RF24, https://github.com/nRF24/RF24bet188官方网站 nRF24 / RF24Network, https://github.com/nRF24/RF24Network * / # include < RF24.h > # include < RF24Network.h > # include < SPI.h > RF24电台(10 9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含广播const uint16_t this_node = 00;//该节点的八进制地址(04,031,etc) const uint16_t node01 = 01;void setup() {SPI.begin();radio.begin ();network.begin(90,this_node);//(channel, node address)} void loop() {network.update();无符号长potValue = analogRead(A0);//读取电位器的值unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Convert the value to 0-180 RF24NetworkHeader header(node01); // (Address where the data is going) bool ok = network.write(header, &angleValue, sizeof(angleValue)); // Send the data }

首先,我们需要包括RF24和RF24Network两个库,以及SPI库。然后,我们需要创建RF24对象,并将其包含到RF24Network对象中。这里我们需要用八进制格式定义节点的地址,这个节点为00,伺服端另一个节点为01。

在设置部分中,我们需要通过设置通道和这个节点的地址来初始化网络。

在循环部分,我们需要不断地调用update()函数,网络中的所有动作都是通过这个函数发生的。然后读取电位器的值,将其转换为适合于伺服控制的0 ~ 180的值。然后我们创建一个网络报头,在那里我们分配数据要去的节点的地址。最后,使用write()函数将数据发送到另一个节点。所以这里第一个参数包含地址信息,第二个参数指出要发送哪些数据,第三个参数是数据的大小。

这是伺服端的代码:

/ * Arduino无线网络 - 多个nrf24l01教程==示例01  - 伺服控制/节点01  - 伺服电机== * / #include  #include  #include  #include <伺服。> RF24收音机(10,9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含无线电uint16_t this_node = 01;//以八进制格式(04,031,等)伺服myservo的节点的地址;//创建伺服对象以控制伺服void setup(){spi.begin();radio.begin ();network.begin(90,this_node);//(通道,节点地址)myservo.attach(3);//(伺服引脚)} void循环(){network.update();while(network.available()){//有任何传入数据? RF24NetworkHeader header; unsigned long incomingData; network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data myservo.write(incomingData); // tell servo to go to a particular angle } }

另一方面,在伺服电机上,我们需要以前面解释的相同方式定义库和对象。这里,这个节点的八进制地址是01。定义伺服电机后,在回路部分,使用while()回路和available()函数不断检查是否有任何传入数据。如果为真,我们将创建一个网络报头,通过它接收数据,并创建一个变量存储数据。然后使用read()函数读取数据,并将其存储到incomingData变量中。最后,我们利用这些数据来根据电位器从另一个节点移动伺服电机。

Arduino无线网络具有多个NRF24L01模块

在理解此示例后,我们可以使用本教程的主要示例,并构建一个彼此通信的5个Arduinos的无线网络。这是该示例的框图。

Arduino-Wireless-Network-with-Multiple-NRF24L01-Modules

因此,使用电位器,使用电位器,我们将在节点01上控制伺服电机,用第二电位计我们将在节点022上控制LED,使用该按钮,我们将在节点012上控制LED,并在此处控制LED基座将在节点02处使用电位器控制。还使用节点012处的红外传感器,我们将在节点01上控制LED。因此,我们可以注意到该示例说明如何同时发送和接收数据,以及如何与来自不同分支的节点通信。让我们来看看Arduino代码。

有关的:DIY Arduino RC发射机

基数00源代码

/ * Arduino无线网络 - 多个NRF24L01教程== Base / Master节点00 == by Dejan,www.www.mfxpo.com库:nrf24 /bet188官方网站 rf24,https://github.com/nrf24/rf24 nrf24 / rf24network,https://github.com/nrf24/rf24network * / #include  #include  #include  #define按钮2 #define LED 3 RF24收音机(10,9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含广播const uint16_t this_node = 00;//该节点的八进制地址(04,031,etc) const uint16_t node01 = 01;//以八进制格式的其他节点的地址const16_t node012 = 012;const uint16_t node022 = 022;void setup() {SPI.begin();radio.begin ();network.begin(90,this_node);//(信道,节点地址)radio.setDataRate(RF24_2MBPS); pinMode(button, INPUT_PULLUP); pinMode(led, OUTPUT); } void loop() { network.update(); //===== Receiving =====// while ( network.available() ) { // Is there any incoming data? RF24NetworkHeader header; unsigned long incomingData; network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data analogWrite(led, incomingData); // PWM output to LED 01 (dimming) } //===== Sending =====// // Servo control at Node 01 unsigned long potValue = analogRead(A0); unsigned long angleValue = map(potValue, 0, 1023, 0, 180); // Suitable for servo control RF24NetworkHeader header2(node01); // (Address where the data is going) bool ok = network.write(header2, &angleValue, sizeof(angleValue)); // Send the data // LED Control at Node 012 unsigned long buttonState = digitalRead(button); RF24NetworkHeader header4(node012); // (Address where the data is going) bool ok3 = network.write(header4, &buttonState, sizeof(buttonState)); // Send the data // LEDs control at Node 022 unsigned long pot2Value = analogRead(A1); RF24NetworkHeader header3(node022); // (Address where the data is going) bool ok2 = network.write(header3, &pot2Value, sizeof(pot2Value)); // Send the data }

所以在基础上或主节点中,我们需要定义早期介绍的库和对象,并且还定义了主设备将发送数据的所有其他节点。在循环部分中,我们通过不断检查是否有任何传入数据而开始。如果是这样,我们读取数据,将其存储到IncomingData变量中并使用它来控制LED亮度。此数据实际上来自节点02的电位器。如果我们看看其代码,我们会注意到设置相同。重要的是要将正确的地址分配给我们要发送数据的位置。在这种情况下,这是主00.因此在读取电位器值并将其转换为0到255的合适的PWM值之后,我们将此数据发送到主设备。我们可以在这里注意到我使用Millis()函数以10毫秒的间隔发送数据。

节点02源代码

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial == Node 02 (Master Node 00的子节点)== */ #include  #include  #include  RF24 radio(10,9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含广播const uint16_t this_node = 02;//我们的节点地址的八进制格式(04,031,etc) const uint16_t master00 = 00;//另一个节点的八进制地址const unsigned long interval = 10;//ms //发送数据到另一个单元的频率//我们上次发送是什么时候?void setup() {SPI.begin();radio.begin ();network.begin(90,this_node); //(channel, node address) radio.setDataRate(RF24_2MBPS); } void loop() { network.update(); //===== Sending =====// unsigned long now = millis(); if (now - last_sent >= interval) { // If it's time to send a data, send it! last_sent = now; unsigned long potValue = analogRead(A0); unsigned long ledBrightness = map(potValue, 0, 1023, 0, 255); RF24NetworkHeader header(master00); // (Address where the data is going) bool ok = network.write(header, &ledBrightness, sizeof(ledBrightness)); // Send the data } }

接下来,从主设备,我们将电位器数据发送到节点01以控制伺服电机。

节点01源代码

/ * arduino无线网络 - 多个nrf24l01教程==节点02(主节点00的子节点)== * / #include  #include  #include  #include  #define LED 2 RF24收音机(10,9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含无线电uint16_t this_node = 01;//我们的节点地址的八进制格式(04,031,etc) const uint16_t master00 = 00;//八进制格式的其他节点的地址伺服myservo;//创建伺服对象以控制伺服void setup(){spi.begin();radio.begin ();network.begin(90,this_node);//(信道,节点地址)radio.setDataRate(RF24_2MBPS);myservo.attach(3); // (servo pin) pinMode(led, OUTPUT); } void loop() { network.update(); //===== Receiving =====// while ( network.available() ) { // Is there any incoming data? RF24NetworkHeader header; unsigned long incomingData; network.read(header, &incomingData, sizeof(incomingData)); // Read the incoming data if (header.from_node == 0) { // If data comes from Node 02 myservo.write(incomingData); // tell servo to go to a particular angle } if (header.from_node == 10) { // If data comes from Node 012 digitalWrite(led, !incomingData); // Turn on or off the LED 02 } } }

节点01实际上是从两个不同节点接收数据,一个用于伺服控制,另一个用于来自来自节点012的红外传感器的LED控制。

节点012源代码

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial ==节点012(节点02的子节点)== */ #include  #include  #include  #define led 2 #define IR 3 RF24 radio(10, 9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含广播const uint16_t this_node = 012;//我们的节点地址的八进制格式(04,031,etc) const uint16_t node01 = 01;//另一个节点的八进制地址void setup() {SPI.begin();radio.begin ();network.begin(90,this_node);//(信道,节点地址)radio.setDataRate(RF24_2MBPS);pinMode(领导、输出);pinMode(红外、输入); } void loop() { network.update(); //===== Receiving =====// while ( network.available() ) { // Is there any incoming data? RF24NetworkHeader header; unsigned long buttonState; network.read(header, &buttonState, sizeof(buttonState)); // Read the incoming data digitalWrite(led, !buttonState); // Turn on or off the LED } //===== Sending =====// unsigned long irV = digitalRead(IR); // Read IR sensor RF24NetworkHeader header8(node01); bool ok = network.write(header8, &irV, sizeof(irV)); // Send the data }

在这种情况下,我们使用标题.From_node属性以获取数据来自哪个节点的信息。如果传入数据来自主设备,我们将使用它来控制伺服,并且在传入数据来自节点012的情况下,我们使用它来控制LED。

在节点012,我们有发射和接收。红外传感器控制前面提到的节点01的LED,这里的LED是从主控机的按钮控制的。

节点022源代码

/* Arduino Wireless Network - Multiple NRF24L01 Tutorial ==节点022(节点02的子节点)== */ #include  #include  #include  #define led1 2 #define led2 3 #define led3 4 #define led4 5 RF24 radio(10, 9);// nRF24L01 (CE,CSN) RF24Network网络(无线);//在网络中包含广播const uint16_t this_node = 022;//我们的节点地址的八进制格式(04,031,etc) const uint16_t master00 = 00;//另一个节点的八进制地址void setup() {SPI.begin();radio.begin ();network.begin(90,this_node);//(信道,节点地址)radio.setDataRate(RF24_2MBPS);pinMode (led1、输出);pinMode (led2、输出); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); } void loop() { network.update(); //===== Receiving =====// while ( network.available() ) { // Is there any incoming data? RF24NetworkHeader header; unsigned long potValue; network.read(header, &potValue, sizeof(potValue)); // Read the incoming data // Turn on the LEDs as depending on the incoming value from the potentiometer if (potValue > 240) { digitalWrite(led1, HIGH); } else { digitalWrite(led1, LOW); } if (potValue > 480) { digitalWrite(led2, HIGH); } else { digitalWrite(led2, LOW); } if (potValue > 720) { digitalWrite(led3, HIGH); } else { digitalWrite(led3, LOW); } if (potValue > 960) { digitalWrite(led4, HIGH); } else { digitalWrite(led4, LOW); } } }

最后,使用来自主机处的其他电位计的数据来控制节点022处的LED。

因此,总而言之,如果一切都连接正确,所有节点都一直处于活动状态,那么我们的工作可以归结为精确地处理节点,所有繁重的工作都由令人难以置信的RF24Network库来完成。

所以这就是全部,我希望你喜欢这个Arduino项目并学会了新的东西。随意询问以下意见部分中的任何问题。

24回复

  1. Sasa Banovic.

    你好,

    这是一个有趣的项目。我有个问题,为什么你选择使用nRF24网络,而不是ESP模块和无线网络?

    我正在计划类似的系统,主要是为了控制(小有效载荷),我选择了MQTT作为主要协议,因为WiFi网络中有带宽可用,但大多数传感器可以通过发送几个整数和其他传感器来完成他们的工作可以使用蓝牙进行额外的流(音频),因此我不需要WiFi,除了在用户界面节点上,该节点除了具有Web服务器控件和配置访问(可能是Raspberry PI,以及它是以太网连接的情况下)。关于NRF的担忧是,除了作为确认的一部分的配对序列之外,没有这么多的升高的安全选项,并且希望没有人可以猜出有效载荷的内容和结构。

    回复
    • 德扬

      谢谢!这只是一个教程,解释如何使用nRF24网络,以防有人想使用它。我没有和其他方法做过任何详细的比较,所以我不能告诉你太多。

      回复
    • 安东尼球

      我认为使用NRF最常见的原因是,它使用的功率大约是esp8266的十分之一,这在电池或太阳能设置中是很重要的,只要你使用低功率的微控制器。

      回复
      • 斯宾塞

        大家好,我想我必须同意,相比之下,8266的能耗真的很大。
        谢谢- Dejan,我真的很感谢你的努力。
        请继续! !

  2. Alex Pasz.

    嗨如何发布机制,首先,令人敬畏!
    你能在7:40之前解释原因我们必须写出标题。从节点12接收信息吗?(我实际上有5个在船长中获得5个信息,但无法理解您使用的数字背后的逻辑)。
    非常感谢你的视频,这太棒了!

    回复
    • 德扬

      嘿,谢谢!说实话,我不确定为什么。我的意思是我看看代码,这是真的,应该是12因为我们收到来自该节点的数据。它可能是一个错字。

      回复
    • 卡洛斯·阿尔贝托·法拉利·梅鲁西

      因为八进制的12是十进制的10

      回复
  3. 一个

    if(header.from_node == 0){//如果数据来自Node 02

    应该是节点00

    if (header.from_node == 10){//如果数据来自节点012 . if (header.from_node == 10)

    12月12日= 12月10日

    回复
  4. Mettdrescher.

    你好,

    做得很好!我有一个问题,我需要做什么,为了同时向多个接收器发送相同的信号?

    回复
    • 德扬

      嘿,谢谢!您可以在基础00示例代码中看到这样的案例。您只需使用要发送数据的特定地址创建不同的标题,并且只需使用写入函数向所有标题发送相同的数据。

      回复
  5. 西蒙

    嗨,我试图为我的项目实施这个代码。
    我正在为风能和太阳能做一个无线电能表。使用两个发射器和一个接收器。我还不完全懂代码。
    但是你用来发送的代码,可以用来发送2个传感器的数据吗?
    一个传感器表示安培一个传感器表示伏特?(在同一发射机上)

    回复
    • 德扬

      嘿,是的,您可以将数据从两个传感器发送到接收器。您只需使用写入功能两次,或者在这种情况下制作具有多个变量的数据包,两个传感器的值。检查我的DIY Arduino基RC发射器,以便在单个数据包中发送多个变量的这样的示例。

      回复
  6. 卡洛斯·阿尔贝托·法拉利·梅鲁西

    这是一个非常酷的项目。我实现了它来读取40个节点,它很棒。谢谢

    回复
    • Truong Ngoc Cuong

      你好,卡洛斯,

      据我所知,NRF24只能同时连接6个节点。能否分享一下你的经验,关于如何实现40个节点?

      回复
  7. James Duffy.

    嗨Dejan,
    首先感谢您的网站,我学到了这么多!我正在计划一个项目,我可以用一个控制器控制两个RC车辆(与DIY Arduino RC发射器项目相同)。有没有办法通过使用物理开关在它们之间进行选择,单独与每个接收器交谈?例如,当交换机是一种方式时,它与车辆A交谈时,当它交换到车辆B时,它仍然是一个新的新手,所以任何帮助都会非常感激

    回复
    • 德扬

      嘿,詹姆斯,谢谢!你可以这样做。使用本教程中解释的方法,我们可以选择要交谈的节点,我们只需要设置适当的地址。你可以用一个简单的开关来改变地址。例如,交换机主用或高用时,设置地址01;交换机非主用或低用时,设置地址02。

      回复
  8. Darrel

    非常好的工作。由于我的残疾,我最近被迫退休,这些教程很棒。我手上有很多时间,我很欣赏你是如何把事情放在外面,易于遵循和精确。
    就我个人而言,我很感激你。
    Darrel

    回复
  9. 约翰L

    德州,
    谢谢你的教程。大量的信息和恰到好处的数量让你思考正在发生的事情。你的多个例子对我来说非常有效。然后我稍微修改了一下,很高兴看到子节点不充当从主节点到孙子节点的传递节点,而是重新传输,允许您有效地扩展nRF24L01的范围。这将是特别有用的,因为我一直在寻找一种方式,以传输数据从我们的树林的一个角落到另一个大约1公里的距离。此外,通过网络进行双向通信比旧的“openReadingPipe, stopListening”等方法简单得多。有趣的是,我发现我不能让一个I2C OLED (Adafruit库)在接收节点上工作,但一个I2C LED可以工作。然而,同样的OLED在标准的nRF24L01应用程序中工作得很好。

    回复
  10. •Romene

    你好,
    这是一个非常酷的项目。良好的工作。谢谢你所有的指导。
    我现在也在尝试做同样的项目,但是用不同的传感器。传感器将被安装在机器上,我想在我的计算机上创建一个GUI,我可以监控机器,而它的工作和可视化的所有参数,我测量。
    所以我的问题是,如果我可以在相当快的时间内同时阅读和传输所有数据,以便我可以整个工作时间监控机器。
    谢谢。

    回复
    • 德扬

      嘿,谢谢。好吧,我认为你应该能够做到这一点,尽管我不太确定你需要的速度以及你需要的速度。干杯!

      回复
  11. 佩德罗·伯斯

    佩德罗·伯克斯,

    不错的工作,学习了很多,希望你继续前进,爱你的网站。

    回复

留下一个回复

您的电子邮件地址不会被公开。

推荐

2019年最佳入门级示波器初学者和爱好者

为初学者和爱好者最好的示波器

推荐

2019年最佳Arduino入门套件

初学者的8个最佳Arduino Starter Kits

推荐

最佳3D打印机为初学者和爱好者- 3D打印

最好的3d打印机为初学者和爱好者