Bauteile · 15 Min. Lesezeit

nRF24L01 Arduino: Funkmodul anschließen, Code und Reichweite

nRF24L01 am Arduino: Anschluss, 3,3 V und 10-µF-Kondensator, RF24-Code für Sender und Empfänger, PA+LNA mit bis zu 1 km, Joystick-Fernbedienung, ESP32 und Pico.

Das Duo nRF24L01 und Arduino ist der günstigste und praktischste Weg, Daten ohne Kabel zwischen zwei Boards zu übertragen. Das fingernagelgroße Funkmodul arbeitet im 2,4-GHz-Band, überträgt bis zu 2 Megabit pro Sekunde und kann sowohl als Sender als auch als Empfänger arbeiten. Es eignet sich ideal für ferngesteuerte Autos, kabellose Joysticks, eine Station, die Messwerte vom Gartensensor ins Haus funkt, oder Alarmknoten, die sich gegenseitig benachrichtigen. Die Standardversion schafft im Freien etwa 100 Meter, die Version nRF24L01+PA+LNA mit externer Antenne unter guten Bedingungen bis zu 1 Kilometer.

In dieser Anleitung lernst du, wie das Modul funktioniert, welche SPI-Pins es nutzt, warum es unbedingt mit 3,3 V versorgt werden muss und wie ein 10-µF-Kondensator das häufigste Problem löst. Danach schreibst du mit der RF24-Bibliothek Code für Sender und Empfänger, verstehst Adressen und Kanäle, baust eine Joystick-Fernbedienung, schließt das Modul an einen ESP32 und einen Raspberry Pi Pico an und löst zum Schluss die Probleme "radio.begin() false" und "keine Daten kommen an" Schritt für Schritt.

nRF24L01 2,4-GHz-Funkmodul
Standardmodul nRF24L01+: Die Zickzack-Leiterbahn am Ende der Platine ist die PCB-Antenne; angeschlossen wird es per SPI über die 8-polige Stiftleiste.

Was ist das nRF24L01 und wie funktioniert es?

Das nRF24L01 ist ein 2,4-GHz-Funk-Transceiver-Chip von Nordic Semiconductor; fast alle heute verkauften Module tragen die verbesserte Version nRF24L01+ oder einen kompatiblen Klon-Chip. Das Modul spricht über SPI mit dem Arduino: Der Arduino schreibt die Einstellungen und die zu sendenden Daten per SPI, den Rest erledigt der Chip. Das Hardware-Protokoll von Nordic namens Enhanced ShockBurst versieht jedes Paket mit einer Adresse und einer CRC (Fehlerprüfung). Empfängt der Empfänger ein Paket fehlerfrei, schickt er automatisch eine Bestätigung (ACK) an den Sender zurück; bleibt sie aus, wiederholt der Sender das Paket selbstständig. Dein Code sagt also nur "senden", Wiederholungen und Fehlerprüfung erledigt die Hardware.

Ein Paket transportiert höchstens 32 Byte Nutzdaten. Das klingt wenig, aber zwei Joystick-Achsen, ein paar Taster und mehrere Sensorwerte passen locker hinein. Das Modul nutzt einen von 126 Kanälen, die Frequenz ergibt sich aus 2400 + Kanalnummer (MHz); Kanal 76 liegt zum Beispiel bei 2476 MHz. Ein Empfänger kann gleichzeitig 6 verschiedene Adressen (Pipes) abhören und so als Zentrale Daten von sechs Sendern sammeln.

EigenschaftWert
Frequenz2,400–2,525 GHz (126 Kanäle, 1 MHz Abstand)
Datenrate250 kbps, 1 Mbps, 2 Mbps
Versorgungsspannung1,9–3,6 V (in der Praxis 3,3 V)
Eingangspins5-V-tolerant (CE, CSN, SCK, MOSI)
Sendeleistung0, −6, −12, −18 dBm
Strom (Senden, 0 dBm)Etwa 11,3 mA
Strom (Empfangen, 2 Mbps)Etwa 13,5 mA
Power-downEtwa 900 nA
Empfindlichkeit−94 dBm (250 kbps), −85 dBm (1 Mbps), −82 dBm (2 Mbps)
Paketgröße1–32 Byte
SchnittstelleSPI, bis 10 MHz
Anzahl Pipes6

nRF24L01 und nRF24L01+PA+LNA im Vergleich

Im Handel findest du zwei Modultypen. Beim Standardmodul ist die Antenne eine aufgedruckte Kupferbahn im Zickzack. Bei der Version nRF24L01+PA+LNA sitzt vor demselben Chip ein zusätzlicher HF-Frontend-Baustein: Der PA (Power Amplifier, Leistungsverstärker) verstärkt das ausgehende Signal, der LNA (Low Noise Amplifier, rauscharmer Verstärker) verstärkt schwache Signale, bevor sie den Chip erreichen. Dazu kommt eine aufschraubbare Antenne am SMA-Anschluss. Beide Module haben dieselbe Pinbelegung und denselben Code und funken problemlos miteinander; der Unterschied liegt in Reichweite und Strombedarf. Die Werte unten sind Richtwerte und hängen stark von der Umgebung ab.

nRF24L01+PA+LNA Funkmodul mit Antenne
nRF24L01+PA+LNA: die Version mit Sende- und Empfangsverstärker und SMA-Antenne. Sie läuft mit demselben Code, braucht aber deutlich mehr Strom.
EigenschaftnRF24L01+ (PCB-Antenne)nRF24L01+PA+LNA
AntenneAuf die Platine gedrucktExterne SMA-Antenne
SendeleistungBis 0 dBm (1 mW)Je nach Modell bis +20 dBm (100 mW)
Spitzenstrom beim SendenEtwa 12 mABis 115 mA
Spitzenstrom beim EmpfangenEtwa 13,5 mABis 45 mA
Reichweite im Freien (250 kbps)50–100 m800–1100 m
Reichweite im Haus10–30 m, 1–2 WändeMehrere Etagen und einige Dutzend Meter
Empfohlene Versorgung3,3-V-Pin + 10-µF-KondensatorEigener 3,3-V-Regler + Kondensator

