Radio Link LabRadio
Module radio nRF24L01+
Fais parler deux cartes en 2,4 GHz : câblage, adresses, acquittements et retransmissions. Le configurateur écrit le code des deux côtés, et le simulateur montre ce que la distance fait à la liaison.
En bref
| Puce | Nordic nRF24L01+, émetteur-récepteur 2,4 GHz (bande ISM) |
|---|---|
| Débits | 250 kbit/s, 1 Mbit/s ou 2 Mbit/s |
| Canaux | 126 canaux de 1 MHz (0 à 125), fréquence = 2400 + canal MHz |
| Interface | SPI, plus deux broches : CE (active l’émission ou la réception) et IRQ (optionnelle) |
| Alimentation | 1,9 à 3,6 V : uniquement du 3,3 V, jamais du 5 V |
| Entrées logiques | tolérantes au 5 V (l’alimentation, elle, ne l’est pas) |
| Paquets | payload de 1 à 32 octets, acquittement (ACK) et retransmission automatiques |
| Réception | 6 « pipes » : jusqu’à 6 émetteurs distincts sur un même récepteur |
Les modules PA+LNA (antenne externe) portent plus loin, mais consomment plus au moment d’émettre et demandent une alimentation bien découplée. Les nRF24L01 sans « + » ne font pas 250 kbit/s.
Câblage
| Broche nRF24 | ESP32 (30 broches) | Arduino Uno / Nano |
|---|---|---|
| VCC | 3V3 | 3,3 V (jamais 5 V) |
| GND | GND | GND |
| CE | GPIO 4 | D9 |
| CSN | GPIO 5 | D10 |
| SCK | GPIO 18 | D13 |
| MOSI | GPIO 23 | D11 |
| MISO | GPIO 19 | D12 |
| IRQ | libre | libre |
- CE et CSN sont au choix : le code doit seulement correspondre à votre câblage.
- Le brochage du module a 2 × 4 broches : GND et VCC sont d’un côté, repère le carré du connecteur ou la sérigraphie avant de brancher.
- Un adaptateur avec régulateur 3,3 V (sérigraphié « 5V ») permet d’alimenter le module depuis 5 V et stabilise l’alimentation.
SPI
Le nRF24 est un périphérique SPI classique : SCK (horloge), MOSI (données vers le module), MISO (données du module) et CSN (sélection, active à l’état bas). La bibliothèque RF24 utilise le bus SPI par défaut de la carte : sur ESP32, SCK 18, MISO 19 et MOSI 23. CE n’est pas du SPI : à l’état haut, le module émet ou écoute selon son mode.
Si radio.begin() renvoie false, le module ne répond pas sur le SPI : c’est presque toujours un problème de câblage ou d’alimentation.
Alimentation
C’est la première cause de panne. La radio demande des pointes de courant brèves quand elle émet, et une alimentation bruitée provoque des pertes de paquets ou des échecs à l’initialisation.
- Ajoute un condensateur de 10 à 100 µF directement entre VCC et GND, au plus près du module.
- La sortie 3,3 V d’une Arduino Uno est trop faible pour un module PA+LNA : utilise l’adaptateur avec régulateur, ou un régulateur 3,3 V séparé.
- Garde les fils d’alimentation courts et éloigne l’antenne des masses métalliques et des servos.
Émetteur
Un émetteur définit l’adresse d’écriture, passe en mode « émission » avec stopListening(), puis appelle write(). Cette fonction renvoie true si un ACK est revenu (quand l’acquittement est activé).
/*
* Émetteur nRF24L01+ — Kaihatsu Lab
* Envoie un compteur et une valeur toutes les secondes.
* Bibliothèque : RF24 (TMRh20), à installer depuis le gestionnaire de bibliothèques.
*
* ESP32 : SCK 18, MISO 19, MOSI 23 (VSPI par défaut). CE et CSN sont au choix.
*/
#include <SPI.h>
#include <RF24.h>
const uint8_t PIN_CE = 4;
const uint8_t PIN_CSN = 5;
RF24 radio(PIN_CE, PIN_CSN);
const byte ADDRESS[6] = "00001"; // 5 caractères : identique côté récepteur
struct Payload { // 8 octets, identique côté récepteur
uint32_t counter;
float value;
};
Payload data = {0, 0};
void setup() {
Serial.begin(115200);
if (!radio.begin()) {
Serial.println(F("nRF24 introuvable : verifie le cablage et l'alimentation 3,3 V"));
while (true) delay(1000);
}
radio.setChannel(76); // 2476 MHz
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.setAutoAck(true);
radio.setRetries(5, 15); // attend 1 500 µs entre les essais, 15 essais au plus
radio.setPayloadSize(sizeof(Payload));
radio.openWritingPipe(ADDRESS);
radio.stopListening(); // mode émetteur
}
void loop() {
data.counter++;
data.value = 20.0 + (data.counter % 10) * 0.1;
bool ok = radio.write(&data, sizeof(data)); // true si l'ACK est revenu
Serial.print(F("Paquet "));
Serial.print(data.counter);
Serial.println(ok ? F(" : recu (ACK)") : F(" : pas d'ACK"));
delay(1000);
}
Récepteur
Le récepteur ouvre un pipe de lecture avec l’adresse de l’émetteur, passe en écoute avec startListening() et lit chaque paquet avec available() puis read().
/*
* Récepteur nRF24L01+ — Kaihatsu Lab
* Affiche chaque paquet reçu. Mêmes réglages que l'émetteur.
* Bibliothèque : RF24 (TMRh20).
*/
#include <SPI.h>
#include <RF24.h>
const uint8_t PIN_CE = 4;
const uint8_t PIN_CSN = 5;
RF24 radio(PIN_CE, PIN_CSN);
const byte ADDRESS[6] = "00001";
struct Payload {
uint32_t counter;
float value;
};
Payload data;
void setup() {
Serial.begin(115200);
if (!radio.begin()) {
Serial.println(F("nRF24 introuvable : verifie le cablage et l'alimentation 3,3 V"));
while (true) delay(1000);
}
radio.setChannel(76);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.setAutoAck(true);
radio.setPayloadSize(sizeof(Payload));
radio.openReadingPipe(1, ADDRESS); // pipe 1 : adresse de l'émetteur
radio.startListening(); // mode récepteur
}
void loop() {
if (radio.available()) {
radio.read(&data, sizeof(data));
Serial.print(F("Paquet "));
Serial.print(data.counter);
Serial.print(F(" : "));
Serial.println(data.value, 1);
}
}
Les réglages de canal, débit, puissance, acquittement et taille de payload doivent être identiques des deux côtés.
Adresses
Une adresse est une suite de 3 à 5 octets (5 par défaut). Le récepteur n’accepte un paquet que si l’adresse correspond à l’un de ses pipes de lecture. En C++ Arduino, const byte ADDRESS[6] = "00001"; donne les 5 octets « 0 », « 0 », « 0 », « 0 », « 1 » (plus le zéro de fin, ignoré).
- Évite les adresses très régulières (
0x00…ou0xAA…) : elles ressemblent trop au bruit ambiant. - Deux montages voisins avec la même adresse et le même canal reçoivent les paquets l’un de l’autre : choisis des adresses différentes.
Pipes
| Pipe | Rôle | Adresse |
|---|---|---|
| 0 | Reçoit aussi les ACK quand le module émet (la bibliothèque le règle avec openWritingPipe) | adresse de 5 octets libre |
| 1 | Pipe de réception | adresse de 5 octets libre |
| 2 à 5 | Pipes de réception | mêmes 4 octets de poids fort que le pipe 1 ; seul le dernier octet change |
Avec un seul récepteur et jusqu’à cinq capteurs, donne à chaque capteur un dernier octet différent et ouvre un pipe par capteur : radio.openReadingPipe(1, addr1), radio.openReadingPipe(2, addr2), etc. radio.available(&pipe) vous dit quel pipe a reçu le paquet.
ACK
Avec setAutoAck(true) (réglage par défaut), le récepteur renvoie automatiquement un accusé de réception. L’émetteur sait ainsi si son paquet est arrivé. Sans ACK, l’émission part « dans le vide » : plus rapide, mais vous ne savez rien du résultat.
- Un ACK peut transporter des données :
enableAckPayload()côté émetteur et récepteur, puiswriteAckPayload()côté récepteur. Cette fonction demande les payloads dynamiques. - L’ACK confirme la réception, pas que votre programme a traité le paquet.
Retransmission
Quand l’ACK n’arrive pas, l’émetteur réessaie tout seul. setRetries(delai, nombre) règle deux choses :
| Paramètre | Valeurs | Effet |
|---|---|---|
| delai | 0 à 15 | temps d’attente entre deux essais : (delai + 1) × 250 µs, soit de 250 µs à 4 000 µs |
| nombre | 0 à 15 | nombre de retransmissions après le premier essai |
Le délai doit laisser le temps à l’ACK de revenir : en 250 kbit/s, ne descendez pas sous environ 500 µs (valeur 1), et prenez davantage si l’ACK contient des données. Plus vous autorisez d’essais, plus la liaison est fiable, mais plus write() peut durer longtemps quand le récepteur est absent.
Payload
Un paquet transporte de 1 à 32 octets. Deux modes :
- Taille fixe :
setPayloadSize(n), la même des deux côtés. Simple et rapide. - Taille dynamique :
enableDynamicPayloads(). Chaque paquet a sa taille, lisible avecgetDynamicPayloadSize(). Nécessaire pour les ACK avec données.
Le plus propre est de décrire les données dans une struct partagée par l’émetteur et le récepteur, comme dans les exemples : write(&data, sizeof(data)). Deux ESP32 utilisent le même agencement mémoire ; entre cartes de types différents (ESP32 et Uno, par exemple), la taille de int et l’alignement changent : préfère des types de taille fixe (uint8_t, int16_t, uint32_t).
Canal
Le canal c correspond à la fréquence 2400 + c MHz. En Europe, la bande ISM 2,4 GHz s’arrête à 2483,5 MHz : reste sur les canaux 0 à 83. Les canaux 84 à 125, accessibles techniquement, sortent de la bande autorisée.
| Canal Wi-Fi | Fréquence centrale | Recouvre à peu près |
|---|---|---|
| 1 | 2412 MHz | canaux nRF 1 à 23 |
| 6 | 2437 MHz | canaux nRF 26 à 48 |
| 11 | 2462 MHz | canaux nRF 51 à 73 |
Choisis un canal loin de votre Wi-Fi. Les canaux 74 à 83 sont souvent plus calmes, sauf si un point d’accès utilise les canaux Wi-Fi 12 ou 13.
Débit
| Débit | Sensibilité | Bande occupée | À retenir |
|---|---|---|---|
| 250 kbit/s | environ −94 dBm | 1 MHz | la meilleure portée (seulement sur nRF24L01+) |
| 1 Mbit/s | environ −85 dBm | 1 MHz | bon compromis (valeur par défaut) |
| 2 Mbit/s | environ −82 dBm | 2 MHz | le plus rapide, la portée la plus courte ; occupe deux canaux : espace-les d’au moins 2 |
Un paquet de 32 octets dure de l’ordre de 0,16 ms à 2 Mbit/s, 0,3 ms à 1 Mbit/s et 1,3 ms à 250 kbit/s. Un débit plus bas allonge le temps d’antenne mais gagne environ 9 dB de sensibilité, soit à peu près trois fois plus de portée en champ libre.
Puissance
| Réglage | Puissance de la puce |
|---|---|
| RF24_PA_MIN | −18 dBm |
| RF24_PA_LOW | −12 dBm |
| RF24_PA_HIGH | −6 dBm |
| RF24_PA_MAX | 0 dBm |
- Sur un module PA+LNA, l’amplificateur ajoute de l’ordre de 20 dB : à « MAX », la puissance rayonnée peut dépasser la limite de 100 mW (20 dBm) de la bande 2,4 GHz en Europe. Utilise « LOW » ou « MIN » pour des tests à courte distance.
- Plus de puissance ne corrige pas une mauvaise alimentation. Traite d’abord le découplage.
- Sur un module PA+LNA, une alimentation faible se traduit par des redémarrages quand vous passez en « HIGH » ou « MAX ».
Configurateur
Règle la liaison et récupère le code de l’émetteur ou du récepteur. Les mêmes valeurs doivent être saisies des deux côtés.
Configurateur radio
// Le code apparaît ici.Simulateur de liaison
Deux cartes virtuelles s’échangent des paquets. Le modèle combine la perte en espace libre, le débit choisi (sensibilité du récepteur) et les retransmissions. Ce n’est pas une mesure : la portée réelle dépend de l’antenne, des obstacles et de l’alimentation.
Simulateur de liaison
- Envoyés
- –
- Reçus
- –
- Confirmés (ACK)
- –
- Perdus
- –
- Taux de réussite
- –
- Essais par paquet
- –
- Puissance reçue
- –
- Marge
- –
- Réussite théorique
- –
- Portée à 90 %
- –
Dépannage
| Symptôme | Cause probable | Solution |
|---|---|---|
radio.begin() renvoie false | Câblage SPI, alimentation ou module défectueux | Vérifie 3,3 V, GND, CE, CSN, SCK, MOSI, MISO. Ajoute un condensateur de 10 à 100 µF sur VCC. |
| Aucune réception | Adresse, canal, débit ou payload différents | Recopie exactement les mêmes réglages des deux côtés, et vérifie stopListening() / startListening(). |
| Marche à quelques centimètres seulement | Antenne ou alimentation | Éloigne les modules d’une masse métallique, stabilise l’alimentation, baisse le débit à 250 kbit/s. |
| Pertes de paquets aléatoires | Wi-Fi sur le même canal, alimentation bruitée | Change de canal (74 à 83), active l’ACK et les retransmissions, ajoute un condensateur. |
write() renvoie toujours false | Le récepteur n’écoute pas ou n’a pas la même adresse | Teste le récepteur seul, vérifie l’adresse et le mode d’écoute. |
| Redémarrages à l’émission | Module PA+LNA sur une alimentation trop faible | Passe à une alimentation 3,3 V dédiée et baisse la puissance. |
| 250 kbit/s ne marche pas | Clone de nRF24L01 sans « + » | Utilise 1 Mbit/s, ou remplace le module. |
| Valeurs incohérentes entre deux cartes | Structures de tailles différentes | Utilise des types de taille fixe (uint8_t, uint32_t) et la même struct des deux côtés. |
Projets
Projets Kaihatsu Lab qui utilisent ce composant :
Émets uniquement dans le cadre de la réglementation de votre région (bande ISM 2,4 GHz, puissance limitée) et ne perturbe pas les communications des autres.
Idées à construire
- Télécommande à plusieurs boutons pour un robot ou un éclairage.
- Capteurs de température ou d’humidité dans plusieurs pièces qui remontent vers un seul récepteur (un pipe par capteur).
- Sonnette sans fil avec un écran OLED côté récepteur.
- Réseau de plusieurs cartes avec la bibliothèque RF24Network ou RF24Mesh.
Le PCB et les composants pour reproduire les projets arriveront avec la boutique.
