Den nRF24L01 meistern: Drahtlose Kommunikation, Arduino-Integration, Schaltpläne & Code-Anleitung
In diesem Tutorial lernen wir, wie man drahtlose Kommunikation zwischen zwei Arduino-Boards mit den nRF24L01 Transceiver-Modulen herstellt. Das nRF24L01-Modul ist eine sehr beliebte Wahl für drahtlose Kommunikation bei Arduino-Projekten. Ich habe dieses Modul bereits für zahlreiche Arduino-Projekte verwendet und Sie können sich einige davon hier ansehen: Sie können das folgende Video ansehen oder das schriftliche Tutorial unten lesen. Es enthält alles, was wir über den nRF24L01 Transceiver-Modul wissen müssen, wie Modul-Pinout, Funktionsweise, Verdrahtung und mehrere Code-Beispiele. Zur Erklärung der drahtlosen Kommunikation werden wir zwei Beispiele machen: Das erste sendet eine einfache „Hello World“-Nachricht von einem Arduino zum anderen. Im zweiten Beispiel haben wir eine bidirektionale Kommunikation zwischen den Arduino-Boards, bei der wir mit dem Joystick am ersten Arduino den Servomotor am zweiten Arduino steuern und umgekehrt – mit dem Taster am zweiten Arduino die LED am ersten Arduino steuern. Sehen wir uns den NRF24L01 Transceiver-Modul genauer an. Er nutzt das 2,4-GHz-Band und kann mit Baudraten von 250 kbps bis 2 Mbps betrieben werden. Im Freifeld und mit niedrigerer Baudrate kann seine Reichweite bis zu 100 Meter erreichen. Hier sind die vollständigen Spezifikationen: Das Modul kann 125 verschiedene Kanäle nutzen, 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 mit bis zu 6 anderen Einheiten gleichzeitig kommunizieren. Der Stromverbrauch dieses Moduls beträgt nur ca. 12 mA während der Übertragung, was sogar niedriger ist als eine einzelne LED. Die Betriebsspannung des Moduls liegt zwischen 1,9 und 3,6 V, aber das Gute ist, dass die anderen Pins 5-V-Logik tolerieren, sodass wir es einfach an einen Arduino anschließen können, ohne Logik-Level-Konverter zu benötigen. Drei dieser Pins sind für die SPI-Kommunikation und müssen mit den SPI-Pins des Arduino verbunden werden. 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 werden verwendet, um das Modul in Standby- oder Aktivmodus zu versetzen sowie zwischen Sende- oder Befehlsmodus zu wechseln. Der letzte Pin ist ein Interrupt-Pin, der nicht verwendet werden muss. Es gibt mehrere Varianten der NRF24L01-Module. Die beliebteste ist die mit Onboard-Antenne. Das macht das Modul kompakter, verringert aber andererseits die Übertragungsreichweite auf etwa 100 Meter. Die zweite Variante hat statt Onboard-Antenne einen SMA-Anschluss, an den wir eine Duck-Antenne für bessere Übertragungsreichweite anschließen können. Die dritte hier gezeigte Variante hat zusätzlich zur Duck-Antenne einen RFX2401C-Chip, der PA (Power Amplifier) und LNA (Low-Noise Amplifier) enthält. Dies verstärkt das NRF24L01-Signal und ermöglicht eine noch bessere Übertragungsreichweite von bis zu 1000 Metern im Freifeld. Hier ein detaillierter Blick auf den NRF24L01-Pinout sowie den NRF24L01+ PA/LNA-Modul. Beide Module, der NRF24L01 und der NRF24L01+ PA/LNA, haben den gleichen Pinout, sodass wir sie in unserem Schaltkreis gleich anschließen können. So müssen wir die NRF24L01-Module mit den Arduino-Boards verbinden. Wie bereits erwähnt, hat jedes Arduino-Board unterschiedliche SPI-Pins, behalten Sie das beim Verbinden der Module mit Ihrem Arduino-Board im Hinterkopf. Sie können die für dieses Arduino-Tutorial benötigten Komponenten über die Links unten beziehen: 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, die die Programmierung erleichtert. Wir können diese Bibliothek auch direkt über den Arduino IDE Library Manager installieren. Suchen Sie einfach nach „rf24“ und finden und installieren Sie die von „TMRh20, Avamander“. Hier sind die beiden Codes für die drahtlose Kommunikation und darunter deren Beschreibung. Wir müssen die grundlegende SPI-Bibliothek und die neu installierte RF24-Bibliothek 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, also die sogenannte Pipe, über die die beiden Module kommunizieren. Wir können den Wert dieser Adresse auf beliebige 5-Buchstaben-Strings ändern, was es ermöglicht, zu wählen, mit welchem Empfänger wir sprechen. In unserem Fall werden wir dieselbe Adresse sowohl beim Empfänger als auch beim Sender haben. Im Setup-Bereich müssen wir das Radio-Objekt initialisieren und mit der radio.openWritingPipe()-Funktion die Adresse des Empfängers festlegen, an den wir Daten senden werden – den 5-Buchstaben-String, den wir zuvor festgelegt haben. Auf der anderen Seite, beim Empfänger, nutzen wir die radio.openReadingPipe()-Funktion, um dieselbe Adresse festzulegen und so die Kommunikation zwischen den beiden Modulen zu ermöglichen. Dann nutzen wir die radio.setPALevel()-Funktion, um den Power-Amplifier-Level einzustellen – in unserem Fall setze ich ihn auf Minimum, da meine Module sehr nah beieinander sind. Beachten Sie, dass bei Verwendung eines höheren Levels empfohlen wird, einen Bypass-Kondensator über GND und 3,3 V der Module zu schalten, damit sie eine stabilere Spannung während des Betriebs haben. Als Nächstes haben wir die radio.stopListening()-Funktion, die das Modul als Sender einstellt, und auf der anderen Seite die radio.startListening()-Funktion, die das Modul als Empfänger einstellt. Im Loop-Bereich erstellen wir beim Sender ein Zeichen-Array, dem wir die Nachricht „Hello World“ zuweisen. Mit der radio.write()-Funktion senden wir diese Nachricht an den Empfänger. Das erste Argument ist die Variable, die gesendet werden soll. Durch das „&“ vor dem Variablennamen setzen wir eigentlich einen Verweis auf die Variable, die die zu sendenden Daten speichert, und mit dem zweiten Argument legen wir die Anzahl der Bytes fest, die wir von dieser Variable nehmen wollen. In diesem Fall holt die sizeof()-Funktion alle Bytes des Strings „text“. Am Ende des Programms fügen wir 1 Sekunde Verzögerung hinzu. Mit der radio.write()-Funktion können wir maximal 32 Bytes auf einmal senden. Auf der anderen Seite, beim Empfänger, prüfen wir im Loop-Bereich mit der radio.available()-Funktion, ob Daten empfangen werden können. Wenn das der Fall ist, erstellen wir zuerst ein Array mit 32 Elementen, genannt „text“, in dem wir die eingehenden Daten speichern. Mit der radio.read()-Funktion lesen und speichern wir die Daten in die „text“-Variable. Am Ende geben wir den Text nur auf dem Serial Monitor aus. Sobald wir beide Programme hochladen, können wir den Serial Monitor beim Empfänger starten und bemerken, dass die Nachricht „Hello World“ jede Sekunde ausgegeben wird. Es ist erwähnenswert, dass Netzteil-Rauschen (power supply noise) eines der häufigsten Probleme ist, die Menschen beim Versuch erfolgreicher Kommunikation mit den NRF24L01-Modulen erleben. Generell sind HF-Schaltungen oder Funkfrequenzsignale empfindlich gegenüber Netzteil-Rauschen. Daher ist es immer eine gute Idee, einen Entkopplungskondensator über die Stromversorgungsleitung zu schalten. Der Kondensator kann von 10 µF bis 100 µF sein. Ein weiteres häufiges Problem ist, dass der 3,3-V-Pin der Arduino-Boards nicht immer genug Strom liefern kann, um das NRF24L01-Modul zu versorgen. Daher ist es auch eine gute Idee, das Modul mit einer externen Stromquelle zu versorgen. Sehen wir uns das zweite Beispiel an: eine bidirektionale drahtlose Kommunikation zwischen zwei Arduino-Boards. Hier ist der Schaltplan: Sie können die für dieses Beispiel benötigten Komponenten über die Links unten beziehen: Hier sind die beiden Codes und ihre Beschreibung darunter. Sender-Code (Transmitter Code) Empfänger-Code (Receiver Code) Was hier anders ist als im vorherigen Beispiel: Wir müssen zwei Pipes oder Adressen für die bidirektionale Kommunikation erstellen. Im Setup-Bereich müssen wir beide Pipes definieren. Beachten Sie, dass die Sende-Adresse beim ersten Arduino die Empfangs-Adresse beim zweiten Arduino sein muss, und umgekehrt – die Empfangs-Adresse beim ersten Arduino muss die Sende-Adresse beim zweiten Arduino sein. Im Loop-Bereich nutzen wir die radio.stopListening()-Funktion, um den ersten Arduino als Sender einzustellen, lesen und mappen den Joystick-Wert von 0 auf 180 und senden die Daten mit der radio.write()-Funktion an den Empfänger. Auf der anderen Seite nutzen wir die radio.startListening()-Funktion, um den zweiten Arduino als Empfänger einzustellen, und prüfen, ob Daten verfügbar sind. Solange Daten verfügbar sind, lesen wir sie, speichern sie in der „angleV“-Variable und nutzen 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, bis der zweite Arduino Daten sendet – und das sind die Daten zum Zustand des Tasters, ob gedrückt oder nicht. Wenn der Taster gedrückt ist, leuchtet die LED. Dieser Prozess wiederholt sich ständig, und beide Arduino-Boards senden und empfangen kontinuierlich Daten. Sehen wir uns ein weiteres Code-Beispiel mit den NRF24L01-Modulen an. Alles bleibt gleich wie in den vorherigen Beispielen, außer der Art, wie wir die Daten strukturieren und senden. Sender-Code (Transmitter Code) So können wir ein Struct erstellen, das eigentlich eine Sammlung verschiedener Variablentypen ist. Wir sollten beachten, dass die maximale Größe dieses Struct-Datens 32 Bytes betragen kann. Hier sehen wir, dass ich drei Byte-Variablen, 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änger-Code (Receiver Code) Auf der Empfängerseite müssen wir dasselbe Struct definieren, um die eingehenden Daten empfangen zu können. Zum Testen, ob die drahtlose Kommunikation ordnungsgemäß funktioniert, habe ich jede Variable auf dem Serial Monitor ausgegeben. Das NRF24L01-Modul ist eine großartige Option, wenn Sie drahtlose Kommunikation für Ihr Arduino-Projekt benötigen. Ich habe dieses Modul bereits in vielen meiner Arduino-Projekte verwendet. Hier liste ich all meine Projekte auf, in denen ich diese Module verwendet habe. Jedes dieser Projekte/Tutorials hat eine detaillierte Erklärung, wie man das NRF24L01-Modul verwendet, einschließlich Schaltplänen, verbesserter Code-Implementierung für bessere Kommunikation usw. Mein Lieblingsprojekt ist dieser individuell designte Arduino RC Transmitter. Es ist eigentlich ein 14-Kanal-RC-Controller, der für die Steuerung praktisch jedes Arduino-Projekts verwendet werden kann. Das war alles für dieses Tutorial. Ich hoffe, es hat Ihnen gefallen und Sie haben etwas Neues gelernt. Wie immer: Fühlen Sie sich frei, Fragen im Kommentarbereich unten zu stellen.
Überblick

