Radio-commande nRF24L01 2.4 Ghz avec Arduino

Utilisation de capteurs et composants électroniques avec Arduino.
Une fiche de tutoriel pour chaque.

Radio-commande nRF24L01 2.4 Ghz avec Arduino

Messagepar tiptop » Dim 25 Aoû 2013 16:59

Module de radio commande nRF24L01 bi-directionnels sur 2.4 GHz, tutoriel d'utilisation avec Arduino.

ImageImage

Composants utilisés

Principe de fonctionnement
Les modules nRF24L01 sont des émetteurs / récepteurs qui utilisent la bande de fréquence 2.4 Ghz comme le radio modélisme, d'utilisation libre sans licence. Ils comportent une antenne intégrée.
Le protocole de transmission ShockBurst permet de garantir une transmission fiable sans s'occuper des détails.
Une modulation GFSK avec 125 canaux, des sauts de fréquence, couplés à un dispositif intégré de détection d'erreur CRC, un adressage des messages,... permettent un anti-parasitage très efficace.

Transmission
La vitesse de fonctionnement maximale est de 2 Mbps, avec une faible consommation électrique.
La distance de transmission est relativement élevée et permet le pilotage de robots, la transmission à distance de données (alarmes, mesures de capteurs de station météo, jeux, jouets, périphériques d'ordinateurs...).

Le module avec antenne incorporée (visible en zigzag sur le circuit) peut transmettre à environ 100 mètres (transmission 1 mW), en terrain dégagé et avec une transmission sur 250 KHz.
Augmenter la vitesse réduit la portée de transmission.

Pour de la plus longue portée (1 km) il existe des module analogues mais amplifiés et avec une plus grande antenne supplémentaire à brancher dessus.

Les modules sont identiques et vendus par paires. Les échanges de données entre modules sont bi-directionnels.

Branchements
Les modules fonctionnent en 3.3V, les entrées tolèrent 5V. J'ai ici monté des résistances de 10 kΩ en série pour adapter les niveaux.

Câblage du module, 8 broches --> Carte Arduino

Schéma vu de dessous et photo vue de dessus :
Image.Image
1 GND --> masse marron
2 VCC --> 3.3V (et pas 5V !) rouge
3 CE (Pin controls RX / TX) --> résistance 10 kΩ --> digital pin8 vert
4 CSN (Chip select) --> résistance 10 kΩ --> digital pin7 bleu
5 SCK --> résistance 10 kΩ --> digital pin13 blanc
6 MOSI --> résistance 10 kΩ --> digital pin11 noir
7 MISO --> digital pin12 jaune
8 IRQ --> non utilisé orange

Image

Sur une carte Arduino Uno, rappelons le brochage :
MISO -> pin12
MOSI -> pin11
SCK -> pin13

Image

Programmation
Télécharger et installer la librairie MIRF
http://playground.arduino.cc/Interfacin ... e/Nrf24L01

et la librairie RF24 ici
https://github.com/maniacbug/RF24

Installer tous ces deux fichiers RF24.cpp et RF24.h
dans un nouveau dossier librairies/RF24.
https://github.com/maniacbug/RF24/blob/master/RF24.cpp
https://github.com/maniacbug/RF24/blob/master/RF24.h
https://github.com/maniacbug/RF24/blob/ ... nRF24L01.h
printf.h

Exemple de fonctionnement

On utilise 2 modules en ping (émetteur) / pong (récepteur), identiques et avec exactement le même montage.

Le premier module envoie un message (codé ici sur 4 octets, qui sont aléatoires dans cet exemple) au second module, qui lui renvoie ensuite la valeur reçue.
Le premier module compare ce qu'il a envoyé avec le message de retour pour s'assurer de la bonne transmission du message.

Le client (module 1)
Code: Tout sélectionner
//=== exemple de code CLIENT nRF24L01 
// communication 2.4 Ghz bi directionnelle
// avec vérification de message bien  reçu
//
// tiptopboards.com 25 08 2013
// Adaptation d'après skyduino
//=============================================
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
 
void setup(){
  Serial.begin(9600);
   
  Mirf.cePin = 8; // CE sur D8
  Mirf.csnPin = 7; // CSN sur D7
  Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
  Mirf.init(); // Tout est bon ? Ok
 
  Mirf.channel = 0; // On va utiliser le canal 0 pour communiquer (128 canaux disponible, de 0 à 127)
  Mirf.payload = sizeof(unsigned long); // = 4, ici il faut déclarer la taille du "payload" soit du message qu'on va transmettre, au max 32 octets
  Mirf.config(); // Tout est bon ? Ok let's go !
   
  Mirf.setTADDR((byte *)"nrf02"); // Le 1er module va envoyer ses info au 2eme module
  Mirf.setRADDR((byte *)"nrf01"); // On définit ici l'adresse du 1er module
   
  Serial.println("Client");
}
 
void loop(){
  byte data_envoi[Mirf.payload];   // Tableau de 4 octets qui va stocker le message à envoyer
  byte data_retour[Mirf.payload];  // Tableau de 4 octets qui va stocker le message recu
 
  data_envoi[0]=random(125);  //Data à envoyer
  data_envoi[1]=random(125);
  data_envoi[2]=random(125);
  data_envoi[3]=random(125);
 
  Mirf.send(data_envoi); // Envoi des 4 octets
  while(Mirf.isSending()); // On attend tant que le message n'a pas été envoyé
   
  Serial.print("Envoi ");
  afficher_4_octets(data_envoi);
  delay(1);  //breve attente (sinon ne passe pas !)
   
   Mirf.getData(data_retour); // on récupère le message retourné
  Serial.print("Retour ");
  afficher_4_octets(data_retour);
  Serial.print(" ");
  //Comparer les deux
  int ok = comparer_4_octets(data_envoi, data_retour);
  Serial.print (ok);
  Serial.println(" erreurs");
  //delay(5);  //Paquet suivant
}

//Fonction affichage de contrôle
void afficher_4_octets(byte data[4])
{
for (int i=0;i<4;i++)
   {Serial.print(data[i]);
   Serial.print(" ");
   }
 }
 
 
 //Fonction de validation aller-retour
int comparer_4_octets(byte aller[4], byte retour[4])
{
  unsigned long entree = aller[0]+aller[1]*256+aller[2]*65536+aller[3]*16777216;
  unsigned long sortie = retour[0]+retour[1]*256+retour[2]*65536+retour[3]*16777216;
  //Serial.print(entree);
  //Serial.print(" et ");
  //Serial.println(sortie);
  if (entree==sortie) { return 0;}  //pas de décalage
  else {return 1;}  //1 erreur
}



Le serveur (module 2)
Code: Tout sélectionner
//=== exemple de code SERVEUR nRF24L01 
// communication 2.4 Ghz bi directionnelle
// avec vérification de message bien  reçu
//
// tiptopboards.com 25 08 2013
// Adaptation d'après skyduino
f//=======================================
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
 
void setup(){
  Serial.begin(9600);
   
  Mirf.cePin = 8; // CE sur D8
  Mirf.csnPin = 7; // CSN sur D7
  Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
  Mirf.init(); // Tout est bon ? Ok let's go !
 
  Mirf.channel = 0; // On va utiliser le canal 0 pour communiquer (128 canaux disponible, de 0 à 127)
  Mirf.payload = sizeof(unsigned long); // = 4, ici il faut déclarer la taille du "payload" soit du message qu'on va transmettre, au max 32 octets
  Mirf.config(); // Tout est bon ? Ok let's go !
   
  Mirf.setTADDR((byte *)"nrf01"); // Le 2eme module va envoyer ses info au 1er module
  Mirf.setRADDR((byte *)"nrf02"); // On définit ici l'adresse du 2eme module
   
  Serial.println("Serveur");
}
 
void loop(){
  byte data_recu[Mirf.payload]; // Tableau de byte qui va stocker le message recu
   
  if(!Mirf.isSending() && Mirf.dataReady())
  { // Si un message a été recu et qu'un autre n'est pas en cours d'emission
    Serial.print("Recu ");
    Mirf.getData(data_recu); // on récupère le message
    //Affichage de contrôle
    afficher_4_octets(data_recu);
    //Serial.print("  ");
   
    Mirf.send(data_recu); // Et on le renvoie tel quel
    Serial.println("Renvoye");
  }
}

//Fonction affichage de contrôle
void afficher_4_octets(byte data[4])
{
for (int i=0;i<4;i++)
   {Serial.print(data[i]);
   Serial.print(" ");
   }
 }


http://arduino-info.wikispaces.com/nRF2 ... 4-Examples
Dans le code, on définit les broches de transmission, la taille des messages (32 octets max), puis on choisit un canal de transmission (0-127) et un "sous canal" grâce aux adresses (sur 5 octets) attribuées aux modules qui doivent communiquer entre eux.
Il y a donc un nombre considérable de combinaisons qui permet d'éviter tout brouillage entre réseaux proches.

Références
Un bon tutoriel sur Skyduino pour mesurer la durée de transmission (en français)
http://skyduino.wordpress.com/2012/01/2 ... -nrf24l01/

Le playground Arduino Nrf24L01 avec la librairie MIRF
http://playground.arduino.cc/Interfacin ... e/Nrf24L01
ou ici la bibliothèque MIRF
https://github.com/aaronds/arduino-nrf24l01
Image

Tutoriel avec la librairie RF24 (en anglais)
http://arduino-info.wikispaces.com/Nrf2 ... 4GHz-HowTo
http://arduino-info.wikispaces.com/nRF2 ... 4-Examples
Image
Image

Datasheet de la puce nRF24L01
http://www.nordicsemi.com/eng/Products/ ... /nRF24L01P
http://yourduino.com/docs/nRF24L01_Prod ... 2_0%20.pdf
tiptopboards - admin
Avatar de l’utilisateur
tiptop
Administrateur du site
 
Messages: 93
Inscription: Mar 13 Aoû 2013 20:38
Localisation: 38

Retourner vers Capteurs et composants

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 10 invités