Il peut arriver que nous ayons besoin de communiquer sans fil entre deux arduino.
Plusieurs solutions existent mais aujourd’hui on parle du module RF24.
J’ai eu beaucoup de mal à produire ce tutoriel car je souhaitais communiquer de manière bidirectionnelle et il y a certaines surprises qui arrivent, comme beaucoup de “bug”, le module envoie l’information mais le module récepteur ne reçoit rien, ou reçoit mais le retour ne fonctionne pas, bref énormément d’acharnement et de boulot pour vous proposer ce tutoriel !
En matériel il nous faut :
- 2 arduino (ici j’ai un uno et un mega, branchement différent sur mega)
- 2 modules nRF24L01
- Tout le reste ci dessous est optionnel et est destiné au tuto
- 2 boutons
- 1 led et la résistance qui va avec
- 1 photo résistance et 1 résistance de la même valeur que la photo résistance
- 1 potentiomètre
Le branchement des modules nRF24L01 suit un schéma différent si arduino uno et mega
ATTENTION LES MODULES FONCTIONNENT EN 3.3V, donc brancher sur le 3.3V
| MOSI | MISO | SCK | CS | CE |
Uno | 11 | 12 | 13 | 8 | 7 |
Mega | 51 | 50 | 52 | 8 | 7 |
Et sur les nRF24L01 les correspondances pin sont
|M |O |D |U |L |E |
VCC 3.3V | CS | MOSI | IRQ |
GNG | CE | SCK | MISO |
Donc si vous suivez ces deux tableaux vous avez votre branchement avec les modules, ensuite si vous souhaitez reproduire le tutoriel sur l’arduino “mode 0” ( on verra dans le code pourquoi) j’ai un bouton branché sur le pin 2 et 3, l’autre partie des boutons sont branché sur le Gnd.
Pour le deuxième arduino “mode 1” j’ai le pin 4 connecté à une led qui est associé à une résistance et à la masse.
Le pin A0 est connecté à l’intersection de la photorésistance et de la résistance, l’autre côté de la photorésistance est connectée au 5V et l’autre côté de la résistance au Gnd.
Le pin A1 est connecté au pin central du potentiomètre, les deux autres pin sont connecté au 5V et Gnd.
Voila normalement vous avez tout bon sur le câblage du circuit, attention au module qui fonctionne en 3.3Volt.
Parlons du code, ici mon but est de transmettre une ou plusieurs informations et de pouvoir avoir un retour d’information suite à une demande.
J’utilise la bibliothèque RF24 qui se trouve dans gérer les bibliothèque RF24 (by THRh20) de votre arduino.
Premièrement nos include pour le SPI , nRF24L01, RF24 (et printf optionnel si on enlève “radio.printDetails();” // affiche ).
La bibliothèque RF24 by TMRh20 dans le gestionnaire de bibliothèque ( doc : http://tmrh20.github.io/RF24/ ).
J’ai défini 2 boutons sur le pin 2 et 3 pour mon module 0 , puis pour mon module 1 je défini le pin pour la photo résistance A0 , une led pin 4 et le potentiomètre en A1.
J’appelle ma librairie RF24 avec RF24 radio(7, 8); pour les pin CE, CSN des modules ce sont les seuls pin que l’on peut modifier tout le reste est fixe.
Ensuite on définit des tuyaux de communication avec “addresses[][6] = {“00001″,”00002”};
Un booleen mode defini à 0 ou 1 qui va aiguiller le programme suivant le module utilisé, j’ai regroupé ici les codes des deux modules en un seul, il est conseillé d’utiliser un programme pour chaque module mais ici j’ai tout regroupé et j’active la partie nécessaire avec mode.
J’initialise des variables “receivedData[32] “, “dataToSend” et “temporisation” qui vont être utilisés dans mon programme.
Les variables “lumiereBool” , “button1”, “button2” sont utilisées pour mes actions (mode 0) , “lumiereBool” contiendra le nombre d’essais d’envois d’information avant abandon et les button évitent que le bouton reste appuyé et envoie des données tout le temps.Et pour le mode 1 “ledBool” pour vérifier l’état de la led et “x” pour une variable de mesure potentiomètre.
On commence dans le setup.
“Serial.begin” pour vérifier nos valeurs et “printf_begin” (optionnel) pour afficher les valeurs du module nRF24L01.
On démarre le module “radio radio.begin();” et on choisit le channel (0 à 125) avec “radio.setChannel(100);”.
Puis on définit la vitesse de communication avec “radio.setDataRate(RF24_250KBPS); // ( valeurs possibles RF24_250KBPS , RF24_1MBPS , ou RF24_2MBPS )”.
On active “radio.enableDynamicPayloads();” pour laisser gérer au module des tailles dynamiques.
Et la partie importante j’ai un if avec “mode == 0” , si le mode = 0 alors j’active les pipes avec des adresses, les pipes sont inversé entre le mode 0 et le mode 1 ce qui permet d’avoir un tuyaux pour communiquer dans un sens et dans l’autre.
On règle ensuite l’amplification avec “radio.setPALevel(RF24_PA_MAX);” // ( valeurs possibles RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH et RF24_PA_MAX ).
On commence à écouter avec “radio.startListening();” , on affiche les informations modules si l’on souhaite avec “radio.printDetails();” et on arrête l’écoute avec “radio.stopListening();”
Je définit le mode des pin pour le mode 0 et mode 1 ” pinMode( PIN_BUTTON1, INPUT_PULLUP); pinMode( PIN_BUTTON2, INPUT_PULLUP); et pinMode( LED1, OUTPUT); pinMode( PIN_X, INPUT);x = analogRead(PIN_X);”
Le setup est terminé.
J’ai ensuite une fonction que j’ai nommée “sendData(String dataToSend)” dans laquelle on envoie un String et je récupère une valeur bool. Cette fonction convertie le string en char et envoie l’information.
Ensuite ma boucle ou tout ce passe suivant si j’ai mon mode à 0 ou 1 je vais effectuer certaines actions.
Premières conditions est sur le bouton 1 , si j’appuie et que mon bouton a bien était à l’état bas à un moment alors “lumiereBool = 5; “et “button1 = 1; “sinon si bouton relâché “button1 = 0; “.
Deuxième condition, si “lumiereBool>0” c’est que l’on a demandé une information a envoyer, donc on va envoyer une information, donc on arrête d’écouter avec “radio.stopListening();” , j’envoie mon information avec “Serial.println(sendData(“D:LUMIERE”));” , ici on peut simplement mettre le “sendData(“D:LUMIERE”);” pour ne pas afficher la valeur de retour.
Je décrémente le nombre de “lumiereBool–; “//( nombre d’essais ) , et j’active à nouveau l’écoute avec “radio.startListening();” et je met une temporisation plus longue d’écoute avec temporisation = 1000; . Pour le bouton 1 on attends un message de retour c’est pour cela que l’on est passé par “lumiereBool” que l’on retrouvera plus tard.
Pour le bouton2 on n’attend pas de retour de l’autre module donc on prend le même type de condition pour éviter d’envoyer le message X fois mais on envoie directement le message “Serial.println(sendData(“D:LED”));” , ici j’envoie D:LED que l’on va pouvoir trier plus tard.
J’ai après mon else qui est pour le mode 1 , sur le mode 1 on a seulement la valeur du potentiomètre à mesurer et à comparer à l’ancienne mesure pour ne pas se déclencher tout le temps et si on détecte un changement de + ou – 30 alors on appelle la fonction “positionPot();” qui va envoyer la valeur du potentiomètre.
Hors des conditions de mode, on à notre programme général qui ne fait qu’écouter et faire les actions nécessaires au message reçu.
Donc on écoute avec “radio.startListening();”, suivi d’une boucle d’attente si module disponible, on remet la temporisation en valeur plus classique par la suite.
Si ma radio est prête “if (radio.available()) {” alors je récupère ce que j’ai reçu avec “radio.read(&receivedData, sizeof(receivedData));”.
Si mes datas reçues sont différentes de vide alors on a notre “découpeuse” d’information. Elle est faite pour couper les messages, exemple je veux envoyer 3 info X Y et Z je peux faire “X:5&Y:4&Z:9” donc je peux récupérer ses 3 valeurs séparément, mais ici on envoie une info exemple “D:LUMIERE”.
La partie qui nous intéresse est au niveau de “if(String(command) == “D”){” j’ai décidé d’envoyer des ordres avec D:MONORDRE donc tout ce qui est apres D est un ordre, si on reçoit LUMIERE “if(String(valueCommand) == “LUMIERE”){” alors j’arrête l’écoute radio et j’appelle “dataLumiere();”,je n’oublie pas d’activer l’écoute ensuite (mode 0).
J’ai une condition sinon si, la commande reçue est LED alors j’effectue l’allumage ou l’extinction de ma led (mode1).
Partie suivante on à une condition sinon si “}else if(String(command) == “LUM”){” , ici pas d’information commençant par “D:” mais par “LUM:” et cette information est importante car elle dit a mon module mode 0 que j’ai reçue l’information attendue à “LUMIERE”. En envoyant “LUMIERE” je voulais un retour “LUM” avec une valeur, ici je l’ai reçue donc je met “lumiereBool=0;” pour que le module n’essaye plus d’envoyer “LUMIERE” au début du programme.
J’ai un autre sinon si, avec comme valeur attendue “POT” et ici j’affiche simplement la valeur reçue.
Et puis on termine nos boucles et conditions et notre loop.
J’ai deux fonctions ensuite , celle qui envoie la valeur de la photorésistance et celle qui envoie la valeur du potentiomètre, il faut créer la valeur à envoyer en String et l’envoyer avec “sendData(dataToSend);”
On en à terminé avec le code, ici le programme ne sert pas a grand chose mais te permettra de faire ce que tu veux avec soit une information ou tu attends un retour soit un envoie simple.
Voici le code NRF24
Retrouve tout le contenu sur retroetgeek.com
N’hésitez pas à poser vos questions sur les réseaux sociaux de la chaîne instagram , twitter , facebook ,youtube ; si vous ne comprenez pas certaines parties du tutoriel n’hésitez pas , me dire ce que vous aimeriez que je crée pour en faire des vidéos tutoriel et à partager les projets que vous aimeriez créer etc…
Comme toujours allez sur la page de C’est quoi Retro et Geek pour connaître tout ce que je recherche à faire sur la chaîne.
Merci les RetroGeeker et RetroGeekeuse