nRF24L01 – Wie es funktioniert, Arduino-Schnittstelle, Schaltkreise, Codes
In diesem Tutorial lernen wir, wie man drahtlos kommuniziert zwischen zwei Arduino-Boards mit dem nRF24L01 Transceiver-Module. Das nRF24L01-Modul ist eine sehr beliebte Wahl für die drahtlose Kommunikation bei der Verwendung von Arduino.
Ich habe dieses Modul bereits für zahlreiche Arduino-Projekte verwendet und Sie können sich einige davon hier ansehen:
Sie können sich das folgende Video ansehen oder das schriftliche Tutorial unten lesen. Es enthält alles, was wir über das Transceiver-Modul nRF24L01 wissen müssen, wie z. B. Modul-Pinbelegung, Funktionsprinzip, Verdrahtung und mehrere Codebeispiele.
Um die drahtlose Kommunikation zu erklären, werden wir zwei Beispiele machen, das erste wird eine einfache „Hello World“-Nachricht von einem Arduino zum anderen senden, und im zweiten Beispiel werden wir eine bidirektionale Kommunikation zwischen den Arduino-Boards haben, wo sie verwendet werden Mit dem Joystick am ersten Arduino steuern wir den Servomotor am zweiten Arduino und umgekehrt, mit dem Taster am zweiten Arduino steuern wir die LED am ersten Arduino.
Schauen wir uns das Transceiver-Modul NRF24L01 genauer an. Es verwendet das 2,4-GHz-Band und kann mit Baudraten von 250 kbps bis zu 2 Mbps arbeiten. Bei Verwendung im Freien und mit niedriger Baudrate kann die Reichweite bis zu 100 Meter betragen.
Hier sind die vollständigen Spezifikationen:
Das Modul kann 125 verschiedene Kanäle verwenden, was die Möglichkeit bietet, ein Netzwerk von 125 unabhängig arbeitenden Modems an einem Ort zu haben. Jeder Kanal kann bis zu 6 Adressen haben, oder jede Einheit kann gleichzeitig mit bis zu 6 anderen Einheiten kommunizieren.
Die Stromaufnahme dieses Moduls liegt beim Senden bei nur rund 12mA und damit sogar unter der einer einzelnen LED. Die Betriebsspannung des Moduls liegt zwischen 1,9 und 3,6 V, aber das Gute ist, dass die anderen Pins eine 5-V-Logik tolerieren, sodass wir es problemlos an einen Arduino anschließen können, ohne Logikpegelwandler zu verwenden.
Drei dieser Pins sind für die SPI-Kommunikation und müssen mit den SPI-Pins des Arduino verbunden werden, aber beachten Sie, dass jedes Arduino-Board unterschiedliche SPI-Pins hat. Die Pins CSN und CE können mit jedem digitalen Pin des Arduino-Boards verbunden werden und dienen zum Setzen des Moduls in den Standby- oder Aktivmodus sowie zum Umschalten zwischen Sende- oder Befehlsmodus. Der letzte Pin ist ein Interrupt-Pin, der nicht verwendet werden muss.
Es gibt mehrere Varianten der NRF24L01-Module. Am beliebtesten ist die mit Bordantenne. Dadurch wird das Modul kompakter, verringert aber andererseits die Übertragungsreichweite auf eine Entfernung von etwa 100 Metern.
Die zweite Variante hat statt der Bordantenne einen SMA-Anschluss und an dem wir eine Entenantenne für eine bessere Übertragungsreichweite anbringen können.
Die hier gezeigte dritte Variante hat zusätzlich zur Entenantenne einen RFX2401C-Chip, der PA enthält (Leistungsverstärker) und LNA (Rauscharmer Verstärker). Dieser verstärkt das Signal des NRF24L01 und ermöglicht eine noch bessere Übertragungsreichweite von bis zu 1000 Metern im freien Raum.
Hier ist ein detaillierter Blick auf die NRF24L01-Pinbelegung sowie das NRF24L01+ PA/LNA-Modul.
Beide Module, das NRF24L01 und das NRF24L01+ PA/LNA haben die gleiche Pinbelegung, sodass wir sie in unserer Schaltung auf die gleiche Weise anschließen können.
So müssen wir die NRF24L01-Module mit den Arduino-Boards verbinden.
Wie ich bereits erwähnt habe, hat jedes Arduino-Board unterschiedliche SPI-Pins, also denken Sie daran, wenn Sie die Module an Ihr Arduino-Board anschließen.
Die für dieses Arduino-Tutorial benötigten Komponenten erhalten Sie über die folgenden Links:
Sobald wir die NRF24L01-Module mit den Arduino-Boards verbunden haben, sind wir bereit, die Codes für Sender und Empfänger zu erstellen.
Zuerst müssen wir die RF24-Bibliothek herunterladen und installieren, was die Programmierung weniger schwierig macht. Wir können diese Bibliothek auch direkt aus dem Arduino IDE Library Manager installieren. Suchen Sie einfach nach „rf24“ und finden und installieren Sie das von „TMRh20, Avamander“.
Hier sind die beiden Codes für die drahtlose Kommunikation und unten ist ihre Beschreibung.
Wir müssen also das Basis-SPI und die neu installierten RF24-Bibliotheken einbinden und ein RF24-Objekt erstellen. Die beiden Argumente hier sind die CSN- und CE-Pins.
Als nächstes müssen wir ein Byte-Array erstellen, das die Adresse darstellt, oder die sogenannte Pipe, durch die die beiden Module kommunizieren werden.
Wir können den Wert dieser Adresse in eine beliebige 5-Buchstaben-Kette ändern und dies ermöglicht die Auswahl, mit welchem Empfänger wir sprechen, sodass wir in unserem Fall dieselbe Adresse sowohl beim Empfänger als auch beim Sender haben.
Im Einrichtungsabschnitt müssen wir das Funkobjekt initialisieren und mit der Funktion radio.openWritingPipe() die Adresse des Empfängers festlegen, an den wir Daten senden werden, die 5-Buchstaben-Zeichenfolge, die wir zuvor festgelegt haben.
Auf der anderen Seite, am Empfänger, setzen wir mit der Funktion radio.setReadingPipe() dieselbe Adresse und ermöglichen so die Kommunikation zwischen den beiden Modulen.
Dann stellen wir mit der Funktion radio.setPALevel() den Pegel des Leistungsverstärkers ein, in unserem Fall werde ich ihn auf Minimum setzen, da meine Module sehr nahe beieinander liegen.
Beachten Sie, dass bei Verwendung eines höheren Pegels empfohlen wird, einen Bypass-Kondensator zwischen GND und 3,3 V der Module zu verwenden, damit sie während des Betriebs eine stabilere Spannung haben.
Als nächstes haben wir die Funktion radio.stopListening(), die das Modul als Sender einstellt, und auf der anderen Seite haben wir die Funktion radio.startListening(), die das Modul als Empfänger einstellt.
Im Loop-Bereich am Sender erstellen wir ein Array von Zeichen, denen wir die Nachricht „Hello World“ zuweisen. Mit der Funktion radio.write() senden wir diese Nachricht an den Empfänger. Das erste Argument hier ist die Variable, die gesendet werden soll.
Indem wir das „&“ vor dem Variablennamen verwenden, setzen wir tatsächlich eine Angabe der Variablen, die die Daten speichert, die wir senden möchten, und mit dem zweiten Argument legen wir die Anzahl der Bytes fest, die wir von dieser Variablen nehmen möchten. In diesem Fall holt die Funktion sizeof() alle Bytes des Strings „text“. Am Ende des Programms fügen wir eine Verzögerung von 1 Sekunde hinzu.
Mit der Funktion radio.write() können wir maximal 32 Bytes gleichzeitig senden.
Auf der anderen Seite prüfen wir beim Empfänger im Schleifenabschnitt mit der Funktion radio.available(), ob Daten zu empfangen sind. Wenn das stimmt, erstellen wir zuerst ein Array aus 32 Elementen namens „Text“, in dem wir die eingehenden Daten speichern.
Mit der Funktion radion.read() lesen wir die Daten und speichern sie in der Variablen „text“. Am Ende drucken wir nur Text auf dem seriellen Monitor. Sobald wir also beide Programme hochgeladen haben, können wir den seriellen Monitor am Empfänger ausführen und wir werden feststellen, dass die Nachricht „Hello World“ jede Sekunde gedruckt wird.
Es ist erwähnenswert, dass Netzteilrauschen ist eines der häufigsten Probleme, auf die Menschen stoßen, wenn sie versuchen, erfolgreich mit den NRF24L01-Modulen zu kommunizieren. Im Allgemeinen sind HF-Schaltungen oder Hochfrequenzsignale empfindlich gegenüber Stromversorgungsrauschen. Daher ist es immer eine gute Idee, einen Entkopplungskondensator über die Stromversorgungsleitung zu legen. Der Kondensator kann zwischen 10 uF und 100 uF liegen.
Ein weiteres häufiges Problem ist, dass der 3,3-V-Pin der Arduino-Boards das NRF24L01-Modul nicht immer mit genügend Strom versorgen kann. Daher ist es auch eine gute Idee, das Modul mit einer externen Stromquelle zu betreiben.
Sehen wir uns das zweite Beispiel an, eine bidirektionale drahtlose Kommunikation zwischen zwei Arduino-Boards. Hier ist der Schaltplan:
Die für dieses Beispiel benötigten Komponenten erhalten Sie über die folgenden Links:
Hier sind die beiden Codes und ihre Beschreibung unten.
Sendercode
Empfängercode
Der Unterschied zum vorherigen Beispiel besteht darin, dass wir zwei Pipes oder Adressen für die bidirektionale Kommunikation erstellen müssen.
Im Setup-Abschnitt müssen wir beide Pipes definieren und beachten, dass die Schreibadresse beim ersten Arduino die Leseadresse beim zweiten Arduino sein muss und umgekehrt die Leseadresse beim ersten Arduino die Schreibadresse bei sein muss der zweite Arduino.
Im Schleifenabschnitt setzen wir mit der Funktion radio.stopListening() den ersten Arduino als Sender, lesen und mappen den Wert von Joystick von 0 bis 180 und senden die Daten mit der Funktion radio.write() an den Empfänger.
Auf der anderen Seite stellen wir mit der Funktion radio.startListening() den zweiten Arduino als Empfänger ein und prüfen, ob Daten verfügbar sind. Solange Daten verfügbar sind, lesen wir sie, speichern sie in der Variablen „angleV“ und verwenden dann diesen Wert, um den Servomotor zu drehen.
Als nächstes stellen wir am Sender den ersten Arduino als Empfänger ein und warten mit einer leeren „while“ Schleife auf den zweiten Arduino die Sendedaten, und das sind die Daten für den Zustand des Tasters ob gedrückt oder nicht. Wenn die Taste gedrückt wird, leuchtet die LED auf. Dieser Vorgang wiederholt sich also ständig und beide Arduino-Boards senden und empfangen ständig Daten.
Werfen wir einen Blick auf einen weiteren Beispielcode mit den NRF24L01-Modulen. Alles bleibt gleich wie in den vorherigen Beispielen, abgesehen von der Art und Weise, wie wir das Datum strukturieren und senden.
Sendercode
Wir können also eine Struktur erstellen, die eigentlich eine Sammlung verschiedener Arten von Variablen ist.
Wir sollten bedenken, dass die maximale Größe dieser Strukturdaten 32 Bytes betragen kann. Hier können wir sehen, dass ich drei Variablen vom Typ Byte, eine Integer-Variable (4 Bytes), eine Float-Variable (4 Bytes) und einen String mit vier Zeichen (4 Bytes) eingefügt habe. Das sind insgesamt 15 Bytes.
Empfängercode
Auf der Empfängerseite müssen wir dieselben Strukturdaten definieren, um die eingehenden Daten empfangen zu können. Um zu testen, ob die drahtlose Kommunikation richtig funktioniert, habe ich jede Variable auf dem seriellen Monitor ausgedruckt.
Das NRF24L01-Modul ist eine großartige Option, wenn Sie für Ihr Arduino-Projekt eine drahtlose Kommunikation benötigen. Ich habe dieses Modul bereits in vielen meiner Arduino-Projekte verwendet.
Hier werde ich alle meine Projekte auflisten, in denen ich diese Module verwendet habe.
Jedes dieser Projekte/Tutorials enthält eine detaillierte Erklärung zur Verwendung des NRF24L01-Moduls, einschließlich Schaltplänen, verbesserter Codeimplementierung für eine bessere Kommunikation und so weiter.
Mein Lieblingsprojekt ist dieser kundenspezifische Arduino RC Transmitter. Es ist eigentlich ein 14-Kanal-RC-Controller, mit dem so ziemlich jedes Arduino-Projekt gesteuert werden kann.
Das war alles für dieses Tutorial. Ich hoffe, es hat Ihnen gefallen und Sie haben etwas Neues gelernt. Fühlen Sie sich wie immer frei, Fragen im Kommentarbereich unten zu stellen.
Übersicht
nRF24L01-Transceiver-Modul
Frequenzbereich 2,4 – 2,5 GHz ISM-Band Datenraten 250 Kbit/s/1 Mbit/s/2 Mbit/s Max. Ausgangsleistung 0dBm Betriebsspannung 1,9 – 3,6 V Max. Betriebsstrom 12,3mA Standbystrom 22µA Logische Eingänge 5V-tolerant Kommunikationsbereich 100m (offener Raum) Wie es funktioniert
Modulvariationen
nRF24L01-Modul-Pinbelegung
So verbinden Sie den nRF24L01 mit Arduino
Arduino SCK MISO MOSI SS Uno 13 12 11 10 Nano 13 12 11 10 Mega 52 50 51 53
Arduino- und nRF24L01-Code
Sendercode
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
Codesprache:Arduino (arduino) Empfängercode
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
Codesprache:Arduino (arduino) Codebeschreibung
RF24 radio(7, 8); // CE, CSN
Codesprache:Arduino (arduino) const byte address[6] = "00001";
Codesprache:Arduino (arduino) radio.openWritingPipe(address);
Codesprache:Arduino (arduino) radio.openReadingPipe(0, address);
Codesprache:Arduino (arduino) radio.setPALevel(RF24_PA_MIN);
Codesprache:Arduino (arduino) // at the Transmitter
radio.stopListening();
Codesprache:Arduino (arduino) // at the Receiver
radio.startListening();
Codesprache:Arduino (arduino) void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
Codesprache:Arduino (arduino) void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
Codesprache:Arduino (arduino) Fehlerbehebung
Bidirektionale drahtlose Kommunikation mit zwei NRF24L01 und Arduino
nRF24L01-Quellcode
/*
* Arduino Wireless Communication Tutorial
* Example 2 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define led 12
RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
boolean buttonState = 0;
void setup() {
pinMode(12, OUTPUT);
radio.begin();
radio.openWritingPipe(addresses[1]); // 00002
radio.openReadingPipe(1, addresses[0]); // 00001
radio.setPALevel(RF24_PA_MIN);
}
void loop() {
delay(5);
radio.stopListening();
int potValue = analogRead(A0);
int angleValue = map(potValue, 0, 1023, 0, 180);
radio.write(&angleValue, sizeof(angleValue));
delay(5);
radio.startListening();
while (!radio.available());
radio.read(&buttonState, sizeof(buttonState));
if (buttonState == HIGH) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}
Codesprache:Arduino (arduino) /*
* Arduino Wireless Communication Tutorial
* Example 2 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
#define button 4
RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
Servo myServo;
boolean buttonState = 0;
void setup() {
pinMode(button, INPUT);
myServo.attach(5);
radio.begin();
radio.openWritingPipe(addresses[0]); // 00001
radio.openReadingPipe(1, addresses[1]); // 00002
radio.setPALevel(RF24_PA_MIN);
}
void loop() {
delay(5);
radio.startListening();
if ( radio.available()) {
while (radio.available()) {
int angleV = 0;
radio.read(&angleV, sizeof(angleV));
myServo.write(angleV);
}
delay(5);
radio.stopListening();
buttonState = digitalRead(button);
radio.write(&buttonState, sizeof(buttonState));
}
}
Codesprache:Arduino (arduino) const byte addresses[][6] = {"00001", "00002"};
Codesprache:Arduino (arduino) // at the Transmitter
radio.openWritingPipe(addresses[1]); // 00001
radio.openReadingPipe(1, addresses[0]); // 00002
Codesprache:Arduino (arduino) // at the Receiver
radio.openWritingPipe(addresses[0]); // 00002
radio.openReadingPipe(1, addresses[1]); // 00001
Codesprache:Arduino (arduino) radio.stopListening();
int potValue = analogRead(A0);
int angleValue = map(potValue, 0, 1023, 0, 180);
radio.write(&angleValue, sizeof(angleValue));
Codesprache:Arduino (arduino) radio.startListening();
if ( radio.available()) {
while (radio.available()) {
int angleV = 0;
radio.read(&angleV, sizeof(angleV));
myServo.write(angleV);
}
Codesprache:Arduino (arduino) Beispiel 3 – Senden mehrerer Variablen in einem einzigen Paket
/*
Arduino Wireless Communication Tutorial
Example 1 - Transmitter Code
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; // Create a variable with the above structure
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
// Send the whole data from the structure to the receiver
radio.write(&data, sizeof(Data_Package));
delay(500);
}
Codesprache:Arduino (arduino) // Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; // Create a variable with the above structure
Codesprache:Arduino (arduino) /*
Arduino Wireless Communication Tutorial
Example 1 - Receiver Code
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; //Create a variable with the above structure
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
}
Serial.print("a: ");
Serial.print(data.a);
Serial.print(" b: ");
Serial.print(data.b);
Serial.print(" c: ");
Serial.print(data.c);
Serial.print(" d: ");
Serial.print(data.d);
Serial.print(" e: ");
Serial.print(data.e);
Serial.print(" f: ");
Serial.println(data.f);
}
Codesprache:Arduino (arduino) Fazit
Herstellungsprozess
- Messen der Luftqualität auf OpenSensors
- Wie man IR-Fernbedienungen hackt
- Wie groß bist du?
- JX-Wellengenerator
- DIY Virtual Reality Skateboard
- Wie man Arduino Mega mit dem NEO-6M GPS-Modul verbindet
- Wie einfach ist es, einen Thermistor zu verwenden?!
- Wie man mit einem Arduino Musik macht
- So verwenden Sie Modbus mit Arduino
- Hier ist eine Idee:Wie eine Gehirn-Computer-Schnittstelle funktioniert