Skyduino:~#
Articles
arduino, programmation, tutoriel

[Tutoriel] Arduino + Mirf v2 (nRF24L01+)

Bonjour tout le monde !

Aujourd’hui je vous ai préparé un tutoriel qui fait suite à mon tutoriel précédent sur VirtualWire.

Le sujet du jour : La librairie Mirf et plus particulièrement la version 2.

La librairie Mirf permet de contrôler rapidement et relativement facilement des modules nRF24L01, pour faire simple ce sont des module émetteur/récepteur 2.4GHz avec un protocole spécial nommé « ShockBurst » permettant de transmettre des données sans se soucié des possible problémes de transmission.
J’en avais fait un test rapide il y a déja quelque temps : http://skyduino.wordpress.com/2011/08/22/test-nrf24l01/

Tout d’abord avant de commencer, le lien vers la librairie Mirf : http://www.arduino.cc/playground/InterfacingWithHardware/Nrf24L01

Pour ce tutoriel comme pour celui sur VirtualWire je vais rester trés simple et me limiter à un simple « hello world », je vais juste poser les bases ;)

Pour ce tutoriel il va nous falloir :
2 cartes arduino,
2 modules nRF24L01,
8 résistances de 10K,
des fils de câblage

Le câblage :
nRF24L01 -> Arduino
MISO -> D12
MOSI -> résistance -> D11
SCK -> résistance -> D13
CE -> résistance -> D8
CSN -> résistance -> D7
VCC -> VCC
GND -> GND

Maintenant que le câblage est prêt attardons nous sur la partie programmation ;)

1er étape, inclure les librairies qui vont bien :

#include <SPI.h> // Pour la gestion du port SPI
#include <Mirf.h> // Pour la gestion de la communication
#include <nRF24L01.h> // Pour les définitions des registres du nRF24L01
#include <MirfHardwareSpiDriver.h> // Pour la communication SPI hardware (revient à utiliser SPI.h mais avec une surcouche en plus)

pfff … trop facile ! :)

2eme étape, configurer la librairie et les broches CSN et CE :

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 !

C’était pas super compliqué, mais un petit peu quand même hein ;)

3eme étape, configurer l’adresse de réception et d’émission :
Chaque module nRF24L01 doit se voir attribuer une adresse RADDR et TADDR de 5 octets, ces deux adresses permettent de définir quelle module doit recevoir tel ou tel message, si plusieurs module se voit attribuer la même adresse ils communiqueront ensemble, en gros il s’agit de choisir un sous canal pour la transmission ;)

// Sur le 1er module
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

// Sur le 2eme module
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

Faisons un rapide calcul :
Il y a 128 canaux disponible, avec une adresse sur 5 octets, soit 136931896490625 possibilité, ça devrait suffire pour éviter les conflits entre modules ;)
Remarque : Il est possible de changer les adresses « on the fly », vous pouvez par exemple faire une boucle qui envoi des données vers nrf04 puis nrf05, etc … en intégrant Mirf.setTADDR directement dans le code de la boucle ;)

4eme étape, on arrive sur du concret ! La transmission :
Rien de plus simple !

unsigned long time = millis(); // on récupére un valeur que l'on veut envoyer
Mirf.send((byte *)&time); // et on l'envoi, remarque il faut passer un pointeur à la fonction send ;)
while(Mirf.isSending()); // On boucle (attend) tant que le message n'as pas était envoyé

5eme étape, la derniére, la réception :
Ne soyez pas déçu mais se sera aussi simple que pour l’émission ;)

unsigned long time; // Variable qui va stocker notre valeur reçu
while(!Mirf.dataReady()){ // On attend de recevoir quelque chose
  // On attend ... exemple d'application : un systéme de timeout
}
Mirf.getData((byte *) &time); // hoho! Un nouveau message, récupérons le vite dans notre variable !

Remarque : Pourquoi (byte *) &time ?
Mirf.send() et Mirf.getData() demande un pointeur vers un tableau de byte comme arguments, tout ce qui peut être stocker en ram/flash peut être converti en tableau de byte.
L’astuce consiste à créer un pointeur byte* pointant sur l’adresse de notre valeur (ici un long), de ce fait le long de 4 octets ce retrouve « vu » comme un tableau de byte de 4 octets par la fonction.
Cela peut néanmoins poser probléme si la communication ce faisait entre deux systèmes différent, un utilisant la norme « big Endian » et l’autre la norme « little Endian », donc si vous voulez utiliser cette technique pour d’autre application (avec Serial et un ordi par exemple) soyez prudent ;)