nRF24L01 Pinbelegung und Anschluss an den Arduino

Das Modul hat 8 Pins in einer 2×4-Stiftleiste. Der Pin mit dem quadratischen Lötpad ist Pin 1, also GND; direkt daneben liegt VCC. CE (Chip Enable) schaltet das Modul in den Empfangs- oder Sendemodus, CSN (Chip Select Not) wird auf LOW gezogen, um auf dem SPI-Bus zu sagen: "Jetzt rede ich mit dir." SCK, MOSI und MISO sind die üblichen SPI-Leitungen und gehören an die festen SPI-Pins deines Boards, CE und CSN dagegen an beliebige Digitalpins. Der IRQ-Pin ist optional; er geht auf LOW, wenn ein Paket ankommt oder ein Sendevorgang abgeschlossen ist, und wird genutzt, wenn du mit Interrupts arbeiten willst. Wie SPI funktioniert, erfährst du unter Was ist SPI, die komplette Pinbelegung deines Boards im Tool Pinout.

nRF24L01-PinFunktionArduino Uno / NanoArduino MegaESP32Raspberry Pi Pico
1 GNDMasseGNDGNDGNDGND
2 VCCVersorgung (3,3 V)3.3V3.3V3V33V3(OUT)
3 CEModuswahlD9D9GPIO 4GP6
4 CSNSPI-ChipauswahlD10D10GPIO 5GP5
5 SCKSPI-TaktD13D52GPIO 18GP2
6 MOSIDaten vom Board zum ModulD11D51GPIO 23GP3
7 MISODaten vom Modul zum BoardD12D50GPIO 19GP4
8 IRQInterrupt (optional)FreiFreiFreiFrei
Schließe VCC niemals an 5 V an. Der Chip verträgt höchstens 3,6 V, 5 V können ihn dauerhaft zerstören. Die Signalpins sind 5-V-tolerant und dürfen direkt an die SPI-Pins des Uno, die Versorgung muss aber immer 3,3 V sein. Stecke das Modul auch nicht direkt ins Breadboard: Wegen der 2×4-Stiftleiste landen gegenüberliegende Pins im selben Kontaktstreifen und werden kurzgeschlossen. Nimm stattdessen Jumperkabel (Buchse auf Stecker).

Der häufigste Fehler: Stromversorgung und der 10-µF-Kondensator

Die meisten nRF24L01-Probleme liegen nicht am Code, sondern an der Stromversorgung. Das Modul zieht beim Senden kurze, steile Stromspitzen. Lange Jumperkabel und eine schwache 3,3-V-Quelle kommen da nicht hinterher: Die Spannung bricht kurz ein, der Chip sendet ein fehlerhaftes Paket, verpasst Bestätigungen oder setzt sich zurück. Laut offizieller Dokumentation liefert der 3,3-V-Pin des Arduino Uno höchstens 50 mA; das reicht für das Standardmodul, aber nicht für die PA+LNA-Version mit bis zu 115 mA. Bei manchen Nano-Klonen kommt die 3,3 V vom USB-Seriell-Chip und ist noch schwächer. Die Symptome kommen dir sicher bekannt vor: write() klappt mal und mal nicht, das Modul funktioniert besser, wenn du es anfasst, oder die Reichweite endet nach wenigen Metern.

  • 10-µF-Kondensator: Setze einen 10-µF-Elektrolytkondensator so nah wie möglich direkt an die Pins VCC und GND des Moduls. Das lange Bein (+) kommt an VCC, die Seite mit dem Streifen (−) an GND. Werte zwischen 10 und 100 µF funktionieren ebenfalls; warum das hilft, liest du unter Was ist ein Kondensator.
  • 100-nF-Keramikkondensator: Ein kleiner Keramikkondensator (Aufdruck 104) parallel zum Elko filtert hochfrequente Störungen. Die Aufdrucke auf Kondensatoren entschlüsselst du mit dem Tool Kondensator-Code.
  • Sockel-Adapter: Die 8-poligen Adapterplatinen für das nRF24L01 haben bereits einen AMS1117-3.3-Regler und Kondensatoren. Du gibst 5 V auf VCC des Adapters, und das Modul bekommt saubere 3,3 V.
  • Eigener Spannungsregler: Versorge die PA+LNA-Version nicht über den 3,3-V-Pin des Arduino, sondern über einen eigenen AMS1117-3.3-Regler, der aus 5 V gespeist wird, und verbinde alle Massen miteinander.
  • Kurze Kabel: Halte die Jumperkabel möglichst unter 10 cm; lange, wackelige Kabel stören sowohl die Versorgung als auch die SPI-Signale.
AMS1117 3,3-V-Spannungsregler
AMS1117-3.3-Regler: Er senkt 5 V auf 3,3 V und liefert problemlos den hohen Strom, den das PA+LNA-Modul beim Senden zieht.

