nRF24L01 Arduino : communication sans fil, code et portée
Guide nRF24L01 Arduino : câblage, 3,3 V et condensateur 10 µF, code RF24 émetteur et récepteur, PA+LNA jusqu'à 1 km, télécommande à joystick, ESP32 et Pico.
Le duo nRF24L01 et Arduino est le moyen le moins cher et le plus pratique d'envoyer des données entre deux cartes sans tirer de câble. Ce module grand comme un ongle fonctionne dans la bande des 2,4 GHz, transmet jusqu'à 2 mégabits par seconde et peut servir aussi bien d'émetteur que de récepteur. Il est idéal pour une voiture télécommandée, un joystick sans fil, une station qui transmet les mesures d'un capteur du jardin jusqu'à la maison ou des nœuds d'alarme qui se préviennent entre eux. La version standard porte à environ 100 mètres en champ libre, et la version nRF24L01+PA+LNA à antenne externe peut atteindre 1 kilomètre dans de bonnes conditions.
Dans ce guide, tu vas découvrir comment fonctionne le module, quelles broches SPI il utilise, pourquoi il doit toujours être alimenté en 3,3 V et comment un condensateur de 10 µF règle le problème le plus fréquent. Ensuite, tu écriras le code émetteur et récepteur avec la bibliothèque RF24, tu comprendras les adresses et les canaux, tu fabriqueras une télécommande à joystick, tu brancheras le module sur un ESP32 et un Raspberry Pi Pico et, pour finir, tu résoudras pas à pas les problèmes « radio.begin() false » et « aucune donnée reçue ».