Avant de donner les deux codes d’exemples commenté, un petit récap des fonctions de la librairie Mirf2 :
Mirf.cePin Définit la broche utilisé pour CE
Mirf.csnPin Définit la broche utilisé pour CSN
Mirf.channel Définit le canal utilisé pour l’émission (0 à 127, par défaut 0)
Mirf.payload Définit la taille du « payload » (message) à transmettre, au maximum 32 octets, cette constante doit être la même sur tout les modules qui dialoguerons ensemble

void init(void)
Initialise le port SPI, et le nRF24L01 avec les valeurs choisi pour cePin et csnPin.

void setRADDR(byte *addr)
Configure l’adresse (5 octets) utilisé pour identifier le module lors d’une réception.

void setTADDR(byte *addr)
Configure l’adresse (5 octets) utilisé pour identifier le module « cible » lors d’une émission.

void config(void)
Configure le nRF24L01 avec les valeurs choisi pour channel et payload, active la partie réception du module et vide le buffer de réception.

bool dataReady(void)
Retourne vrai (true) si un nouveau message a été recu, faux (false) sinon.

void getData(byte *data)
Récupère le message de taille « payload » dans le tableau de byte « data » donné en arguments.

void send(byte *data)
Envoi le message de taille « payload » à partir des données du tableau de byte « data » donné en arguments.

bool isSending(void)
Retourne vrai (true) si un message est en cours d’émission, faux (false) sinon.

bool rxFifoEmpty(void)
Retourne vrai (true) si le buffer de réception est vide, faux (false) sinon.

bool txFifoEmpty(void)
Retourne vrai (true) si le buffer de transmission est vide, faux (false) sinon.

byte getStatus(void)
Retourne la valeur brute du registre « status »

Note : Le registre « status » du nRF24L01 donne énormément d’information additionnelles qui ne sont pas disponible via des fonctions simple, comme par exemple la gestion des ACK, des échecs d’envoi, l’encombrement du canal, etc …

void powerUpRx(void)
Active le module et la partie émission du nRF24L01.

void powerUpTx(void)
Active la partie réception du nRF24L01.

Ok, vous avez tout bien suivis ? Donc maintenant le code ;)
(C’est l’exemple « ping » de la librairie Mirf que j’ai juste commenté)

Le client :

#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 *)"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("Go !"); 
}

void loop(){
  unsigned long time = millis(); // On stock le temps actuelle retourné par millis() dans time
  
  Mirf.send((byte *)&time); // On envoi time en utilisant l'astuce du cast de pointeur sur adresse
  
  while(Mirf.isSending()); // On boucle (attend) tant que le message n'as pas était envoyé
  
  Serial.print("Ping ... ");
  delay(10);
  
  while(!Mirf.dataReady()){ // On attend de recevoir quelque chose
    if ( ( millis() - time ) > 1000 ) { // Si on attend depuis plus d'une seconde
      Serial.println("=("); // C'est le drame ...
      return;
    }
  }
  
  Mirf.getData((byte *) &time); // On récupére le message recu
  
  Serial.print(millis() - time); // On affiche le temps de latence
  Serial.println("ms");
  
  delay(1000);
} 

Le serveur :

#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("Go !"); 
}

void loop(){
  byte data[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.println("Ping !");
    Mirf.getData(data); // on récupére le méssage
    Mirf.send(data); // Et on le renvoi tel quelle (comme pour un ping réseau)
    Serial.println("Pong !");
  }
}

On petit test et …

… ça marche ! :)

Voila, voila ! Maintenant vous ne pourrez plus dure que vous savez pas utiliser les breakout/modules nRF24L01 avec une carte arduino ;)

About these ads

Discussion