Die RF24-Bibliothek installieren

  1. Öffne in der Arduino IDE Werkzeuge > Bibliotheken verwalten oder klicke links auf das Bibliotheks-Symbol.
  2. Gib RF24 ins Suchfeld ein und installiere die Bibliothek RF24 von TMRh20. RF24Network, RF24Mesh und RF24Ethernet sind separate Bibliotheken und für den Einstieg nicht nötig.
  3. Nach der Installation findest du unter Datei > Beispiele > RF24 das Beispiel GettingStarted. Der Code in diesem Artikel nutzt die Schreibweise von RF24 ab Version 1.5.
  4. Wenn du zum ersten Mal eine Bibliothek installierst, folge den Schritten in Arduino-Bibliothek hinzufügen.
In älteren Beispielen im Netz siehst du radio.openWritingPipe(address) und danach radio.stopListening(). Seit RF24 1.5 wird stattdessen die einzelne Zeile radio.stopListening(address) empfohlen; die alte Schreibweise kompiliert noch, kann aber eine "deprecated"-Warnung auslösen. Falls der Code hier nicht kompiliert, aktualisiere deine RF24-Bibliothek.

Adresse, Kanal und Datenrate: damit sich zwei Module verstehen

Damit sich zwei Module hören, müssen einige Einstellungen auf beiden Seiten exakt gleich sein. Stell es dir wie ein Gespräch per Walkie-Talkie vor: Ohne dieselbe Frequenz (Kanal), dasselbe Sprechtempo (Datenrate) und dasselbe Rufzeichen (Adresse) hörst du die Gegenseite nicht. Die Adresse ist ein 5-Byte-Array; am einfachsten schreibst du sie im Code als Text mit 5 Zeichen wie "00001". Sieh die Adresse nicht als Kennung eines Geräts, sondern als gemeinsamen Weg zwischen zwei Geräten: Der Sender legt Pakete auf diesen Weg, der Empfänger, der ihn abhört, nimmt sie auf. Auch die Paketgröße ist wichtig; RF24 nutzt standardmäßig feste Paketgrößen, und erwartet der Empfänger nicht dieselbe Größe wie der Sender, sieht er das Paket nie.

EinstellungRF24-FunktionWert in diesem ArtikelHinweis
KanalsetChannel(76)76 (2476 MHz)0–125; muss auf beiden Seiten gleich sein
DatenratesetDataRate(RF24_250KBPS)250 kbpsWeniger Tempo, mehr Reichweite
AdressestopListening(Adresse) / openReadingPipe(1, Adresse)"00001"Ziel des Senders = Pipe des Empfängers
PaketgrößesetPayloadSize(sizeof(daten))32 Byte (im Joystick-Beispiel 5)Bei fester Größe auf beiden Seiten gleich
SendeleistungsetPALevel(RF24_PA_LOW)NiedrigMuss nicht übereinstimmen, bestimmt die Reichweite
Auto-ACK und CRCStandardmäßig an16-Bit-CRCWenn du sie abschaltest, dann auf beiden Seiten

Sender-Code (TX)

Schließe für den ersten Test beide Arduinos an zwei USB-Ports an und lege 1–2 Meter zwischen die Module. Lade auf einen davon den folgenden Sender-Code. Er sendet jede Sekunde eine nummerierte Nachricht und zeigt im seriellen Monitor an, ob der Empfänger sie bestätigt hat. Stelle den seriellen Monitor auf 115200 Baud.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // iki tarafta aynı adres / same address on both sides
6char message[32];                         // en fazla 32 bayt / 32 bytes max
7uint16_t counter = 0;
8
9void setup() {
10  Serial.begin(115200);
11  if (!radio.begin()) {                   // modül cevap vermiyor / module not responding
12    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
13    while (true) {}
14  }
15  radio.setChannel(76);                   // kanal 76 = 2476 MHz / channel 76 = 2476 MHz
16  radio.setDataRate(RF24_250KBPS);        // en uzun menzil / longest range
17  radio.setPALevel(RF24_PA_LOW);          // masa testi için düşük güç / low power for desk tests
18  radio.setPayloadSize(sizeof(message));  // paket boyu 32 bayt / 32-byte payload
19  radio.stopListening(address);           // verici modu + hedef adres / TX mode + target address
20}
21
22void loop() {
23  snprintf(message, sizeof(message), "Merhaba BlueGrays #%u", counter++);
24  bool ok = radio.write(message, sizeof(message));   // onay (ACK) geldi mi? / was it acknowledged?
25  if (ok) {
26    Serial.print(F("Gonderildi: "));
27    Serial.println(message);
28  } else {
29    Serial.println(F("Onay gelmedi"));
30  }
31  delay(1000);
32}

Empfänger-Code (RX)

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // vericiyle aynı adres / same address as the transmitter
6char message[32];
7
8void setup() {
9  Serial.begin(115200);
10  if (!radio.begin()) {
11    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
12    while (true) {}
13  }
14  radio.setChannel(76);                   // ayarlar vericiyle aynı / settings match the transmitter
15  radio.setDataRate(RF24_250KBPS);
16  radio.setPALevel(RF24_PA_LOW);
17  radio.setPayloadSize(sizeof(message));
18  radio.openReadingPipe(1, address);      // 1 numaralı boruyu aç / open pipe 1
19  radio.startListening();                 // alıcı modu / RX mode
20}
21
22void loop() {
23  if (radio.available()) {                // paket geldi mi? / has a packet arrived?
24    radio.read(message, sizeof(message));
25    Serial.print(F("Gelen: "));
26    Serial.println(message);
27  }
28}

radio.write() sendet das Paket und gibt true zurück, wenn der Empfänger bestätigt; ohne Bestätigung versucht es die Bibliothek mit den Standardeinstellungen 15-mal im Abstand von etwa 1,5 ms und gibt dann false zurück. Beim Empfänger stellt openReadingPipe(1, address) Pipe 1 auf die Adresse des Senders ein, startListening() schaltet in den Empfangsmodus, available() meldet, ob ein Paket wartet, und read() kopiert es in deine Variable. Siehst du im seriellen Monitor des Empfängers hochzählende Zeilen wie "Gelen: Merhaba BlueGrays #0", "#1", "#2", funktioniert deine Funkstrecke.

