Maîtriser le nRF24L01 : Communication sans fil, Intégration Arduino, Circuits et Guide de Code
Dans ce tutoriel, nous allons apprendre comment faire de la communication sans fil entre deux cartes Arduino en utilisant les modules transcepteurs nRF24L01. Le module nRF24L01 est un choix très populaire pour la communication sans fil avec Arduino.
J'ai déjà utilisé ce module pour de nombreux projets Arduino et vous pouvez en consulter certains ici :
- Émetteur RC Arduino DIY
- Avion RC Arduino | 100% DIY
- Hovercraft RC Arduino DIY
- Projet Station Météo Sans Fil Arduino
Vous pouvez regarder la vidéo suivante ou lire le tutoriel écrit ci-dessous. Il inclut tout ce qu'il faut savoir sur le module transcepteur nRF24L01, tel que le brochage du module, le principe de fonctionnement, le câblage et plusieurs exemples de code.
Aperçu
Pour expliquer la communication sans fil, nous ferons deux exemples : le premier sera l'envoi d'un simple message « Hello World » d'un Arduino à un autre, et dans le second exemple nous aurons une communication bidirectionnelle entre les cartes Arduino, où en utilisant le Joystick sur le premier Arduino nous contrôlerons le servomoteur sur le second Arduino, et vice versa, en utilisant le bouton poussoir sur le second Arduino nous contrôlerons la LED sur le premier Arduino.

Module Transcepteur nRF24L01
Examinons de plus près le module transcepteur NRF24L01. Il utilise la bande 2,4 GHz et peut fonctionner avec des débits de 250 kbps jusqu'à 2 Mbps. S'il est utilisé en espace ouvert et avec un débit plus bas, sa portée peut atteindre jusqu'à 100 mètres.

Voici les spécifications complètes :
| Plage de fréquence | 2,4 – 2,5 GHz bande ISM |
| Débits de données | 250 Kbps / 1 Mbps / 2 Mbps |
| Puissance de sortie max | 0 dBm |
| Tension de fonctionnement | 1,9 – 3,6 V |
| Courant de fonctionnement max | 12,3 mA |
| Courant en veille | 22 µA |
| Entrées logiques | Tolérant 5 V |
| Portée de communication | 100 m (espace ouvert) |
Comment ça fonctionne
Le module peut utiliser 125 canaux différents ce qui donne la possibilité d'avoir un réseau de 125 modems fonctionnant indépendamment au même endroit. Chaque canal peut avoir jusqu'à 6 adresses, ou chaque unité peut communiquer avec jusqu'à 6 autres unités en même temps.

La consommation d'énergie de ce module est d'environ 12 mA pendant la transmission, ce qui est même inférieur à une seule LED. La tension de fonctionnement du module est de 1,9 à 3,6 V, mais la bonne chose est que les autres broches tolèrent la logique 5 V, donc nous pouvons facilement le connecter à un Arduino sans utiliser de convertisseurs de niveau logique.

Trois de ces broches sont pour la communication SPI et doivent être connectées aux broches SPI de l'Arduino, mais notez que chaque carte Arduino a des broches SPI différentes. Les broches CSN et CE peuvent être connectées à n'importe quelle broche digitale de la carte Arduino et sont utilisées pour mettre le module en mode veille ou actif, ainsi que pour basculer entre le mode transmission ou commande. La dernière broche est une broche d'interruption qui n'a pas à être utilisée.
Variations du module
Il existe plusieurs variations des modules NRF24L01. La plus populaire est celle avec antenne intégrée. Cela rend le module plus compact, mais d'un autre côté, réduit la portée de transmission à une distance d'environ 100 mètres.