Qu'est-ce que le nRF24L01 et comment fonctionne-t-il ?
Le nRF24L01 est une puce émetteur-récepteur radio 2,4 GHz fabriquée par Nordic Semiconductor ; presque tous les modules vendus aujourd'hui embarquent la version améliorée nRF24L01+ ou un clone compatible. Le module dialogue avec l'Arduino en SPI : l'Arduino écrit en SPI les réglages et les données à envoyer, la puce s'occupe du reste. Le protocole matériel de Nordic, appelé Enhanced ShockBurst, emballe chaque paquet avec une adresse et un CRC (contrôle d'erreurs). Quand le récepteur reçoit un paquet correctement, il renvoie automatiquement un accusé de réception (ACK) à l'émetteur ; si l'ACK n'arrive pas, l'émetteur réessaie tout seul. Ton code se contente donc de dire « envoie », les nouvelles tentatives et le contrôle d'erreurs se font dans le matériel.
Un paquet transporte au maximum 32 octets de données. Cela paraît peu, mais les deux axes d'un joystick, quelques boutons et plusieurs valeurs de capteurs y tiennent largement. Le module utilise l'un de 126 canaux, et la fréquence du canal se calcule avec 2400 + numéro de canal (MHz) ; le canal 76 correspond par exemple à 2476 MHz. Un récepteur peut écouter 6 adresses différentes (appelées pipes, ou tuyaux) en même temps, ce qui permet à un nœud central de collecter les données de six émetteurs.
| Caractéristique | Valeur |
|---|---|
| Fréquence | 2,400–2,525 GHz (126 canaux, pas de 1 MHz) |
| Débit | 250 kbps, 1 Mbps, 2 Mbps |
| Tension d'alimentation | 1,9–3,6 V (3,3 V en pratique) |
| Broches d'entrée | Tolérantes au 5 V (CE, CSN, SCK, MOSI) |
| Puissance d'émission | 0, −6, −12, −18 dBm |
| Courant (émission, 0 dBm) | Environ 11,3 mA |
| Courant (réception, 2 Mbps) | Environ 13,5 mA |
| Veille (power down) | Environ 900 nA |
| Sensibilité du récepteur | −94 dBm (250 kbps), −85 dBm (1 Mbps), −82 dBm (2 Mbps) |
| Taille de paquet | 1–32 octets |
| Interface | SPI, jusqu'à 10 MHz |
| Nombre de pipes | 6 |
Différences entre nRF24L01 et nRF24L01+PA+LNA
Tu trouveras deux types de modules dans le commerce. Sur le module standard, l'antenne est une piste de cuivre en zigzag imprimée sur la carte. La version nRF24L01+PA+LNA ajoute devant la même puce un circuit radio frontal : le PA (Power Amplifier, amplificateur de puissance) renforce le signal émis, et le LNA (Low Noise Amplifier, amplificateur à faible bruit) amplifie les signaux faibles reçus avant qu'ils n'atteignent la puce. Une antenne externe se visse sur un connecteur SMA. Les deux modules ont le même brochage et le même code, et ils communiquent sans problème entre eux ; la différence porte sur la portée et la consommation. Les valeurs ci-dessous sont approximatives et dépendent de l'environnement.

| Caractéristique | nRF24L01+ (antenne imprimée) | nRF24L01+PA+LNA |
|---|---|---|
| Antenne | Imprimée sur la carte | Antenne SMA externe |
| Puissance d'émission | Jusqu'à 0 dBm (1 mW) | Jusqu'à +20 dBm (100 mW) selon le modèle |
| Pic de courant en émission | Environ 12 mA | Jusqu'à 115 mA |
| Pic de courant en réception | Environ 13,5 mA | Jusqu'à 45 mA |
| Portée en champ libre (250 kbps) | 50–100 m | 800–1100 m |
| Portée en intérieur | 10–30 m, 1–2 murs | Plusieurs étages et quelques dizaines de mètres |
| Alimentation conseillée | Broche 3,3 V + condensateur de 10 µF | Régulateur 3,3 V séparé + condensateur |
Brochage du nRF24L01 et câblage sur Arduino
Le module possède 8 broches disposées en connecteur 2×4. La broche à la pastille carrée est la broche 1, c'est-à-dire GND ; VCC se trouve juste à côté. CE (Chip Enable) fait passer le module en mode écoute ou émission, et CSN (Chip Select Not) est mise à LOW pour dire « c'est à toi que je parle » sur le bus SPI. SCK, MOSI et MISO sont les lignes SPI classiques et doivent aller sur les broches SPI fixes de ta carte, tandis que CE et CSN peuvent aller sur n'importe quelles broches numériques. La broche IRQ est facultative : elle passe à LOW à l'arrivée d'un paquet ou à la fin d'un envoi et sert si tu veux travailler avec des interruptions. Pour comprendre le SPI, lis Qu'est-ce que le SPI, et pour le brochage complet de ta carte, utilise l'outil Pinout.
| Broche nRF24L01 | Rôle | Arduino Uno / Nano | Arduino Mega | ESP32 | Raspberry Pi Pico |
|---|---|---|---|---|---|
| 1 GND | Masse | GND | GND | GND | GND |
| 2 VCC | Alimentation (3,3 V) | 3.3V | 3.3V | 3V3 | 3V3(OUT) |
| 3 CE | Choix du mode | D9 | D9 | GPIO 4 | GP6 |
| 4 CSN | Sélection SPI | D10 | D10 | GPIO 5 | GP5 |
| 5 SCK | Horloge SPI | D13 | D52 | GPIO 18 | GP2 |
| 6 MOSI | Données de la carte vers le module | D11 | D51 | GPIO 23 | GP3 |
| 7 MISO | Données du module vers la carte | D12 | D50 | GPIO 19 | GP4 |
| 8 IRQ | Interruption (facultative) | Non branchée | Non branchée | Non branchée | Non branchée |
L'erreur la plus fréquente : l'alimentation et le condensateur de 10 µF
La plupart des problèmes avec le nRF24L01 ne viennent pas du code mais de l'alimentation. Au moment d'émettre, le module tire des pics de courant brefs et brutaux. Des fils longs et une source 3,3 V faible n'arrivent pas à suivre : la tension chute un instant, la puce envoie un paquet corrompu, rate des accusés de réception ou redémarre. D'après la documentation officielle, la broche 3,3 V de l'Arduino Uno fournit au maximum 50 mA ; c'est suffisant pour le module standard, mais pas pour la version PA+LNA qui monte jusqu'à 115 mA. Sur certains clones de Nano, le 3,3 V vient de la puce USB-série et il est encore plus faible. Les symptômes te diront sûrement quelque chose : write() réussit une fois sur deux, le module marche mieux quand tu le touches, ou la portée s'arrête à quelques mètres.
- Condensateur de 10 µF : Place un condensateur électrolytique de 10 µF entre les broches VCC et GND du module, le plus près possible. La patte longue (+) va sur VCC et le côté marqué d'une bande (−) sur GND. Des valeurs de 10 à 100 µF conviennent aussi ; tu peux lire pourquoi cela fonctionne dans Qu'est-ce qu'un condensateur.
- Condensateur céramique de 100 nF : Un petit condensateur céramique (marqué 104) en parallèle avec l'électrolytique filtre les parasites haute fréquence. Tu peux décoder le marquage des condensateurs avec l'outil Code condensateur.
- Adaptateur à support : Les cartes adaptatrices à 8 broches vendues pour le nRF24L01 intègrent déjà un régulateur AMS1117-3.3 et des condensateurs. Tu envoies 5 V sur le VCC de l'adaptateur et le module reçoit un 3,3 V propre.
- Régulateur séparé : Alimente la version PA+LNA non pas par la broche 3,3 V de l'Arduino, mais par un régulateur AMS1117-3.3 séparé branché sur le 5 V, et relie toutes les masses entre elles.
- Fils courts : Garde les fils de connexion sous 10 cm si possible ; des fils longs et mal enfoncés perturbent à la fois l'alimentation et les signaux SPI.

Installer la bibliothèque RF24
- Dans l'Arduino IDE, ouvre Outils > Gérer les bibliothèques ou clique sur l'icône des bibliothèques à gauche.
- Tape RF24 dans la recherche et installe la bibliothèque RF24 de TMRh20. RF24Network, RF24Mesh et RF24Ethernet sont des bibliothèques distinctes, inutiles pour débuter.
- Après l'installation, tu trouveras l'exemple GettingStarted dans Fichier > Exemples > RF24. Le code de cet article suit la syntaxe de RF24 à partir de la version 1.5.
- Si c'est la première fois que tu installes une bibliothèque, suis les étapes de Ajouter une bibliothèque Arduino.
Adresse, canal et débit : mettre deux modules d'accord
Pour que deux modules s'entendent, certains réglages doivent être strictement identiques des deux côtés. Pense à une conversation au talkie-walkie : si vous n'êtes pas sur la même fréquence (canal), au même rythme (débit) et avec le même indicatif (adresse), tu n'entends pas l'autre. L'adresse est un tableau de 5 octets, et le plus simple est de l'écrire dans le code sous forme de texte de 5 caractères comme "00001". Ne vois pas l'adresse comme l'identité d'un appareil, mais comme un chemin partagé entre deux appareils : l'émetteur dépose ses paquets sur ce chemin, et le récepteur qui l'écoute les récupère. La taille de paquet compte aussi : RF24 utilise par défaut des paquets de taille fixe, et si le récepteur n'attend pas la même taille que l'émetteur, il ne voit jamais le paquet.
| Réglage | Fonction RF24 | Valeur dans cet article | Remarque |
|---|---|---|---|
| Canal | setChannel(76) | 76 (2476 MHz) | 0–125 ; identique des deux côtés |
| Débit | setDataRate(RF24_250KBPS) | 250 kbps | Plus le débit baisse, plus la portée augmente |
| Adresse | stopListening(adresse) / openReadingPipe(1, adresse) | "00001" | Cible de l'émetteur = pipe du récepteur |
| Taille de paquet | setPayloadSize(sizeof(donnees)) | 32 octets (5 dans l'exemple du joystick) | En taille fixe, identique des deux côtés |
| Puissance d'émission | setPALevel(RF24_PA_LOW) | Faible | Pas besoin qu'elle corresponde ; fixe la portée |
| ACK automatique et CRC | Activés par défaut | CRC 16 bits | Si tu les désactives, fais-le des deux côtés |
Code de l'émetteur (TX)
Pour un premier essai, branche les deux Arduino sur deux ports USB et laisse 1 à 2 mètres entre les modules. Téléverse le code émetteur ci-dessous sur l'un d'eux. Chaque seconde, il envoie un message numéroté et affiche dans le moniteur série si le récepteur l'a acquitté. N'oublie pas de régler le moniteur série sur 115200 bauds.
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}Code du récepteur (RX)
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() envoie le paquet et renvoie true si le récepteur l'acquitte ; sans accusé, avec les réglages par défaut, il réessaie 15 fois à environ 1,5 ms d'intervalle puis renvoie false. Côté récepteur, openReadingPipe(1, address) règle le pipe 1 sur l'adresse de l'émetteur, startListening() passe le module en écoute, available() indique si un paquet attend et read() le copie dans ta variable. Si le moniteur série du récepteur affiche des lignes qui s'incrémentent comme « Gelen: Merhaba BlueGrays #0 », « #1 », « #2 », ta liaison fonctionne.
Portée : de 100 mètres à 1 kilomètre
Trois éléments déterminent la portée : la puissance d'émission, la sensibilité du récepteur et l'environnement. Plus le débit est bas, plus le récepteur peut décoder des signaux faibles ; la sensibilité est de −94 dBm à 250 kbps contre −82 dBm à 2 Mbps. Cet écart de 12 dB représente environ 4 fois plus de portée en champ libre. Les murs, les arbres, le corps humain et les surfaces métalliques atténuent fortement le signal 2,4 GHz, et les box Wi-Fi, les appareils Bluetooth et les fours à micro-ondes partagent la même bande.
| Débit | Sensibilité | Portée relative | Quand l'utiliser ? |
|---|---|---|---|
| 250 kbps | −94 dBm | La plus grande | Télécommande, capteurs éloignés |
| 1 Mbps | −85 dBm | Moyenne | Usage général (valeur par défaut de RF24) |
| 2 Mbps | −82 dBm | La plus courte | Haut débit, courte distance |
Le choix du canal compte aussi. Les canaux Wi-Fi les plus utilisés, 1, 6 et 11, occupent environ 2401 à 2473 MHz ; les canaux 74 à 83 du nRF24L01 se situent au-dessus et sont plus calmes tant qu'aucune box voisine n'utilise les canaux Wi-Fi 12 ou 13. En Europe, la bande 2,4 GHz libre de licence s'étend de 2400 à 2483,5 MHz : n'utilise donc pas les canaux au-delà de 83 ; les canaux 100 et plus que proposent certains exemples en ligne sont hors de cette bande. Pour gagner en portée, essaie ceci :
- Passe à 250 kbps : Une télécommande ou des données de capteur n'ont pas besoin de débit, et le faible débit fait gagner de la portée.
- Soigne d'abord l'alimentation, puis augmente la puissance : RF24_PA_MAX n'a de sens qu'avec un 3,3 V stable et un condensateur ; sur une alimentation faible, augmenter la puissance aggrave les choses.
- Place les antennes en hauteur et dans le même sens : 1 à 2 mètres au-dessus du sol et les deux antennes verticales dans la même orientation améliorent nettement la portée.
- Éloigne-le du métal : Ne mets pas le module dans un boîtier métallique ni juste à côté d'un gros bloc de batteries.
- Emballe la carte PA+LNA non blindée : Entourer un module PA+LNA sans capot métallique de ruban isolant puis de papier aluminium réduit les parasites qu'il se crée lui-même ; l'aluminium ne doit toucher aucune broche ni le connecteur d'antenne.
- N'émets jamais sans antenne : Faire fonctionner un module PA+LNA à pleine puissance sans antenne fatigue l'amplificateur de puissance.
Télécommande sans fil à joystick
Passons à un vrai projet : avec un joystick branché sur un Arduino, on va commander sans fil un servomoteur et une LED sur un second Arduino. Côté émetteur, la broche VRx du joystick va sur A0, VRy sur A1 et le bouton (SW) sur D2 ; les détails sont dans Module joystick. Côté récepteur, le fil de signal du servo va sur D3 et la LED sur D4 via une résistance de 220 Ω. Le nRF24L01 se branche des deux côtés comme dans le tableau plus haut.
La façon la plus propre d'envoyer plusieurs valeurs dans un seul paquet est une struct (structure). Un détail important ici : utilise des types de taille fixe comme int16_t et uint8_t. Un int fait 2 octets sur l'Arduino Uno mais 4 sur l'ESP32, et le compilateur de l'ESP32 ajoute en plus des octets de remplissage à la fin de la structure pour l'aligner. Si la même structure fait 5 octets sur l'Uno et 6 sur l'ESP32, les tailles de paquet ne correspondent plus et aucune donnée n'arrive. __attribute__((packed)) supprime ce remplissage et fixe la structure à 5 octets sur toutes les cartes. D'abord l'émetteur :
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}Puis le récepteur qui pilote le servo et la LED :
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}L'émetteur envoie 20 paquets par seconde ; à chaque paquet, le récepteur convertit l'axe X en 0–180 degrés et l'envoie au servo. La partie position de sécurité (failsafe) du récepteur est essentielle : si la pile de la télécommande se vide ou si tu sors de la portée, la dernière commande ne reste pas appliquée indéfiniment ; si aucun paquet n'arrive pendant 0,5 seconde, le servo revient au centre et la LED s'éteint. Si tu construis une voiture robot, arrête les moteurs au même endroit. Alimenter le servo par une source 5 V séparée plutôt que par la broche 5 V de l'Arduino évite aussi que ses pics de courant perturbent le nRF24L01. Branche l'axe Y sur un driver de moteurs L298N et tu obtiens une voiture robot sans fil ; pour le servo, vois Qu'est-ce qu'un servomoteur.
Communication bidirectionnelle et plusieurs émetteurs
Le nRF24L01 ne peut pas émettre et écouter en même temps, mais il existe un moyen simple d'obtenir une communication bidirectionnelle : l'ACK payload, c'est-à-dire des données glissées dans l'accusé de réception. Le récepteur prépare à l'avance avec writeAckPayload() les données à joindre au prochain accusé (la tension de la batterie ou une valeur de capteur, par exemple), et après un write() réussi, l'émetteur lit cette réponse avec available() et read(). Pour cela, les deux côtés doivent appeler enableDynamicPayloads() et enableAckPayload(). Pour plusieurs émetteurs, le récepteur dispose de 6 pipes : les pipes 0 et 1 reçoivent une adresse complète de 5 octets, tandis que les pipes 2 à 5 partagent le reste de l'adresse du pipe 1 et ne diffèrent que d'un octet. Dans RF24, cet octet est le premier caractère du tableau d'adresse ; c'est pourquoi on utilise des adresses comme "1Node", "2Node" et "3Node" qui ne changent que par le premier caractère. Pour des réseaux plus grands, il existe les bibliothèques RF24Network et RF24Mesh.
Brancher le nRF24L01 sur un ESP32
Sur l'ESP32, la bibliothèque RF24 fonctionne telle quelle, et radio.begin() utilise le bus VSPI par défaut : SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. GPIO 5 convient bien pour CSN et GPIO 4 pour CE. Le régulateur 3,3 V des cartes ESP32 DevKit est plus costaud que celui de l'Uno, mais ne fais pas l'impasse sur le condensateur de 10 µF. Sur des modèles comme l'ESP32-C3 ou l'ESP32-S3, les broches SPI par défaut sont différentes : consulte le brochage de ta carte. Comme le Wi-Fi de l'ESP32 fonctionne lui aussi à 2,4 GHz, choisis un canal nRF24L01 éloigné du canal Wi-Fi de ta box si tu utilises les deux en même temps. Le code ci-dessous lit sur l'ESP32 les paquets de l'émetteur à joystick ; avec la même structure, tu peux faire de l'ESP32 une passerelle qui transmet sur Internet les données des nœuds nRF24L01. Si tu découvres cette carte, commence par Qu'est-ce que l'ESP32.
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}Si tu ne relies que des cartes ESP32 entre elles, ESP-NOW, qui ne demande aucun module supplémentaire, est aussi une bonne option ; l'avantage du nRF24L01, c'est qu'il fonctionne aussi avec des cartes bon marché et économes comme l'Uno, le Nano ou le Pro Mini.
Le nRF24L01 avec le Raspberry Pi Pico et MicroPython
Pour MicroPython sur le Pico, on utilise le pilote nrf24l01.py du dépôt officiel micropython-lib. Tu peux copier le fichier sur le Pico avec Thonny ou l'installer depuis ton ordinateur avec mpremote mip install nrf24l01. Le câblage passe par SPI0 : SCK = GP2, MOSI = GP3, MISO = GP4, CSN = GP5, CE = GP6 et VCC = 3V3(OUT). Les valeurs par défaut du pilote diffèrent de celles de RF24 (canal 46, paquets de 16 octets) : pour dialoguer avec l'Arduino, on fixe donc explicitement le canal, le débit et la taille de paquet dans le code. Le code ci-dessous décode sur le Pico les paquets de l'émetteur à joystick :
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") transforme les 5 octets reçus en deux entiers signés de 16 bits et un octet ; le « < » initial indique l'ordre des octets little-endian, celui qu'utilisent l'AVR et l'ESP32. Si le module est introuvable, le pilote lève « nRF24L01+ Hardware not responding », l'équivalent MicroPython d'un begin() qui renvoie false sur Arduino. Si tu débutes avec le Pico, lis d'abord Qu'est-ce que le Raspberry Pi Pico.
radio.begin() renvoie false : la solution pas à pas
Si le moniteur série affiche « nRF24L01 bulunamadi » ou le message « radio hardware is not responding!! » des exemples RF24, l'Arduino n'arrive pas du tout à dialoguer avec le module en SPI. Dans ce cas, le problème vient presque toujours du câblage ou de l'alimentation, pas du code. Téléverse d'abord le programme de diagnostic ci-dessous ; il affiche tous les réglages du module sous une forme lisible.
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}- Vérifie MOSI et MISO : Ce sont les deux fils les plus souvent inversés. Sur l'Uno et le Nano, MOSI = D11, MISO = D12 et SCK = D13 ; sur le Mega, ce sont 51, 50 et 52.
- CE et CSN correspondent-ils au code ? Si tu as écrit RF24 radio(9, 10), CE va sur D9 et CSN sur D10. L'exemple GettingStarted de RF24 utilise les broches 7 et 8 ; si tu l'essaies tel quel, câble en conséquence.
- L'alimentation est-elle en 3,3 V ? Mesure au multimètre entre VCC et GND : tu dois lire 3,0 à 3,6 V. Si le module a déjà été branché sur 5 V, il est peut-être endommagé.
- Regarde la sortie de printPrettyDetails : Si les adresses et les registres affichent tous 0x00 ou 0xff, le bus SPI ne fonctionne pas. Si les valeurs semblent cohérentes mais que la liaison ne passe pas, le problème vient de la broche CE, des réglages ou de l'alimentation.
- Raccourcis les fils et baisse la vitesse SPI : Avec des fils longs ou mal enfoncés, écris RF24 radio(9, 10, 4000000) pour passer le SPI de 10 MHz par défaut à 4 MHz.
- Change de module : Si tout le reste est bon, essaie un module de rechange ; les lots bon marché peuvent en contenir un défectueux.
Aucune donnée ou données intermittentes : erreurs fréquentes
| Symptôme | Cause probable | Solution |
|---|---|---|
| begin() vaut true mais rien n'arrive au récepteur | Canal, débit, adresse ou taille de paquet différents des deux côtés | Compare les quatre réglages côte à côte dans les deux programmes |
| Aucune donnée de l'Uno vers l'ESP32 | Taille de struct différente (5 et 6 octets) | Utilise des types de taille fixe et __attribute__((packed)) |
| write() vaut false mais le récepteur reçoit les données | L'accusé du récepteur n'atteint pas l'émetteur, souvent à cause de l'alimentation du récepteur | Ajoute aussi un condensateur de 10 µF sur le module récepteur |
| Données vides ou incohérentes en permanence | Fil SPI mal enfoncé ou MISO coupé | Change les fils et baisse le SPI à 4 MHz |
| Ne marche pas côte à côte, marche une fois éloigné | Le récepteur sature à pleine puissance | Utilise setPALevel(RF24_PA_LOW) ou RF24_PA_MIN |
| Marche mieux quand on le touche | Alimentation instable ou PA+LNA non blindé | Condensateur, régulateur séparé et blindage en aluminium |
| La liaison coupe au bout de quelques mètres | Débit de 2 Mbps, alimentation faible ou parasites Wi-Fi | 250 kbps, alimentation propre, canal entre 74 et 83 |
Idées de projets avec le nRF24L01
- Télécommande sans fil pour voiture robot : Pilote une voiture robot à plusieurs dizaines de mètres avec une télécommande à deux joysticks.
- Station de capteurs pour le jardin : Envoie les mesures d'un capteur d'humidité du sol et la température depuis un émetteur sur piles jusqu'à un écran dans la maison. Avec radio.powerDown(), le module consomme environ 900 nA en veille ; tu peux estimer l'autonomie avec l'outil Autonomie de batterie.
- Alarme sans fil de porte et de mouvement : Déclenche un buzzer sur la centrale quand un capteur PIR ou un interrupteur reed se déclenche.
- Réseau de température multi-pièces : Rassemble sur un seul récepteur les mesures des capteurs de six pièces grâce aux six pipes.
- Passerelle ESP32 : Transmets avec un ESP32 les données des nœuds nRF24L01 vers Internet, ton téléphone ou un tableau de bord.
- Tableau de score sans fil : Mets à jour un tableau à afficheurs 7 segments dans un gymnase avec des télécommandes à boutons.
Malgré son petit prix, le nRF24L01 offre plus de portée, moins de latence et la prise en charge de plusieurs appareils que le Bluetooth ; il demande seulement une alimentation 3,3 V propre et des réglages identiques des deux côtés. Pour piloter depuis un téléphone, le module Bluetooth HC-05 conviendra mieux, et pour des kilomètres de portée, LoRa ; tu trouveras une comparaison des options dans Modules de communication sans fil pour Arduino. Dans l'application BlueGrays, tu trouveras des projets comme la communication entre deux Arduino, la commande d'un servo et d'une LED au joystick ou une voiture télécommandée, pas à pas, avec schémas de câblage et code prêt à l'emploi.
Questions fréquentes
Quelle est la portée du nRF24L01 ?
Le nRF24L01+ standard à antenne imprimée porte à environ 50–100 mètres en champ libre à 250 kbps, et à 10–30 mètres en intérieur selon les murs. La version nRF24L01+PA+LNA à antenne externe peut atteindre 800–1100 mètres en terrain dégagé et sans obstacle. Pour y parvenir, il faut une alimentation 3,3 V propre, un condensateur de 10 µF et un débit faible.
Le nRF24L01 fonctionne-t-il en 5V ?
Non : la broche VCC fonctionne entre 1,9 et 3,6 V, et le 5 V peut détruire la puce. En revanche, les broches d'entrée CE, CSN, SCK et MOSI tolèrent le 5 V et peuvent donc être reliées aux broches SPI d'un Arduino Uno sans convertisseur de niveau. Pour alimenter le module en 5 V, utilise un adaptateur à support avec régulateur AMS1117-3.3.
Pourquoi l'erreur « radio hardware is not responding » apparaît-elle ?
Ce message s'affiche quand radio.begin() renvoie false et signifie que l'Arduino ne parvient pas à dialoguer avec le module en SPI. Les causes les plus fréquentes sont MOSI et MISO inversés, des broches CE et CSN différentes de celles du code, une alimentation faible ou en 5 V et des fils mal enfoncés. Vérifie le câblage et consulte la sortie de printPrettyDetails() pour cerner le problème.
nRF24L01 ou Bluetooth HC-05 : lequel choisir ?
Si tu as besoin entre plusieurs Arduino d'une longue portée, d'une faible latence et de plusieurs appareils, le nRF24L01 est le meilleur choix. Pour piloter depuis un téléphone, prends un module Bluetooth comme le HC-05 ou un ESP32, car les smartphones ne parlent pas le protocole du nRF24L01. Le HC-05 porte en général à une dizaine de mètres, alors que le nRF24L01 va beaucoup plus loin pour un prix comparable.
Combien d'émetteurs un récepteur nRF24L01 peut-il écouter ?
Un récepteur peut écouter 6 pipes en même temps, donc collecter directement les données de 6 émetteurs. Les pipes 2 à 5 partagent le corps de l'adresse du pipe 1 et ne diffèrent que d'un octet. Pour plus de nœuds, tu peux interroger les émetteurs à tour de rôle ou construire des réseaux bien plus grands avec les bibliothèques RF24Network et RF24Mesh.
Le nRF24L01 peut-il se connecter à un téléphone ?
Pas directement : même s'il fonctionne dans la même bande des 2,4 GHz, le nRF24L01 n'utilise ni le protocole Wi-Fi ni le Bluetooth. Pour un pilotage au téléphone, place un ESP32 au centre de ton réseau nRF24L01 et transmets les données au téléphone en Wi-Fi ou en Bluetooth. Ainsi, les nœuds distants parlent nRF24L01 et le téléphone dialogue avec l'ESP32.
Projets à réaliser après cet article
Voir tous les projets
Communication unidirectionnelle entre 2 Arduino
Tu fais discuter deux Arduino par un seul fil : appuie sur le bouton de l'un et la LED de l'autre s'allume, appuie encore et elle s'éteint. La carte qui envoie signale l'appui par un court message, et