Lege die Module beim Testen nicht direkt nebeneinander und halte die Sendeleistung niedrig. Vor allem PA+LNA-Module übersteuern sich gegenseitig, wenn sie wenige Zentimeter voneinander entfernt mit voller Leistung senden; Pakete gehen verloren, und es sieht nach einem Defekt aus. Nutze auf kurze Distanz RF24_PA_LOW oder RF24_PA_MIN und erhöhe die Leistung erst bei der echten Entfernung.

Reichweite: von 100 Metern bis 1 Kilometer

Drei Dinge bestimmen die Reichweite: Sendeleistung, Empfindlichkeit des Empfängers und Umgebung. Je niedriger die Datenrate, desto schwächere Signale kann der Empfänger noch auswerten; bei 250 kbps liegt die Empfindlichkeit bei −94 dBm, bei 2 Mbps bei −82 dBm. Diese 12 dB Unterschied bedeuten im Freien grob die vierfache Reichweite. Wände, Bäume, Menschen und Metallflächen dämpfen 2,4-GHz-Signale stark, und WLAN-Router, Bluetooth-Geräte und Mikrowellen teilen sich dasselbe Band.

DatenrateEmpfindlichkeitRelative ReichweiteWann?
250 kbps−94 dBmAm größtenFernbedienung, entfernte Sensoren
1 Mbps−85 dBmMittelAllgemein (RF24-Standard)
2 Mbps−82 dBmAm kleinstenHohe Geschwindigkeit, kurze Distanz

Auch die Kanalwahl zählt. Die häufig genutzten WLAN-Kanäle 1, 6 und 11 belegen ungefähr 2401–2473 MHz; die nRF24L01-Kanäle 74–83 liegen darüber und sind ruhiger, solange in der Nähe kein Router WLAN-Kanal 12 oder 13 nutzt. In Europa reicht das lizenzfreie 2,4-GHz-Band von 2400 bis 2483,5 MHz, nutze also keine Kanäle über 83; die Kanäle ab 100, die manche Beispiele im Netz empfehlen, liegen außerhalb dieses Bands. Für mehr Reichweite probierst du Folgendes:

  • 250 kbps verwenden: Fernbedienungen und Sensordaten brauchen kein hohes Tempo, die niedrige Rate bringt Reichweite.
  • Erst die Versorgung reparieren, dann die Leistung erhöhen: RF24_PA_MAX ist nur mit stabilen 3,3 V und Kondensator sinnvoll; bei schwacher Versorgung macht mehr Leistung alles schlimmer.
  • Antennen hoch und gleich ausgerichtet montieren: 1–2 Meter über dem Boden und beide Antennen senkrecht in derselben Richtung verbessern die Reichweite spürbar.
  • Abstand zu Metall halten: Setze das Modul nicht in ein Metallgehäuse und nicht direkt neben einen großen Akkupack.
  • Ungeschirmte PA+LNA-Platine umwickeln: Ein PA+LNA-Modul ohne Metallabdeckung mit Isolierband und darüber Alufolie zu umwickeln, verringert die Störungen, die es sich selbst einfängt; die Folie darf keinen Pin und nicht den Antennenanschluss berühren.
  • Nie ohne Antenne senden: Ein PA+LNA-Modul ohne angeschlossene Antenne mit voller Leistung zu betreiben, belastet den Leistungsverstärker.

Funk-Fernbedienung mit Joystick

Jetzt bauen wir ein echtes Projekt: Mit einem Joystick am einen Arduino steuern wir kabellos einen Servomotor und eine LED am zweiten Arduino. Beim Sender kommt VRx des Joysticks an A0, VRy an A1 und der Taster (SW) an D2; Details findest du unter Joystick-Modul. Beim Empfänger kommt die Signalleitung des Servos an D3 und die LED über einen 220-Ω-Widerstand an D4. Das nRF24L01 wird auf beiden Seiten wie in der Tabelle oben angeschlossen.

Mehrere Werte in einem Paket sendest du am saubersten mit einem struct. Dabei gibt es ein wichtiges Detail: Verwende Typen mit fester Größe wie int16_t und uint8_t. Ein int hat auf dem Arduino Uno 2 Byte, auf dem ESP32 aber 4 Byte, und der ESP32-Compiler hängt zur Ausrichtung zusätzlich Füllbytes an das Ende des structs. Ist dieselbe Struktur auf dem Uno 5 und auf dem ESP32 6 Byte groß, passen die Paketgrößen nicht zusammen, und es kommen gar keine Daten an. __attribute__((packed)) entfernt diese Lücken und macht die Struktur auf jedem Board 5 Byte groß. Zuerst der Sender:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // her kartta 5 bayt / 5 bytes on every board
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
11const uint8_t address[6] = "JOY01";       // kumanda adresi / remote address
12JoystickData data;
13
14void setup() {
15  pinMode(2, INPUT_PULLUP);               // joystick butonu (SW) / joystick button (SW)
16  if (!radio.begin()) {
17    while (true) {}                       // modül yok / no module
18  }
19  radio.setChannel(76);
20  radio.setDataRate(RF24_250KBPS);
21  radio.setPALevel(RF24_PA_HIGH);         // orta-yüksek güç / medium-high power
22  radio.setPayloadSize(sizeof(data));
23  radio.stopListening(address);           // verici modu / TX mode
24}
25
26void loop() {
27  data.x = analogRead(A0);                // VRx ekseni 0-1023 / VRx axis 0-1023
28  data.y = analogRead(A1);                // VRy ekseni 0-1023 / VRy axis 0-1023
29  data.button = (digitalRead(2) == LOW);  // basılıysa 1 / 1 when pressed
30  radio.write(&data, sizeof(data));
31  delay(50);                              // saniyede 20 paket / 20 packets per second
32}