46 réflexions sur “[Tutoriel] Arduino + Mirf v2 (nRF24L01+)

  1. Cool! Merci
    j’ai hâte de recevoir les miens…
    c’est quoi la portée dans une maison environ?

    Publié par nicolas | 21 janvier 2012, 0 h 00 min
  2. Super sympa ce tuto!

    Quelle serait la meilleure méthode pour envoyer plusieurs données de type différents, par exemple envoyer un int puis un un tableau de char et les récupérer de l autre coté?

    Merci d avance

    Publié par fly | 24 janvier 2012, 12 h 56 min
    • La meilleur solution serait de tout envoyer en byte[], que ce soit les int ou les char avec un octet « balise » avant pour faire la différence à la réception.
      Exemple :

      Publié par skywodd | 24 janvier 2012, 13 h 27 min
      • Merci pour ta réponse, c’est ce que j avais en tete, envoyer une « trame » de byte avec une entête (ou « etiquette ») pour déterminer de quelle valeur il s agit et pouvoir la stocker au bon endroit.

        Publié par fly | 24 janvier 2012, 23 h 41 min
  3. Re-Bonjour,

    J’ai pas mal étudier cette page, qui est celle de l auteur de la librairie à priori : http://www.mrroot.net/tag/arduino/

    Il me reste quelques questions :

    Pour configurer mon NRF, j utilise ce code

    Mirf.configRegister(RF_SETUP, 0x07);
    Mirf.channel=120;
    Mirf.config();

    Ce qui est sensé paramétrer un débit de 1Mo et une puissance d’émission maximum, est ce correct?

    Je pose cette question car ma portée ne dépasse pas les 10m ce qui m’étonne un peu.

    Voici le type de module que j utilise avec une amplification de la partie HF : http://2fly.free.fr/arduino/nrf24l01.jpg
    (Je n’ai pas mis les résistance pour passer à 3.3v sauf pour la partie alimentation car d après la doc technique, c’est toléré)

    Merci encore de votre aide

    Publié par fly | 25 janvier 2012, 0 h 18 min
    • Ça ressemble à un module nRF « made in china » (ebay ?) …
      Mon module nRF à une antenne céramique et un ci nRF24L01+ (version +), je sait pas si cela peut affecter la distance d’émission mais j’arrive aux 40m sans trop de probléme.

      Ps: plus la vitesse est élevé plus la porté est réduite, à 1Mbs (Mbs pas Mo ;)) tu perd pas mal de porté, moi je suis en 250Kbs.

      Publié par skywodd | 25 janvier 2012, 11 h 27 min
  4. Oui c’est du module made in China mais j ai également testé des modules Nordic qui ne me donnent pas plus de résultat.

    Peux tu me donner la configuration de ton registre stp? moi j’utilise : Mirf.configRegister(RF_SETUP, 0×07);

    Que me conseilles tu?

    Publié par fly | 25 janvier 2012, 19 h 53 min
  5. Merci pour ta réponse, je vais essayer avec cette config et je te tiendrai au courant.

    Je bosse dans le modèle réduit et pas mal d’émetteurs récepteurs 2.4Ghz utilisent le nrf24L01 et bien souvent les platines ne sont pas plus belles à voir mais fonctionnent tout de même.

    @+

    Publié par Fly | 25 janvier 2012, 23 h 20 min
    • C’est vrai qu’en modélisme les kit RC 2.4GHz sont courant, mais ils ont l’avantage d’avoir une antenne amplifié externe.
      Chez sparkfun ils ont un kit nRF avec connecteur à vis pour antenne externe qui porte sur +100m, donc quelque pars le design de l’antenne doit jouer énormément.

      Publié par skywodd | 26 janvier 2012, 13 h 59 min
  6. Bonjour, j’ai tenté d’utiliser ces modules pour faire des transferts de données et ils ne tiennent pas en endurance.
    Je m’explique, j’ai utilisé un module pour transférer des trames teleinfo de mon compteur EDF vers un autre module relié à mon PC : les modules tiennent 30 secondes puis se bloquent. J’envoie chaque trame de teleinfo (après récupération par Arduino Nano) dans des payload de 32bytes en 1Mbps. L’Arduino relié au PC retransmet directement ces trames sur le terminal dés qu’il les reçoit.
    J’ai essayé des tonnes de configurations pour résoudre le problème mais rien n’y fait.

    Pareil, j’ai tenté de monter des sondes de températures avec. Même sur quelques caractères avec des sollicitations toutes les 10 minutes, il y a au moins 1 sonde sur 2 qui bloque.

    Pour moi, ces petits modules ne sont pas du tout fiable. Tous les test que l’on voit sur internet ne font que du ping, ou n’envoient pas de données à manipuler derrière donc personne ne mets ceci en évidence.

    De plus et pour info, pour envoyer des données et les recevoir pour les manipuler se fait de cette manière :
    Pour envoyer :
    char message[Mirf.payload];
    Mirf.send((byte *)&message); // avec le &

    Pour recevoir :
    char message[Mirf.payload];
    Mirf.getData((byte *)message); // sans le &

    Si des personnes ont déjà rencontré ce problème, je suis preneur de la solution ! En attendant, je migre vers une solution plus chère, mais plus FIABLE.

    Publié par Tibrol | 1 février 2012, 10 h 53 min
    • Je suis pas du tout d’accord !

      J’utilise des nRF24L01+ pour tout mes projets sans fil « simple ».
      Pour mon derniers bricolage j’envoyai 9 octets en provenance d’un capteur capacitif. J’ai fait tourner mon prog pendant bien 3h et rien n’as planté !

      Les nRF24L01 sont utilisé pour faire des télécommandes, de la communication en robotique, etc … ils sont reconnu partout pour leur fiabilité à toute épreuve !

      Je pense qu’il s’agit plutôt d’un bug au niveau du code ou quelque chose dans le genre …

      Publié par skywodd | 1 février 2012, 21 h 58 min
      • Dans ce cas je voudrais bien voir ton sketch pour comprendre d’où vient l’erreur dans mon algorithme. Je suis dessus depuis plusieurs semaines et je ne trouve pas d’où vient l’erreur (si elle existe…).

        Montre moi ta routine d’échange entre tes différentes platines, stp.

        Publié par Tibrol | 1 février 2012, 22 h 17 min
  7. Je te propose d’essayer ceci :
    2 platines arduino chacune munies d’un NRF24L01+

    la premiere platine :

    #include “SPI.h”
    #include “Mirf.h”
    #include “nRF24L01.h”
    #include “MirfHardwareSpiDriver.h”
    
    #define PAYLOAD 20
    
    void setup(){
      
      Mirf.spi = &MirfHardwareSpi;
      Mirf.cePin = 10;
      Mirf.csnPin = 9;
      Mirf.init();
      
      Mirf.setRADDR((byte *)"tele1");
      Mirf.setTADDR((byte *)"serv1");
      Mirf.payload = PAYLOAD;
      Mirf.channel = 12;
      Mirf.config();
    }
    
    void loop(){
       char reponse[PAYLOAD];
      
       String("ADCO:123456789012").toCharArray(reponse,String("ADCO:123456789012").length()+1);
       Mirf.send((byte *)&reponse); while(Mirf.isSending()){}
       delay(100);
    }
    

    Et la seconde platine :

    #include “SPI.h”
    #include “Mirf.h”
    #include “nRF24L01.h”
    #include “MirfHardwareSpiDriver.h”
    
    const int waiter = 100;
    long compteur;
    
    void setup(){
      
      Serial.begin(115200); 
      
      Mirf.spi = &amp;MirfHardwareSpi;
      Mirf.cePin = 10;
      Mirf.csnPin = 9;
      Mirf.init();
      
      Mirf.setRADDR((byte *)"serv1");
      Mirf.setTADDR((byte *)"tele1");
      Mirf.payload = 20;
      Mirf.channel = 12;
    
      Mirf.config();
      
      attachInterrupt(1,teleinfo,LOW);
    }
    
    void loop(){  
    }
    
    void teleinfo(){
    
      if(!Mirf.isSending() &amp;&amp; Mirf.dataReady()){
        
        char inData[Mirf.payload];  
        Mirf.getData((byte *)inData);
        Serial.println(inData);
      
      }
    }
    

    Tu vas voir les temps de réponses se dégrader au fur et à mesure….

    Essaies et dis moi comment ça réagit chez toi…

    Publié par Tibrol | 1 février 2012, 22 h 57 min
    • Tu envois une String de 18 octets avec un payload de 20 octets donc à tout les coup tu dégage 2 octets de la ram …
      De plus je suis pas sure que la librairie Mirf2 est était pensé pour marcher en interruption donc coté récepteur aussi ça doit posé probléme je pense.

      PS: Je me suis permis d’éditer ton commentaire pour activer la coloration syntaxique ;)

      Publié par skywodd | 1 février 2012, 23 h 25 min
  8. @TIBROL J’ai mis tout le code source émetteur & récepteur dans un nouvelle article ;)

    Publié par skywodd | 1 février 2012, 23 h 07 min
  9. mea-culpa,

    j’étais en tort, je l’avoue, après avoir repris mon sketch ça fonctionne à merveille. Pardon à toi oh grand Dieu Nordic Semiconductor pour avoir blasphémé. Tes créations sont bonnes et fonctionnent à merveille. Merci à toi SKYWODD pour m’avoir mis sur la voie.

    Publié par Tibrol | 11 février 2012, 17 h 02 min
    • No problém ^^

      Bonne chance pour ton projet ^^

      Publié par skywodd | 11 février 2012, 17 h 13 min
    • Hello blog ..
      Tibrol, peux tu stp expliquer quel etait ton probleme de « fiabilité » ?..
      je fais moi meme mumuse avec ces modules et un PIC (donc pas un carte ARDUINO et pas la librairie correspondante) .. et je tombe sur le meme probleme !

      ca semble fonctionner sans probleme sur un reset, pendant 30 secondes (ping/pong avec une payload de 1 byte) et ensuite ca se plante ..
      mon TX me génère tout d’un coup une IRQ MAX_RT … je la reset, mais elle revient aussi tot !

      merci de tes suggestions
      phil

      Publié par phil | 15 mai 2012, 16 h 35 min
  10. Ma petite contribution:

    Pour rendre la librairie compatible avec IDE Arduino 1.0, il faut remplacer Wprogram.h par Arduino.h dans le fichier Mirf.h de la librairie. En effet WProgram.h a été remplacé par Arduino.h, il faut donc mettre à jour tous vos programmes.

    Il est possible de faire un test pour rendre vos programmes compatibles avec les différentes versions :

    #if defined(ARDUINO) && ARDUINO >= 100
    #include « Arduino.h »
    #else
    #include « WProgram.h »
    #endif

    @+
    FLY

    Publié par FLY | 11 mars 2012, 23 h 06 min
  11. Bonjours,

    J’ai suivi ce tuto mais mon montage ne fonctionne pas. J’ai utilisé deux cartes arduino mega 2560 sur lesquel j’ai connecté le module nrf24L01+ comme suit:
    MISO -> 50
    MOSI -> 51
    SCK -> 52
    CE -> 48
    CSN -> 53
    IRQ -> pas connecté
    Donc j’ai juste adapter les lignes de déclaration des pin CE et CSN comme suit:
    Mirf.cePin = 48; // CE sur 48
    Mirf.csnPin = 53; // CSN sur 53

    Je n’avais pas vu tout de suite que le Vcc doit être connecté au 3v3 et j’ai fait quelques essais en ayant mis le Vcc sur le 5V alors j’espère ne pas avoir endomagé le module nrf24L01+.

    Si quelqu’un a une solution ce serais super sympas, je ne sais plus quoi faire. Dans le sérial je vois juste le message « go! » pour chacun des deux mega. Je pense que le client est bloqué sur le while(Mirf.isSending()).

    Merci pour l’aide

    Publié par Manuc | 16 novembre 2012, 12 h 33 min
    • Si ce sont des modules nRF24L01 chinois & co, je ne sait pas si ils auront survécu au +5v à la place de +3v3 …
      Les modules sparkfun eux ont un régulateur 3v3 intégré donc pas de problème.

      Pour le problème de communication je vois pas trop de solution …
      Regarde ces deux liens, ils pourraient peut être t’aider :

      http://arduino.cc/forum/index.php/topic,82906.0.html

      http://www.bajdi.com/playing-with-nrf24l01-modules/

      Publié par skywodd | 16 novembre 2012, 18 h 10 min
      • Tu répond rappidement Skywodd. Sympas.
        C’est un module qui vient de chez Nordic semiconductor, sur le datasheet il est indiqué que le module tolère des signaux d’entrées à 5V, donc je suppose alors qu’il a résisté au +5V.
        Le premier lien indiqué je l’ai épluché a fond, J’ai tester les librairies « RF24Network » et « RF24″ et j’ai placé un condensateur électrolitique de 4,5µF entre le 3v3 et le Gnd.
        Ca reste toujours sans effet.

        Peut-être que si je met un petit régulateur de tension alimenté par l’extérieur, je vais tester.

        Publié par Manuc | 16 novembre 2012, 19 h 59 min
  12. Salut tout le monde et merci Skywodd pour ce blog qui m’a déjà beaucoup appris.
    Juste pour info, et pour éviter à d’autre de se prendre la tête pendant des heures : j’ai acheté des modules chinois sur ebay (les moins chers), ils ne marchent que si je ne mets pas les résistances de 10K.

    Publié par sebuntu | 10 décembre 2012, 23 h 17 min
  13. Bonjour à tous,

    Tout d’abord, je tiens à remercier l’auteur de cet article super détailler qui met le NRF à portée de tous y compris les débutant comme moi.
    Malheureusement, malgré toutes ces explications je n’arrive pas à faire fonctionner mon montage.
    Le montage est à base de deux arduino micro (ATmega 32U4 idem leonardo). Les modules NRF sont alimentés par le +3.3 de l’arduino. Les broches SCK, MOSI, CE et CSN sont reliées au µc à travers des resistances de 10k.
    Le CE est relié à la broche 8 et le CSN à la 10 (J’ai modifié le code en conséquence). Les autres broches sont reliées au port SPI de l’arduino micro.

    Lorsque je lance l’exemple de ping, j’obtiens un ping/pong infini sur le serveur et « =( » sur le client. C’est assez frustrant car je sens qu’il ne doit pas manquer grand chose…

    J’ai tenté de vérifier le lien SPI en utilisant le code suivant afin de lire un registre, le modifier et le lire à nouveau… (Attention ce code va surement piquer les yeux des maitres de la programmation que vous êtes…)

    #include
    #include
    #include
    #include

    void setup() {
    byte rf_setup = 0;
    byte newval=0;

    Serial.begin(9600);
    while(!Serial);
    Serial.println( « Init… » );

    Mirf.cePin = 8; // CE sur D8
    Serial.println(« CEpin ok »);
    Mirf.csnPin = 10; // CSN sur D10
    Serial.println(« CSNpin ok »);
    Mirf.spi = &MirfHardwareSpi; // On veut utiliser le port SPI hardware
    Serial.println(« mirfhardware ok »);
    Mirf.init(); // Tout est bon ? Ok let’s go !
    Serial.println(« init ok »);

    Mirf.readRegister( RF_SETUP, &rf_setup, sizeof(rf_setup) );
    Serial.print( « rf_setup =  » );
    Serial.println( rf_setup, BIN );
    Serial.println(« Enter a new Rf register value: « );
    while(Serial.available()==0);
    newval=Serial.read();
    Serial.print(« Nouvelle valeur renseignee : »);
    Serial.println(newval, BIN);

    Mirf.writeRegister( RF_SETUP, &newval, sizeof(rf_setup));

    Mirf.readRegister( RF_SETUP, &rf_setup, sizeof(rf_setup) );
    Serial.print(« Nouvelle valeur lue: »);
    Serial.println( rf_setup, BIN );

    }

    void loop() {
    }

    En exécutant ce code, j’arrive bien, à modifier et lire la nouvelle valeur du registre RF_SETUP. J’en déduit que le SPI fonctionne. Ce code s’exécute de la même façon sur mes deux montages.

    Si quelqu’un a une idée à me proposer, je suis preneur.

    Merci d’avance

    Publié par Drainbow | 9 septembre 2013, 19 h 58 min
    • Les cartes Leonardo sont très spéciales.
      Le port SPI ce trouve sur le connecteur 6 broches au centre-droite de la carte.
      Tu est sûr de ton montage ?

      Publié par skywodd | 9 septembre 2013, 20 h 46 min
      • Bonjour et merci de cette réponse,

        Effectivement, la carte micro est un peu spéciale et dispose du port SPI à deux endroits : au centre de la carte ainsi que sur des contacts dédiés à l’opposé du port USB. (voir schéma http://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf).
        Je pense donc que mon montage est correct, d’autant plus que a priori j’arrive à dialoguer en SPI puisque je lis et j’écris dans des registres du NRF.
        Ce que je n’arrive pas à faire fonctionner c’est la transmission/récupération d’info entre deux Micro/NRF.

        Publié par Drainbow | 10 septembre 2013, 19 h 24 min
  14. Bonjour à tous,

    J’ai réglé mon problème… Après avoir vérifier 50 fois mon montage, je l’ai prêter à un collègue qui a tout de suite remarqué que les deux micro n’étaient pas câblés pareil… en effet, sur l’un des deux montage le +3.3v était câblé sur le Vref. Les repère de contact sont inscrits sur le coté des trous, et sur l’un des deux micro un repère est effacé. J’ai donc décalé ma broche d’un trou.
    C’est rectifié et maintenant tout fonctionne.

    Merci encore pour ce tuto!!!

    @+
    Drainbow

    Publié par Drainbow | 13 septembre 2013, 18 h 38 min
  15. je ne comprends pas, je mets n’importe quoi à la place de Mirf.setRADDR((byte *) »nrf01″); et l’arduino nrf01 reçoit quand même les données :(

    Publié par laul | 21 octobre 2013, 15 h 33 min
  16. Salut,
    Serait-il possible de savoir comment tu es arrivé a avoir des résistances d’une valeur de 10KOhms ?

    Publié par vincent | 18 janvier 2014, 21 h 22 min
    • Suffit d’aller sur n’importe quel site / boutique de vente d’électronique.
      Selectronic, Lextronic, Go Tronic, Farnell, …

      Publié par skywodd | 19 janvier 2014, 16 h 03 min
      • x) enfaite la question c’est as-tu fait des calcul ? parce que sur d’autre site présentant ce module ils le font sans résistance…
        Merci

        Publié par vincent | 19 janvier 2014, 16 h 19 min
      • Le nRF24L01+ a des broches tolérants le 5v mais de base c’est censé être du 3v3.
        En ajoutant une résistance (10K c’est classique comme valeur) tu limites le courant et tu allonges un peu la durée de vie du circuit. La diode zener dans la broche du circuit n’as ainsi pas à dissiper trop de courant.

        Ça marche aussi bien sans résistances, mais sur le long terme c’est mieux avec les résistances en série.
        Et ce serait encore mieux avec un montage de type « level shifter » à mosfet, mais là c’est pas le même niveau de câblage :)

        Publié par skywodd | 19 janvier 2014, 16 h 25 min
      • D’accord merci pour cette explication

        Publié par vincent | 19 janvier 2014, 16 h 37 min
  17. Salut,

    J’utilise ces modules pour la transmission d’un drone et je voulais savoir si il est possible ce connaître la force du signal de réception (en % par exemple) pour éviter de le perdre si ça ne capte plus.

    Je me demandais aussi quel est l’utilité de la librairie “nRF24L01.h” et si elle est vraiment nécessaire car chez moi ça fonctionne très bien sans.

    Merci

    Publié par Nicobas | 18 mars 2014, 20 h 26 min
    • Les modules nRF24L01+ n’ont pas de registre RSSI, il est donc impossible de quantifier la qualité du signal.

      Au mieux tu as le bit « RPD » du registre 0x09 (bit 0) qui passe à « 1 » quand le signal reçu est inférieur à -64Dbm, mais pas plus.

      Publié par skywodd | 24 mars 2014, 14 h 17 min

Rétroliens/Pings

  1. Pingback: Outils, services, sites à (re)découvrir 2012 S03 | La Mare du Gof - 22 janvier 2012

  2. Pingback: [Tutorial] Le Nrf24L01, l’Arduino et le MSP 430. | B@ttoMicro - Microcontrôleurs et compagnie ! - 27 mars 2013

  3. Pingback: arduino + modules NRF24L01+ avec LCD | blog de laurent - 8 octobre 2013

  4. Pingback: arduino + ethernet +modules NRF24L01 | blog de laurent - 9 octobre 2013

  5. Pingback: Sonnerie Portail arduino sans fil | Alnoa.fr - 12 mars 2014

  6. Pingback: Coms and ports | Pearltrees - 22 octobre 2014

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Archives

Wow. Dogecoin. Amaze.

Laissez un tip en Dogecoin

DMMNFk6WBVTpx2Wu1Z35GL61QXSd6r6WQx

Suivre

Recevez les nouvelles publications par mail.

Rejoignez 768 autres abonnés