La seconde variation, au lieu d'antenne intégrée, a un connecteur SMA auquel on peut attacher une antenne duck pour une meilleure portée de transmission.
La troisième variation montrée ici, en plus de l'antenne duck, a une puce RFX2401C qui inclut PA (Amplificateur de Puissance) et LNA (Amplificateur Faible Bruit). Cela amplifie le signal NRF24L01 et permet une portée de transmission encore meilleure jusqu'à 1000 mètres en espace ouvert.
Brochage du module nRF24L01
Voici un regard détaillé sur le brochage du NRF24L01, ainsi que le module NRF24L01+ PA/LNA.

Les deux modules, le NRF24L01 et le NRF24L01+ PA/LNA ont le même brochage, donc nous pouvons les connecter dans notre circuit de la même façon.
Comment connecter le nRF24L01 à l'Arduino
Voici comment nous devons connecter les modules NRF24L01 aux cartes Arduino.

Comme je l'ai déjà mentionné, chaque carte Arduino a des broches SPI différentes, gardez cela à l'esprit quand vous connectez les modules à votre carte Arduino.
| Arduino | SCK | MISO | MOSI | SS |
| Uno | 13 | 12 | 11 | 10 |
| Nano | 13 | 12 | 11 | 10 |
| Mega | 52 | 50 | 51 | 53 |
Vous pouvez obtenir les composants nécessaires pour ce tutoriel Arduino depuis les liens ci-dessous :
- Module Transcepteur NRF24L01………
- Carte Arduino ………………………………
- Plaque d'essai et Fils de liaison …………
Code Arduino et nRF24L01
Une fois que nous connectons les modules NRF24L01 aux cartes Arduino, nous sommes prêts à faire les codes pour l'émetteur et le récepteur.
Premièrement, nous devons télécharger et installer la bibliothèque RF24 qui rend la programmation moins difficile. Nous pouvons aussi installer cette bibliothèque directement depuis le Gestionnaire de Bibliothèques de l'IDE Arduino. Cherchez juste « rf24 » et trouvez et installez celle par « TMRh20, Avamander ».
Voici les deux codes pour la communication sans fil et ci-dessous leur description.
Code Émetteur
/*
* 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);
}
Code Récepteur
/*
* 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);
}
}
Description du code
Nous devons inclure la bibliothèque SPI de base et la bibliothèque RF24 nouvellement installée et créer un objet RF24. Les deux arguments ici sont les broches CSN et CE.
RF24 radio(7, 8); // CE, CSN
Ensuite, nous devons créer un tableau d'octets qui représentera l'adresse, ou le soi-disant tuyau à travers lequel les deux modules communiqueront.
const byte address[6] = "00001";
Nous pouvons changer la valeur de cette adresse à n'importe quelle chaîne de 5 lettres et cela permet de choisir à quel récepteur nous parlerons, donc dans notre cas nous aurons la même adresse à la fois au récepteur et à l'émetteur.
Dans la section setup, nous devons initialiser l'objet radio et en utilisant la fonction radio.openWritingPipe() nous définissons l'adresse du récepteur vers lequel nous enverrons les données, la chaîne de 5 lettres que nous avons définie précédemment.
radio.openWritingPipe(address);
De l'autre côté, au récepteur, en utilisant la fonction radio.openReadingPipe() nous définissons la même adresse et ainsi nous activons la communication entre les deux modules.
radio.openReadingPipe(0, address);
Ensuite, en utilisant la fonction radio.setPALevel() nous définissons le niveau de l'amplificateur de puissance, dans notre cas je le mettrai au minimum car mes modules sont très proches l'un de l'autre.
radio.setPALevel(RF24_PA_MIN);
Notez que si vous utilisez un niveau plus élevé, il est recommandé d'utiliser des condensateurs de découplage entre GND et 3,3 V des modules pour qu'ils aient une tension plus stable pendant le fonctionnement.
Ensuite, nous avons la fonction radio.stopListening() qui met le module en mode émetteur, et de l'autre côté, nous avons la fonction radio.startListening() qui met le module en mode récepteur.
// à l'Émetteur
radio.stopListening();
// au Récepteur
radio.startListening();
Dans la section loop, à l'émetteur, nous créons un tableau de caractères auquel nous assignons le message « Hello World ». En utilisant la fonction radio.write() nous enverrons ce message au récepteur. Le premier argument ici est la variable que nous voulons envoyer.
void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
En utilisant le « & » avant le nom de la variable, nous définissons en fait un pointeur vers la variable qui stocke les données que nous voulons envoyer et en utilisant le second argument nous définissons le nombre d'octets que nous voulons prendre de cette variable. Dans ce cas, la fonction sizeof() prend tous les octets de la chaîne « text ». À la fin du programme, nous ajouterons un délai d'une seconde.
En utilisant la fonction radio.write(), nous pouvons envoyer un maximum de 32 octets à la fois.
De l'autre côté, au récepteur, dans la section loop, en utilisant la fonction radio.available() nous vérifions s'il y a des données à recevoir. Si c'est vrai, d'abord nous créons un tableau de 32 éléments, appelé « text », dans lequel nous sauvegarderons les données entrantes.
void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
En utilisant la fonction radio.read() nous lisons et stockons les données dans la variable « text ». À la fin, nous affichons juste le texte sur le moniteur série. Donc une fois que nous téléchargeons les deux programmes, nous pouvons lancer le moniteur série au récepteur et nous remarquerons que le message « Hello World » s'imprime chaque seconde.
Dépannage
Il vaut la peine de noter que le bruit d'alimentation est l'un des problèmes les plus courants que les gens rencontrent quand ils essaient de faire une communication réussie avec les modules NRF24L01. Généralement, les circuits RF ou signaux de radiofréquence sont sensibles au bruit d'alimentation. Par conséquent, c'est toujours une bonne idée d'inclure un condensateur de découplage sur la ligne d'alimentation. Le condensateur peut être n'importe quoi de 10 µF à 100 µF.

Un autre problème courant est que la broche 3,3 V des cartes Arduino ne peut pas toujours fournir assez de puissance au module NRF24L01. Donc, alimenter le module avec une source d'alimentation externe est aussi une bonne idée.
Communication sans fil bidirectionnelle avec deux NRF24L01 et Arduino
Voyons le second exemple, une communication sans fil bidirectionnelle entre deux cartes Arduino. Voici le schéma de circuit :

Vous pouvez obtenir les composants nécessaires pour cet exemple depuis les liens ci-dessous :
- Module Transcepteur NRF24L01…………
- Carte Arduino………………………………….
- Module Joystick ……………………………….
- Servomoteur …………………………………….
- Bouton poussoir ……………………………………..
- LED …………………………………………………
Code Source nRF24L01
Voici les deux codes et leur description ci-dessous.
Code Émetteur
/*
* 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);
}
}
Code Récepteur
/*
* 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));
}
}
Ce qui est différent ici de l'exemple précédent, c'est que nous devons créer deux tuyaux ou adresses pour la communication bidirectionnelle.
const byte addresses[][6] = {"00001", "00002"};
Dans la section setup, nous devons définir les deux tuyaux, et notez que l'adresse d'écriture au premier Arduino doit être l'adresse de lecture au second Arduino, et vice versa, l'adresse de lecture au premier Arduino doit être l'adresse d'écriture au second Arduino.
// à l'Émetteur
radio.openWritingPipe(addresses[1]); // 00002
radio.openReadingPipe(1, addresses[0]); // 00001
// au Récepteur
radio.openWritingPipe(addresses[0]); // 00001
radio.openReadingPipe(1, addresses[1]); // 00002
Dans la section loop, en utilisant la fonction radio.stopListening() nous mettons le premier Arduino en émetteur, lisons et mappons la valeur du Joystick de 0 à 180, et en utilisant la fonction radio.write() envoyons les données au récepteur.
radio.stopListening();
int potValue = analogRead(A0);
int angleValue = map(potValue, 0, 1023, 0, 180);
radio.write(&angleValue, sizeof(angleValue));
De l'autre côté, en utilisant la fonction radio.startListening() nous mettons le second Arduino en récepteur et nous vérifions s'il y a des données disponibles. Tant qu'il y a des données disponibles, nous les lirons, les sauvegarderons dans la variable « angleV » et puis utiliserons cette valeur pour faire tourner le servomoteur.
radio.startListening();
if ( radio.available()) {
while (radio.available()) {
int angleV = 0;
radio.read(&angleV, sizeof(angleV));
myServo.write(angleV);
}
Ensuite, à l'émetteur, nous mettons le premier Arduino en récepteur et avec une boucle « while » vide nous attendons que le second Arduino envoie les données, et ce sont les données pour l'état du bouton poussoir s'il est pressé ou non. Si le bouton est pressé, la LED s'allumera. Donc ce processus se répète constamment et les deux cartes Arduino envoient et reçoivent constamment des données.
Exemple 3 – Envoi de plusieurs variables dans un seul paquet
Regardons un exemple de code de plus utilisant les modules NRF24L01. Tout reste le même que dans les exemples précédents, sauf pour la façon dont nous structurons et envoyons les données.
Code Émetteur
/* 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);
}
Donc, nous pouvons créer une structure qui est en fait une collection de divers types de variables.
// 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
Nous devrions garder à l'esprit que la taille maximale de cette structure de données peut être de 32 octets. Ici, nous voyons que j'ai inclus trois variables de type byte, une variable entière (4 octets), une variable float (4 octets) et une String contenant quatre caractères (4 octets). Cela fait un total de 15 octets.
Code Récepteur
/* 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);
}
Du côté récepteur, nous devons définir la même structure de données pour être capable de recevoir les données entrantes. Pour tester si la communication sans fil fonctionne correctement, j'ai imprimé chaque variable sur le moniteur série.

Conclusion
Le module NRF24L01 est une excellente option pour quand vous avez besoin de communication sans fil pour votre projet Arduino. J'ai déjà utilisé ce module dans beaucoup de mes projets Arduino.
Ici, je listerai tous mes projets dans lesquels j'ai utilisé ces modules.
- Voiture Robot Arduino Contrôle Sans Fil utilisant HC-05 Bluetooth, NRF24L01 et Modules Transcepteurs HC-12
- Projet Station Météo Sans Fil Arduino
- Émetteur RC Arduino DIY
- Robot Hexapode Fourmi Arduino
- Hovercraft RC Arduino DIY
- Robot Roues Mecanum Arduino
- Récepteur RC Arduino DIY pour Modèles RC et Projets Arduino
- Avion RC Arduino | 100% DIY
Chacun de ces projets/tutoriels a une explication détaillée sur comment utiliser le module NRF24L01, incluant diagrammes de circuits, implémentation de code améliorée pour une meilleure communication, etc.
Mon projet préféré est cet émetteur RC Arduino conçu sur mesure. C'est en fait une manette RC 14 canaux qui peut être utilisée pour contrôler à peu près n'importe quel projet Arduino.

C'est tout pour ce tutoriel, j'espère que vous l'avez apprécié et avez appris quelque chose de nouveau. Comme toujours, n'hésitez pas à poser toute question dans la section commentaires ci-dessous.
Processus de fabrication
- Mesurer la qualité de l'air avec OpenSensors : Guide Arduino et Python
- Construire une télécommande IR universelle avec Arduino : Guide étape par étape
- Construisez un Stadiomètre Numérique : Suivez la Croissance avec Arduino et Capteur Laser
- JX Wave Generator – Générateur DDS compatible Arduino avec affichage OLED
- Construisez un skateboard VR DIY avec Arduino, Google Cardboard et Bluetooth
- Connecter un module GPS NEO‑6M à l'Arduino Mega : Guide pas à pas
- Utiliser une thermistance facilement : Guide étape par étape Arduino
- Générer des Sons Musicaux avec Arduino : Guide Pas à Pas
- Interfaces cerveau-ordinateur : reconnecter la pensée à l'action