Dann der Empfänger, der Servo und LED ansteuert:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include <Servo.h>
4
5struct __attribute__((packed)) JoystickData {   // vericiyle birebir aynı / identical to the transmitter
6  int16_t x;
7  int16_t y;
8  uint8_t button;
9};
10
11RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
12const uint8_t address[6] = "JOY01";       // vericiyle aynı / same as the transmitter
13JoystickData data;
14Servo servo;
15unsigned long lastPacket = 0;
16
17void setup() {
18  pinMode(4, OUTPUT);                     // LED çıkışı / LED output
19  servo.attach(3);                        // servo sinyal pini / servo signal pin
20  if (!radio.begin()) {
21    while (true) {}
22  }
23  radio.setChannel(76);
24  radio.setDataRate(RF24_250KBPS);
25  radio.setPALevel(RF24_PA_HIGH);
26  radio.setPayloadSize(sizeof(data));
27  radio.openReadingPipe(1, address);
28  radio.startListening();                 // alıcı modu / RX mode
29}
30
31void loop() {
32  if (radio.available()) {
33    radio.read(&data, sizeof(data));
34    servo.write(map(data.x, 0, 1023, 0, 180));   // X ekseni -> servo açısı / X axis -> servo angle
35    digitalWrite(4, data.button ? HIGH : LOW);   // buton LED'i yakar / button lights the LED
36    lastPacket = millis();
37  }
38  if (millis() - lastPacket > 500) {      // 0,5 sn paket yok: güvenli konum / no packet for 0.5 s: failsafe
39    servo.write(90);
40    digitalWrite(4, LOW);
41  }
42}

Der Sender schickt 20 Pakete pro Sekunde; der Empfänger rechnet bei jedem Paket die X-Achse auf 0–180 Grad um und gibt den Wert an den Servo. Sehr wichtig ist der Failsafe-Teil beim Empfänger: Ist der Akku der Fernbedienung leer oder bist du außer Reichweite, bleibt der letzte Befehl nicht ewig aktiv; kommt 0,5 Sekunden lang kein Paket, fährt der Servo in die Mitte und die LED geht aus. Baust du ein Roboterauto, hältst du an derselben Stelle die Motoren an. Versorgst du den Servo aus einer eigenen 5-V-Quelle statt über den 5-V-Pin des Arduino, stören seine Stromspitzen außerdem das nRF24L01 nicht. Schließt du die Y-Achse an einen L298N-Motortreiber an, wird daraus ein kabelloses Roboterauto; Details zum Servo findest du unter Was ist ein Servomotor.

Zwei-Wege-Kommunikation und mehrere Sender

Das nRF24L01 kann nicht gleichzeitig senden und empfangen, aber es gibt einen einfachen Weg zur Zwei-Wege-Kommunikation: ACK-Payload, also Daten, die in der Bestätigung mitreisen. Der Empfänger legt mit writeAckPayload() vorab fest, was er an die nächste Bestätigung anhängt (etwa die Akkuspannung oder einen Sensorwert); nach einem erfolgreichen write() liest der Sender diese Antwort mit available() und read(). Dazu müssen beide Seiten enableDynamicPayloads() und enableAckPayload() aufrufen. Für mehrere Sender hat der Empfänger 6 Pipes: Pipe 0 und 1 bekommen eine volle 5-Byte-Adresse, die Pipes 2–5 teilen sich den Rest der Adresse von Pipe 1 und unterscheiden sich nur in einem Byte. Bei RF24 ist dieses Byte das erste Zeichen des Adress-Arrays; deshalb nutzt man Adressen wie "1Node", "2Node" und "3Node", die sich nur im ersten Zeichen unterscheiden. Für größere Netze gibt es die Bibliotheken RF24Network und RF24Mesh.

nRF24L01 am ESP32 anschließen

Auf dem ESP32 läuft die RF24-Bibliothek unverändert, und radio.begin() nutzt den Standard-VSPI-Bus: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. Für CSN eignet sich GPIO 5, für CE GPIO 4. Der 3,3-V-Regler auf ESP32-DevKit-Boards ist kräftiger als der des Uno, den 10-µF-Kondensator solltest du trotzdem nicht weglassen. Bei Modellen wie dem ESP32-C3 oder ESP32-S3 liegen die Standard-SPI-Pins anders, schau also in die Pinbelegung deines Boards. Da auch das WLAN des ESP32 auf 2,4 GHz funkt, wähle einen nRF24L01-Kanal weit weg vom WLAN-Kanal deines Routers, wenn du beides gleichzeitig nutzt. Der folgende Code liest die Pakete des Joystick-Senders auf dem ESP32; mit demselben Aufbau kannst du den ESP32 als Gateway nutzen, das Daten von nRF24L01-Knoten ins Internet weiterleitet. Kennst du das Board noch nicht, starte mit Was ist der ESP32.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // packed olmasa 6 bayt olurdu / 6 bytes without packed
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(4, 5);                         // CE = GPIO 4, CSN = GPIO 5 pinleri / CE = GPIO 4, CSN = GPIO 5 pins
11const uint8_t address[6] = "JOY01";
12JoystickData data;
13
14void setup() {
15  Serial.begin(115200);
16  if (!radio.begin()) {                   // varsayılan VSPI: SCK 18, MISO 19, MOSI 23 / default VSPI pins
17    Serial.println("nRF24L01 bulunamadi!");
18    while (true) delay(1000);
19  }
20  radio.setChannel(76);
21  radio.setDataRate(RF24_250KBPS);
22  radio.setPALevel(RF24_PA_HIGH);
23  radio.setPayloadSize(sizeof(data));     // packed sayesinde 5 bayt / 5 bytes thanks to packed
24  radio.openReadingPipe(1, address);
25  radio.startListening();
26}
27
28void loop() {
29  if (radio.available()) {
30    radio.read(&data, sizeof(data));
31    Serial.printf("X=%d  Y=%d  Buton=%d\n", data.x, data.y, data.button);
32  }
33}