Communication bidirectionnelle entre 2 Arduino
Deux Arduino reliés par des fils se parlent : appuie sur le bouton de l'un et la lumière de l'autre s'allume, appuie encore et elle s'éteint. Les deux cartes ont le même programme, donc chacune envoie

Contrôle de LED avec un joystick
Pousse à fond le petit levier du joystick dans une direction, et la LED de cette direction s'allume : il y a quatre couleurs différentes pour droite, gauche, haut et bas. Quand tu lâches le levier, il

Servocommande avec joystick
Pilote deux moteurs avec un joystick, comme si tu orientais une caméra de surveillance. Pousse le manche à gauche ou à droite et le servomoteur du bas tourne doucement, vers le haut ou le bas et celui

Voiture contrôlée par Bluetooth avec L298N
Transforme ton téléphone en télécommande et pilote ta propre voiture robot. L'Arduino reçoit, via un module Bluetooth, les ordres d'une appli de télécommande sur ton téléphone et fait tourner les roue

Contrôler une LED depuis un téléphone via Bluetooth
Une petite répétition pour allumer et éteindre les lumières de ta chambre depuis ton téléphone. Le module Bluetooth transmet à l'Arduino les lettres envoyées par ton téléphone ; une lettre allume la L

Allumer et éteindre des LED avec un récepteur IR et une télécommande
Comme commander trois lampes sans quitter ton fauteuil : les touches 1, 2 et 3 de la télécommande allument les LED bleue, rouge et verte, et les touches 4, 5 et 6 les éteignent dans le même ordre. La

Télécommande universelle ESP32 IR (récepteur IR + télécommande + 3 LED + buzzer + écran OLED)
Avec l'ESP32, tu peux lire les signaux d'une télécommande IR standard et contrôler ton propre appareil ! Dans ce projet, nous capturons les signaux d'une télécommande IR à 20 touches à l'aide d'un récepteur infrarouge (protocole NEC 38 kHz). Nous avons défini une action différente pour chaque touche : les touches 1/2/3 activent ou désactivent trois LED distinctes, la touche PWR les éteint toutes, et les chiffres 4 à 9 affichent des informations spécifiques sur l'écran OLED. Sur l'écran OLED SSD1
Autres articles
Application BlueGrays
Réalise ce montage pas à pas sur ton téléphone
Schéma, code et liste des composants sur un seul écran. Plus de 200 projets Arduino, ESP32 et Pico à réaliser.
Scanne avec ton téléphone
Pointe l’appareil photo vers le code : la boutique d’applications de ton téléphone s’ouvre.
ou ouvre la boutique