nRF24L01 Transceiver-Modul

Frequenzbereich 2,4 – 2,5 GHz ISM-Band Datenraten 250 Kbps / 1 Mbps / 2 Mbps Max. Ausgangsleistung 0 dBm Betriebsspannung 1,9 – 3,6 V Max. Betriebsstrom 12,3 mA Standby-Strom 22 µA Logik-Eingänge 5 V tolerant Kommunikationsreichweite 100 m (Freifeld) Funktionsweise


Modulvarianten

nRF24L01 Modul-Pinout

Wie man den nRF24L01 mit Arduino verbindet

Arduino SCK MISO MOSI SS Uno 13 12 11 10 Nano 13 12 11 10 Mega 52 50 51 53
Arduino und nRF24L01 Code
Sender-Code (Transmitter Code)
/* * 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); }Empfänger-Code (Receiver Code)
/* * 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); } }Code-Beschreibung
RF24 radio(7, 8); // CE, CSNconst byte address[6] = "00001";radio.openWritingPipe(address);radio.openReadingPipe(0, address);radio.setPALevel(RF24_PA_MIN);// am Sender radio.stopListening();// am Empfänger radio.startListening();void loop() { const char text[] = "Hello World"; radio.write(&text, sizeof(text)); delay(1000); }void loop() { if (radio.available()) { char text[32] = ""; radio.read(&text, sizeof(text)); Serial.println(text); } }Fehlerbehebung (Troubleshooting)

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); } }/* * 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)); } }const byte addresses[][6] = {"00001", "00002"};// am Sender radio.openWritingPipe(addresses[1]); // 00001 radio.openReadingPipe(1, addresses[0]); // 00002// am Empfänger radio.openWritingPipe(addresses[0]); // 00002 radio.openReadingPipe(1, addresses[1]); // 00001radio.stopListening(); int potValue = analogRead(A0); int angleValue = map(potValue, 0, 1023, 0, 180); radio.write(&angleValue, sizeof(angleValue));radio.startListening(); if ( radio.available()) { while (radio.available()) { int angleV = 0; radio.read(&angleV, sizeof(angleV)); myServo.write(angleV); }Beispiel 3 – Mehrere Variablen in einem einzelnen Paket senden
/* 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); }// 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/* 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); }
Fazit

Herstellungsprozess
- Luftqualität messen mit OpenSensors: Arduino & Python Anleitung
- Universelle IR-Fernbedienung mit Arduino bauen: Schritt-für-Schritt-Anleitung
- Digitales Stadiometer bauen: Körpergröße messen mit Arduino & Lasersensor VL53L0X
- JX Wave Generator – Arduino-kompatibler DDS-Oszillator mit OLED-Display
- DIY VR-Skateboard mit Arduino, Google Cardboard und Bluetooth bauen
- Arduino Mega mit NEO‑6M GPS-Modul verbinden: Schritt-für-Schritt-Anleitung
- Thermistor (NTC) einfach nutzen: Schritt-für-Schritt Arduino-Anleitung
- Musikalische Töne mit Arduino erzeugen: Schritt-für-Schritt-Anleitung
- Modbus auf Arduino meistern: Schritt-für-Schritt-Anleitung
- Brain-Computer-Interfaces: Wiederverbindung von Gedanke und Handlung