Willst du nur ESP32-Boards untereinander verbinden, ist auch ESP-NOW ohne Zusatzmodul eine gute Wahl; der Vorteil des nRF24L01 ist, dass es auch mit günstigen, sparsamen Boards wie Uno, Nano und Pro Mini funktioniert.

nRF24L01 mit dem Raspberry Pi Pico und MicroPython

Für MicroPython auf dem Pico nutzt du den Treiber nrf24l01.py aus dem offiziellen Repository micropython-lib. Du kannst die Datei mit Thonny auf den Pico kopieren oder am Computer mit mpremote mip install nrf24l01 installieren. Angeschlossen wird über SPI0: SCK = GP2, MOSI = GP3, MISO = GP4, CSN = GP5, CE = GP6 und VCC = 3V3(OUT). Die Standardwerte des Treibers weichen von RF24 ab (Kanal 46, 16 Byte Paketgröße), deshalb setzen wir Kanal, Datenrate und Paketgröße im Code ausdrücklich passend zum Arduino. Der folgende Code wertet die Pakete des Joystick-Senders auf dem Pico aus:

MicroPython
1from machine import Pin, SPI
2import struct
3import utime
4from nrf24l01 import NRF24L01, POWER_2, SPEED_250K
5
6spi = SPI(0, sck=Pin(2), mosi=Pin(3), miso=Pin(4))   # SPI0 pinleri / SPI0 pins
7csn = Pin(5, mode=Pin.OUT, value=1)                  # CSN pini GP5 / CSN pin GP5
8ce = Pin(6, mode=Pin.OUT, value=0)                   # CE pini GP6 / CE pin GP6
9
10nrf = NRF24L01(spi, csn, ce, channel=76, payload_size=5)   # Arduino ile aynı / same as the Arduino
11nrf.set_power_speed(POWER_2, SPEED_250K)             # -6 dBm güç, 250 kbps / -6 dBm power, 250 kbps
12nrf.open_rx_pipe(1, b"JOY01")                        # vericinin adresi / transmitter address
13nrf.start_listening()                                # alıcı modu / RX mode
14print("Dinleniyor... / Listening...")
15
16while True:
17    if nrf.any():                                    # paket geldi mi? / packet waiting?
18        x, y, button = struct.unpack("<hhB", nrf.recv())   # 2 + 2 + 1 bayt / 2 + 2 + 1 bytes
19        print("X:", x, "Y:", y, "Buton:", button)
20    utime.sleep_ms(5)

struct.unpack("<hhB") wandelt die 5 empfangenen Bytes in zwei vorzeichenbehaftete 16-Bit-Zahlen und ein Byte um; das führende "<" legt die Little-Endian-Bytereihenfolge fest, die auch AVR und ESP32 verwenden. Findet der Treiber das Modul nicht, meldet er "nRF24L01+ Hardware not responding", das MicroPython-Gegenstück zu begin() false am Arduino. Bist du neu beim Pico, lies zuerst Was ist der Raspberry Pi Pico.

radio.begin() gibt false zurück: Lösung Schritt für Schritt

Zeigt der serielle Monitor "nRF24L01 bulunamadi" oder die Meldung "radio hardware is not responding!!" aus den RF24-Beispielen, kann der Arduino überhaupt nicht per SPI mit dem Modul sprechen. Dann liegt das Problem fast immer an der Verkabelung oder der Versorgung, nicht am Code. Lade zuerst den folgenden Diagnose-Sketch hoch; er gibt alle Einstellungen des Moduls lesbar aus.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include "printf.h"                       // RF24 ile gelir / ships with RF24
4
5RF24 radio(9, 10);                        // kendi CE, CSN pinlerin / your CE, CSN pins
6
7void setup() {
8  Serial.begin(115200);
9  printf_begin();                         // printPrettyDetails için / needed for printPrettyDetails
10  bool ok = radio.begin();
11  Serial.print(F("begin(): "));
12  Serial.println(ok ? "true" : "false");
13  Serial.print(F("isChipConnected(): "));
14  Serial.println(radio.isChipConnected() ? "true" : "false");
15  radio.printPrettyDetails();             // tüm ayarları yazdır / print every setting
16}
17
18void loop() {
19}
  1. MOSI und MISO prüfen: Diese beiden Leitungen werden am häufigsten vertauscht. Beim Uno und Nano gilt MOSI = D11, MISO = D12, SCK = D13; beim Mega sind es 51, 50 und 52.
  2. Stimmen CE und CSN mit dem Code überein: Hast du RF24 radio(9, 10) geschrieben, gehört CE an D9 und CSN an D10. Das RF24-Beispiel GettingStarted nutzt die Pins 7 und 8; probierst du es unverändert aus, verkable es entsprechend.
  3. Liegen 3,3 V an: Miss mit dem Multimeter zwischen VCC und GND, du solltest 3,0–3,6 V sehen. War das Modul schon einmal an 5 V, ist es womöglich defekt.
  4. Ausgabe von printPrettyDetails ansehen: Zeigen Adressen und Registerwerte durchgehend 0x00 oder 0xff, funktioniert der SPI-Bus nicht. Sehen die Werte plausibel aus, aber die Verbindung klappt trotzdem nicht, liegt es am CE-Pin, an den Einstellungen oder an der Versorgung.
  5. Kabel kürzen, SPI-Takt senken: Bei langen oder wackeligen Kabeln senkst du den SPI-Takt mit RF24 radio(9, 10, 4000000) von standardmäßig 10 MHz auf 4 MHz.
  6. Modul tauschen: Wenn alles andere stimmt, teste ein Ersatzmodul; in günstigen Mehrfachpackungen kann ein defektes stecken.

