具有多个 NRF24L01 模块的 Arduino 无线网络
在本教程中,我们将学习如何构建由多个 NR24L01 收发器模块组成的 Arduino 无线网络。您可以观看以下视频或阅读下面的书面教程。
作为一个例子,我制作了一个由 5 个节点组成的网络,每个节点都可以与网络中的任何节点通信,同时它们可以作为发送器和接收器工作。这个例子实际上是为了解释如何建立一个更大的网络,或者更准确地说,我们可以让总共 3125 个模块在一个 RF 通道上相互通信。那么让我们来看看它是如何工作的。
在我之前的教程中,我们已经学习了如何使用 NRF24L01 模块和 RF24 库在两个 Arduino 板之间进行无线通信。现在除了这个库之外,我们将使用 RF24Network 库,它可以轻松地构建一个 Arduino 无线网络,其中许多板相互通信。以下是网络拓扑的工作原理。
单个NRF24L01模块最多可以同时主动监听6个其他模块。
RF24Network 库利用这种能力来生成以树形拓扑排列的网络,其中一个节点是基础,所有其他节点都是该节点或另一个节点的子节点。每个节点最多可以有 5 个子节点,这可以深入 5 层,这意味着我们可以创建一个总共 3125 个节点的网络。每个节点都必须定义一个 15 位的地址,它精确地描述了节点在树中的位置。
我们实际上可以用八进制格式定义节点的地址。所以,master或base的地址是00,base children的地址是01到05,01节点的children地址是011到051等等。
请注意,如果节点011要与节点02通信,则必须通过节点01和基础节点00进行通信,因此这两个节点必须始终处于活动状态才能通信成功。
在我们解释本教程的主要示例之前,为了更好地理解库的工作原理,让我们做一个两个 Arduino 板相互通信的简单示例。这是这个例子的电路图。
您可以从以下链接获取本 Arduino 教程所需的组件:
因此,使用第一个 Arduino 上的电位器,我们将控制第二个 Arduino 上的伺服电机。现在让我们看一下源代码。
这是电位器端的代码:
首先,我们需要包括库 RF24 和 RF24Network,以及 SPI 库。然后我们需要创建 RF24 对象,并将其包含到 RF24Network 对象中。这里我们需要用八进制格式定义节点的地址,或者00代表这个节点,01代表伺服侧的另一个节点。
在设置部分我们需要初始化网络,通过设置这个节点的通道和地址。
在循环部分,我们经常需要调用 update() 函数,网络中的所有动作都通过该函数发生。然后我们读取电位器的值并将其转换为适合伺服控制的 0 到 180 的值。然后我们创建一个网络头,我们在其中分配数据要去的节点的地址。最后,我们使用 write() 函数将数据发送到另一个节点。所以这里第一个参数包含地址信息,第二个参数指向要发送的数据,第三个参数是数据的大小。
伺服端的代码如下:
另一方面,在伺服电机上,我们需要以与前面解释相同的方式定义库和对象。这里这个节点的八进制地址是01。在定义了伺服电机之后,在循环部分,使用while()循环和available()函数我们不断检查是否有任何传入数据。如果为真,我们将创建一个网络标头,通过该标头接受数据,以及一个用于存储数据的变量。然后使用 read() 函数读取数据,并将其存储到incomingData 变量中。最后我们使用这些数据根据来自另一个节点的电位器移动伺服电机。
在理解了这个例子之后,我们可以继续本教程的主要例子,并建立一个由 5 个 Arduino 相互通信的无线网络。这是示例的框图。
因此,从基础开始,使用电位器控制节点 01 处的伺服电机,使用第二个电位器控制节点 022 处的 LED,使用按钮控制节点 012 处的 LED,此处的 LED 位于基座将使用节点 02 处的电位器进行控制。同样使用节点 012 处的红外传感器,我们将控制节点 01 处的 LED。因此我们可以注意到,此示例说明了如何同时发送和接收数据,以及如何与来自不同分支的节点进行通信。现在让我们看一下Arduino代码。
相关:DIY Arduino RC 发射器
因此,在基础节点或主节点上,我们需要定义库和对象,如前所述,并定义主节点将向其发送数据的所有其他节点。在循环部分,我们首先不断检查是否有任何传入数据。如果是这样,我们读取数据,将其存储到incomingData 变量中并使用它来控制LED 亮度。该数据实际上来自节点 02 的电位器。如果我们看一下它的代码,我们会发现设置几乎相同。重要的是为我们要发送数据的地方分配正确的地址。在这种情况下,就是主机 00。所以在读取电位器值并将其转换为 0 到 255 的合适 PWM 值后,我们将这个数据发送给主机。我们可以注意到这里我使用了millis()函数以10毫秒的间隔发送数据。
接下来,从主控端,我们将电位器数据发送到节点01,用于控制伺服电机。
节点01实际上是从两个不同的节点接收数据,一个用于伺服控制,另一个用于LED控制,来自节点012的红外传感器。
在这种情况下,我们使用 header.from_node 属性来获取数据来自哪个节点的信息。如果传入的数据来自master,我们用它来控制舵机,如果传入的数据来自节点012,我们用它来控制LED。
在节点 012,我们既有发送又有接收。红外传感器控制前面提到的节点 01 的 LED,这里的 LED 是通过主机上的按钮控制的。
最后,节点 022 的 LED 使用来自主机上另一个电位器的数据进行控制。
因此,总而言之,如果一切都正确连接,并且所有节点始终处于活动状态,我们的工作归结为精确寻址节点,所有繁重的工作都由令人难以置信的 RF24Network 库执行。主页>
这就是全部,我希望你喜欢这个 Arduino 项目并学到新的东西。欢迎在下方评论区提出任何问题。概览
多个NRF24L01模块通信
使用 RF24Network 库的 Arduino 无线伺服电机控制
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Example 01 - Servo Control / Node 00 - Potentiometer ==
by Dejan, www.HowToMechatronics.com
Libraries:
nRF24/RF24, https://github.com/nRF24/RF24
nRF24/RF24Network, https://github.com/nRF24/RF24Network
*/
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 00; // Address of this node in Octal format ( 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();
unsigned long potValue = analogRead(A0); // Read the potentiometer value
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
}
Code language: Arduino (arduino)/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Example 01 - Servo Control / Node 01 - Servo motor ==
*/
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
#include <Servo.h>
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc)
Servo myservo; // create servo object to control a servo
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
myservo.attach(3); // (servo pin)
}
void loop() {
network.update();
while ( network.available() ) { // Is there any incoming data?
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
}
}
Code language: Arduino (arduino)具有多个 NRF24L01 模块的 Arduino 无线网络
Base 00 源代码
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Base/ Master Node 00==
by Dejan, www.HowToMechatronics.com
Libraries:
nRF24/RF24, https://github.com/nRF24/RF24
nRF24/RF24Network, https://github.com/nRF24/RF24Network
*/
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#define button 2
#define led 3
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 00; // Address of this node in Octal format ( 04,031, etc)
const uint16_t node01 = 01; // Address of the other node in Octal format
const uint16_t node012 = 012;
const uint16_t node022 = 022;
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
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
}
Code language: Arduino (arduino)节点02源码
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 02 (Child of Master node 00) ==
*/
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 02; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
const unsigned long interval = 10; //ms // How often to send data to the other unit
unsigned long last_sent; // When did we last send?
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
}
}
Code language: Arduino (arduino)节点01源码
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 02 (Child of Master node 00) ==
*/
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <Servo.h>
#define led 2
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
Servo myservo; // create servo object to control a servo
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
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
}
}
}
Code language: Arduino (arduino)节点012源代码
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 012 (child of Node 02)==
*/
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#define led 2
#define IR 3
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 012; // Address of our node in Octal format ( 04,031, etc)
const uint16_t node01 = 01; // Address of the other node in Octal format
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
pinMode(led, OUTPUT);
pinMode(IR, INPUT);
}
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
}
Code language: Arduino (arduino)节点022源码
/*
Arduino Wireless Network - Multiple NRF24L01 Tutorial
== Node 022 (child of Node 02)==
*/
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#define led1 2
#define led2 3
#define led3 4
#define led4 5
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio); // Include the radio in the network
const uint16_t this_node = 022; // Address of our node in Octal format ( 04,031, etc)
const uint16_t master00 = 00; // Address of the other node in Octal format
void setup() {
SPI.begin();
radio.begin();
network.begin(90, this_node); //(channel, node address)
radio.setDataRate(RF24_2MBPS);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
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);
}
}
}
Code language: Arduino (arduino)
制造工艺