Keine oder lückenhafte Daten: häufige Fehler

SymptomMögliche UrsacheLösung
begin() ist true, aber beim Empfänger kommt nichts anKanal, Datenrate, Adresse oder Paketgröße unterscheiden sichDie vier Einstellungen in beiden Sketches nebeneinander vergleichen
Keine Daten vom Uno zum ESP32Unterschiedliche struct-Größe (5 und 6 Byte)Typen mit fester Größe und __attribute__((packed)) verwenden
write() ist false, aber der Empfänger erhält die DatenDie Bestätigung des Empfängers kommt nicht an, meist wegen dessen VersorgungAuch am Empfängermodul einen 10-µF-Kondensator einsetzen
Ständig leere oder sinnlose DatenWackeliges SPI-Kabel oder unterbrochenes MISOKabel tauschen, SPI-Takt auf 4 MHz senken
Geht direkt nebeneinander nicht, mit Abstand schonDer Empfänger wird bei voller Leistung übersteuertsetPALevel(RF24_PA_LOW) oder RF24_PA_MIN verwenden
Funktioniert besser, wenn man es anfasstInstabile Versorgung oder ungeschirmtes PA+LNAKondensator, eigener Regler und Folienabschirmung
Verbindung bricht nach wenigen Metern ab2 Mbps, schwache Versorgung oder WLAN-Störungen250 kbps, saubere Versorgung, Kanal zwischen 74 und 83
Geh bei der Fehlersuche immer zum einfachsten Aufbau zurück: zwei Module 1–2 Meter auseinander, RF24_PA_LOW, 250 kbps, kurze Kabel und ein 10-µF-Kondensator. Steht damit eine funktionierende Verbindung, erhöhst du Entfernung, Leistung und Komplexität des Codes Schritt für Schritt und siehst sofort, ab welchem Schritt das Problem beginnt.

Projektideen mit dem nRF24L01

  • Funk-Fernbedienung für ein Roboterauto: Steuere ein Roboterauto mit einer Zwei-Joystick-Fernbedienung aus Dutzenden Metern Entfernung.
  • Gartensensor-Station: Funke Werte von einem Bodenfeuchtesensor und Temperaturdaten von einem batteriebetriebenen Sender an ein Display im Haus. Mit radio.powerDown() zieht das Modul im Schlaf etwa 900 nA; die Akkulaufzeit berechnest du mit dem Tool Akkulaufzeit.
  • Funk-Tür- und Bewegungsalarm: Lass in der Zentrale einen Summer ertönen, wenn ein PIR-Sensor oder ein Reedschalter auslöst.
  • Temperaturnetz für mehrere Räume: Sammle die Werte von Sensoren in sechs Räumen über sechs Pipes an einem einzigen Empfänger.
  • ESP32-Gateway: Leite Daten von nRF24L01-Knoten mit einem ESP32 ins Internet, aufs Handy oder an ein Dashboard weiter.
  • Funk-Anzeigetafel: Aktualisiere eine 7-Segment-Anzeigetafel in der Sporthalle über Fernbedienungen mit Tastern.

Trotz seines niedrigen Preises bietet das nRF24L01 mehr Reichweite, geringere Latenz und Unterstützung für mehrere Geräte als Bluetooth; es braucht nur eine saubere 3,3-V-Versorgung und übereinstimmende Einstellungen auf beiden Seiten. Willst du per Handy steuern, passt das Bluetooth-Modul HC-05 besser, für kilometerweite Reichweite eher LoRa; einen Vergleich der Optionen findest du unter Funkmodule für Arduino. In der BlueGrays-App findest du Projekte wie die Kommunikation zwischen zwei Arduinos, die Joystick-Steuerung von Servo und LED und ein ferngesteuertes Auto Schritt für Schritt mit Schaltplänen und fertigem Code.

Häufige Fragen

Welche Reichweite hat das nRF24L01?

Das Standard-nRF24L01+ mit PCB-Antenne schafft im Freien bei 250 kbps etwa 50–100 Meter, im Haus je nach Wänden 10–30 Meter. Die Version nRF24L01+PA+LNA mit externer Antenne erreicht auf freier Fläche ohne Hindernisse 800–1100 Meter. Dafür brauchst du eine saubere 3,3-V-Versorgung, einen 10-µF-Kondensator und eine niedrige Datenrate.

Funktioniert das nRF24L01 mit 5V?

Nein, der VCC-Pin arbeitet mit 1,9–3,6 V, und 5 V können den Chip zerstören. Die Eingangspins CE, CSN, SCK und MOSI sind dagegen 5-V-tolerant und dürfen ohne Pegelwandler an die SPI-Pins eines Arduino Uno. Willst du das Modul aus 5 V versorgen, nimm einen Sockel-Adapter mit AMS1117-3.3-Regler.

Warum erscheint "radio hardware is not responding"?

Diese Meldung erscheint, wenn radio.begin() false zurückgibt, und bedeutet, dass der Arduino nicht per SPI mit dem Modul sprechen kann. Häufigste Ursachen sind vertauschte MOSI- und MISO-Leitungen, CE- und CSN-Pins, die nicht zum Code passen, eine schwache oder 5-V-Versorgung und wackelige Jumperkabel. Prüfe die Verkabelung und grenze das Problem mit der Ausgabe von printPrettyDetails() ein.

nRF24L01 oder HC-05 Bluetooth: Was ist besser?

Brauchst du zwischen Arduinos große Reichweite, geringe Latenz und mehrere Geräte, ist das nRF24L01 die bessere Wahl. Willst du per Handy steuern, nimm ein Bluetooth-Modul wie das HC-05 oder einen ESP32, denn Smartphones sprechen das Protokoll des nRF24L01 nicht. Das HC-05 reicht meist rund 10 Meter weit, das nRF24L01 kommt zum ähnlichen Preis viel weiter.

Wie viele Sender kann ein nRF24L01-Empfänger abhören?

Ein Empfänger kann gleichzeitig 6 Pipes abhören und damit direkt Daten von 6 Sendern sammeln. Die Pipes 2–5 teilen sich den Adressrumpf von Pipe 1 und unterscheiden sich nur in einem Byte. Für mehr Knoten kannst du die Sender der Reihe nach abfragen oder mit den Bibliotheken RF24Network und RF24Mesh deutlich größere Netze aufbauen.

Kann sich das nRF24L01 mit dem Handy verbinden?

Nicht direkt: Das nRF24L01 funkt zwar im selben 2,4-GHz-Band, nutzt aber weder das WLAN- noch das Bluetooth-Protokoll. Für eine Handy-Steuerung setzt du einen ESP32 in die Mitte deines nRF24L01-Netzes und gibst die Daten per WLAN oder Bluetooth ans Handy weiter. So sprechen die entfernten Knoten nRF24L01 und das Handy mit dem ESP32.

Alle Projekte ansehen
Einweg-Kommunikation zwischen 2 Arduinos
#57Mittel
Premium

Einweg-Kommunikation zwischen 2 Arduinos

Du bringst zwei Arduinos über ein einziges Kabel zum Reden: Drückst du den Knopf am einen, geht die LED am anderen an, drückst du noch einmal, geht sie aus. Die sendende Platine meldet den Knopfdruck

4.4(37)
50
Bidirektionale Kommunikation zwischen 2 Arduinos
#58Mittel
Premium

Bidirektionale Kommunikation zwischen 2 Arduinos

Zwei Arduinos werden per Kabel verbunden und unterhalten sich: Drückst du den Knopf am einen, geht am anderen das Licht an, drückst du noch einmal, geht es aus. Auf beiden Platinen läuft dasselbe Prog

4.5(20)
26
Led-Steuerung mit Joystick
#59Mittel
Premium

Led-Steuerung mit Joystick

Drück den kleinen Hebel des Joysticks ganz in eine Richtung, und die LED für diese Richtung leuchtet: Für rechts, links, oben und unten gibt es vier verschiedene Farben. Lässt du den Hebel los, spring

4.7(50)
67
Servo-Steuerung mit Joystick
#60Mittel
Premium

Servo-Steuerung mit Joystick

Steuere zwei Motoren mit einem Joystick, genau wie beim Schwenken einer Überwachungskamera. Drückst du den Hebel nach links oder rechts, dreht sich der untere Servomotor langsam, nach oben oder unten,

4.7(42)
58
Bluetooth-gesteuertes Auto mit L298N
#80Fortgeschritten
Premium

Bluetooth-gesteuertes Auto mit L298N

Mach dein Handy zur Fernbedienung und steuere dein eigenes Roboterauto. Der Arduino empfängt über ein Bluetooth-Modul die Befehle einer Fernsteuer-App auf dem Handy und treibt die Räder über einen Mot

5.0(38)
65
LED per Bluetooth mit dem Handy steuern
#34Anfänger
Premium

LED per Bluetooth mit dem Handy steuern

Eine kleine Probe dafür, das Licht in deinem Zimmer vom Handy aus ein- und auszuschalten. Das Bluetooth-Modul leitet die Buchstaben, die du vom Handy schickst, an den Arduino weiter; ein Buchstabe sch

4.8(68)
89
Led ein- und ausschalten mit IR-Empfänger und Fernbedienung
#17Mittel
Premium

Led ein- und ausschalten mit IR-Empfänger und Fernbedienung

Wie drei Lampen steuern, ohne aus dem Sessel aufzustehen: Die Tasten 1, 2 und 3 der Fernbedienung schalten die blaue, rote und grüne LED ein, die Tasten 4, 5 und 6 schalten sie in derselben Reihenfolg

4.7(45)
66
ESP32 IR-Universalfernbedienung (IR-Empfänger + Fernbedienung + 3 LEDs + Summer + OLED)
#143Fortgeschritten
Premium

ESP32 IR-Universalfernbedienung (IR-Empfänger + Fernbedienung + 3 LEDs + Summer + OLED)

Mit dem ESP32 kannst du eine fertige IR-Fernbedienung auslesen und dein eigenes Gerät steuern! In diesem Projekt erfassen wir mit einem Infrarotempfänger (NEC-Protokoll, 38 kHz) die Signale einer IR-Fernbedienung mit 20 Tasten. Für jede Taste haben wir eine andere Aktion definiert: Die Tasten 1/2/3 schalten drei separate LEDs ein und aus, die PWR-Taste schaltet alle aus, die Ziffern 4–9 sorgen für eine spezielle Anzeige auf dem OLED-Display. Auf dem SSD1306-OLED-Display werden die zuletzt gedrüc

4.5(9)
16