Faire dialoguer un Raspberry et un Arduino via nRF24L01

Proposer ou rechercher un tutoriel concernant le Raspberry Pi

Modérateur : Francois

domi
Administrateur
Messages : 1936
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar domi » mer. 24 juin 2015 22:24

Recherchant un moyen de relier des capteurs autonomes à un Raspberry Pi. Mon choix s’est orienté sur l’utilisation d’un Arduino Nano. Petit mais suffisamment puissant pour être autonome, effectuer différents relevés, mais également effectuer des actions comme par exemple piloter un relais.

Pour communiquer avec le Raspberry Pi, j’ai choisi d’utiliser des modules nRF24L01, module de liaison Hertzienne à 2,4 Ghz.

1 - But recherché

Le but de ce tutoriel est de faire dialoguer un Raspberry Pi et un Arduino Nano.
Nous allons voir comment réaliser l’installation de la bibliothèque RF24, le cablage, ainsi que la configuration du Raspberry et de l’Arduino Nano.
Les programmes en C++ sont une adaptation de programmes trouvés en exemple sur Internet, je les ait adapté à mon besoin.

2 - Principe de fonctionnement souhaité

Le principe de fonctionnement de ce tutoriel est de piloter depuis un Raspberry Pi, une LED commandée par l’Arduino Nano, ce dernier retourne au Raspberry Pi un état de la commande pour indiquer sa bonne exécution, ou pas.

  • Allumage de la LED
    • On envoi dans une commande une chaine JSON au Raspberry Pi, celui ci l’interprète, puis envoi au Nano via le nRF24L01 la commande d’allumage de la led (envoi du N° id attribué au nRF24L01 du Nano + commande "on" ).
    • Le Nano reçoit la commande, allume la LED, et retourne sont état au Rpi.
    • Le Rpi reçoit l’état de la LED, le programme reconstruit une chaine JSON de retour avec la valeur de retour pour l'utilisateur ("true" ou "false"), ainsi que l’état de la Led ("on" ou "off"))
  • Extinction de la LED
    • Idem ci dessus, mais envoi d’une commande "off"
  • Demander l’état de la LED
    • Le Rpi envoi une demande au Nano pour connaitre l’état de la led (envoi du N° id attribué au nRF24L01 du Nano + commande "get").
    • Le Nano lit l’état de la Led qu’il a en mémoire, et le retourne au Rpi.
    • Le Rpi reçoit l’état de la LED, le programme reconstruit une chaine JSON de retour avec la valeur de retour ("true" ou "false") ainsi que l’état de la Led ("on" ou "off"))
Passons maintenant à la partie technique, installation et configuration du matériel.

3 - Mise à jour du système

Avant toute installation, on commence par mettre à jour le système :

Code : Tout sélectionner

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade


4 - Préparation du système

4.1 - Installation de SPI

Afin d’assurer une bonne stabilité de l’interface SPI, si le système est Overclocké, il est préférable de l’annuler. Il sera possible une fois que l’ensemble sera fonctionnel, de tenter une réactivation de l’overclock, Mais par sécurité, il vaut mieux d’abord installer l’ensemble, et le faire fonctionner dans des conditions normales et sur un système sain, et seulement après retenter un overclockage.

Pour activer l’interface SPI, il faut lancer la commande :

Code : Tout sélectionner

$ sudo raspi-config

Aller dans le menu des options avancées (menu "Advanced Options"), puis dans le sous-menu, sélectionner "SPI", et cliquer sur "Oui" pour activer le SPI.

Il est ensuite demandé si l’on souhaite charger le module SPI avec le Noyau, répondre "oui"

Quitter l’utilitaire "Raspi-config". Rebooter le système.

Après le redémarrage, on va autoriser l’accès à SPI. Pour cela, éditer le fichier "raspi-blacklist.conf" :

Code : Tout sélectionner

$ sudo nano /etc/modprobe.d/raspi-blacklist.conf

Attention, dans les dernières versions de Raspbian, j'ai remarqué que ce fichier n’existe plus, ou qu'il est vide, il n’y a donc plus rien à modifier dedans. Passer directement à la suite du prochain reboot sans suivre les modifications du fichier.

Si le fichier n’est pas vide, vérifier si la ligne ci-dessous existe :

Code : Tout sélectionner

blacklist spi-bcm2708

Dans ce cas, il faut la commenter en ajoutant un « # » devant :

Code : Tout sélectionner

#blacklist spi-bcm2708

On enregistre, on quitte l’éditeur, et on reboot le Raspberry.

Au redémarrage, on vérifie que le SPI est bien activé :

Code : Tout sélectionner

pi@raspberrypi ~ $ ls -la /dev/spi*
crw-rw---T 1 root spi 153, 0 janv. 1 1970 /dev/spidev0.0
crw-rw---T 1 root spi 153, 1 janv. 1 1970 /dev/spidev0.1

Si on voit apparaître les « /dev/spi*« , c’est que la configuration est correct.

5 - Installation de la bibliothèque

Créer un dossier que l’on nommera "nrf24l01" dans le "home directory" de l’utilisateur "pi". Importer la bibliothèque RF24, et la compiler de la façon suivante.

Code : Tout sélectionner

$ cd
$ mkdir nrf24l01
$ cd nrf24l01
$ git clone https://github.com/TMRh20/RF24.git
$ cd RF24
$ make
$ sudo make install

On installe la librairie « JSON » que l’on va utiliser dans notre script de communication :

Code : Tout sélectionner

$ sudo apt-get install libjson0-dev

Revenir dans le dossier nrf24l01

Code : Tout sélectionner

$ cd ~/nrf24l01

Copier les fichiers "Makefile" et "sender.cpp" que vous trouverez dans le ZIP "nRF24L01_Raspberry" en bas de ce tutoriel.
Compiler le fichier à l’aide de la commande « make »

Code : Tout sélectionner

$ make


6 - Installation matériel

6.1 - Le Raspberry Pi

Éteindre le Raspberry, nous allons lui connecter physiquement le module nRF24L01.

Rpi_nrf24l01.png
Connexion Raspberry et nRF24L01
Rpi_nrf24l01.png (117.79 Kio) Vu 6262 fois

L’exemple est ici avec un Raspberry Type B, mais il est de même avec un A, A+, B+ ou Pi2

Connexion sur le Raspberry, les connexions aux broches ci-dessous ne peuvent être changées :

  • Pin 19 = MOSI du Raspberry vers MOSI (pin 6) du nRF24L01.
  • Pin 21 = MISO du Raspberry vers MISO (pin 7) du nRF24L01.
  • Pin 23 = SCLK du Raspberry vers SCK (pin 5) du nRF24L01.
  • Pin 24 = CE0 du Raspberry vers CSN (pin 4) du nRF24L01. (Peut éventuellement être connecté sur pin 26 du Raspberry, mais les scripts devront être adaptés).

La connexion du +3,3v, pin 2 du nRF24L01 est prise dans ce schéma sur le pin 1 du Raspberry. Cette alimentation peut être prise sur tout autre pin du Raspberry fournissant du 3,3v (pin 1 ou 17).

La connexion GND, pin 1 du nRF24L01 peut être prise partout ou il y a une pin GND sur le Raspberry.

  • Reste la pin 22 du Raspberry, il s’agit d’un port GPIO. Si celui ci est déjà utilisé, on peut prendre n’importe quel port GPIO. Il faudra pour cela adapter le script "sender.cpp" puis le recompiler.

Dans le script, changer la ligne :

Code : Tout sélectionner

RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_16MHZ);

en adaptant « RPI_V2_GPIO_P1_22″ en fonction du pin GPIO connecté.
Exemple : « RPI_V2_GPIO_P1_11″ pour le GPIO 0.

6.2 - L’Arduino Nano

Nous allons installer le module nRF24L01 sur un Arduino Nano. C’est ce dernier qui recevra l’ordre du Raspberry qui lui demandera d’allumer ou d’éteindre la Led.
Le tutoriel est ici donné avec un Arduino Nano, mais toute autre Arduino fera l'affaire, en respectant les connexions ci-dessous.

Voici le schéme de cablage du Nano et du nRF24L01

Nano_nrf24l01.png
Connexion Arduino Nano et nRF24L01
Nano_nrf24l01.png (70.83 Kio) Vu 6262 fois


Connexion sur le Arduino Nano, les connexions aux broches ci-dessous ne peuvent être changées :

  • Pin D11 du Nano vers MOSI (pin 6) du nRF24L01.
  • Pin D12 du Nano vers MISO (pin 7) du nRF24L01.
  • Pin D13 du Nano vers SCK (pin 5) du nRF24L01.

Connexions pouvant être effectuées sur d’autre pin, mais qui devront être adaptée dans le code du Croquis exporté vers le Nano.

  • Pin D10 du Nano vers CSN (pin 4) du nRF24L01.
  • Pin D9 du Nano vers CE (pin 3) du nRF24L01.
  • Pin D6 du Nano vers l’anode de la LED.

  • L’alimentation du +3,3v, pin 2 du nRF24L01 est prise dans ce schéma sur le pin +3,3v du Nano.

Pour effectuer les connexions D10, D9 ou D6 à un autre pin, il faut ouvrir le croquis Arduino (.ino) et adapter les lignes suivantes :

Code : Tout sélectionner

#define RF_CE    9
#define RF_CSN   10
#define LED_PIN  6


7 - Les Programmes

7.1 - Programme Raspberry Pi

Le programme du Raspberry Pi permet d’envoyer via le nRF24L01, un ordre d’allumage ou d’extinction d’une LED. Cette dernière est commandée par notre Arduino Nano, l’ordre d’allumage et d’extinction est donc envoyé par le Raspberry Pi, vers Arduino Nano.

Le programme est écrit en C++, il utilise la bibliothèque RF24, que nous avons installée plus haut dans ce tutoriel.

Le principe est d’envoyer une chaine JSON via la ligne de commande du Raspberry Pi. Cette chaîne est composée de :

Code : Tout sélectionner

{
   "to":"1",              // id di nRF24L01 vers lequel on envoi la commande.
   "message":"get", // commande envoyée au Arduino Nano.
   "TTL":"3000"      // (paramètre optionnel) "Time out" (si non précisé il sera de 1000 ms).
}

Les messages peuvent être :

Code : Tout sélectionner

set=on     // Commande l'allumage de la LED
set=off    // Commande l'extinction de la LED
get         // Demande au Nano quel est l'état de la LED

Exemple de commande envoyée pour commander l’allumage de la LED :

Code : Tout sélectionner

$ sudo ./sender '{"to":"1","message":"set=on"}'

Nous envoyons bien en paramètre une chaîne au format JSON. Le programme du Raspberry s’occupe de transcrire cette chaine afin d’envoyer les commandes au Arduino, via nRF24L01.

Télécharger ci-dessous le ZIP, puis copier les deux fichiers contenus dans l'archive "nRF24L01_Raspberry " vers le dossier « ~/nrf24l01/

nrf24-raspberry.zip
Script pour Raspberry
(1.58 Kio) Téléchargé 2144 fois

Se placer dans le dossier puis compiler le programme.

Code : Tout sélectionner

$ cd ~/nrf24l01
$ make

Le programme sur Raspberry est maintenant fonctionnel.

7.2 - Programme Aduino Nano

Le programme du Arduino Nano permet de recevoir les commandes envoyées, les interpréter, puis de répondre au Raspberry Pi si la commande est OK ou pas.

Ci-dessous le programme "ino" à charger depuis votre atelier Arduino (IDE).

nrf24-arduino.ino.zip
Script pour Arduino
(1.28 Kio) Téléchargé 2075 fois

8 - Conclusion

Notre montage est maintenant fonctionnel.
Les prochaines étapes seront de changer la LED par une sonde de température DS18B20, et donc adapter les programmes.
Au menu également une sonde DHT11 ou DHT 22, un détecteur ultrason de type HC-SR04 (pour remplacer le Raspi dans ma cuve à eau), .... et tout autre détecteur ou sonde dont je pourrais avoir besoin.

9 - Références

Voici quelques liens vers des articles sur la mise en oeuvre du nRF24L01. Ce sont des articles de montages ou de programmes, auxquels je me suis inspirés afin d’arriver à ce résultat.

http://blog.carr3r.com/post/raspberry-p ... 1-modules/
http://hack.lenotta.com/arduino-raspber ... -nrf24l01/
http://www.homautomation.org/2014/06/11 ... -nrf24l01/

domi
Administrateur
Messages : 1936
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar domi » mer. 24 juin 2015 22:25

Emplacement réservé pour évolution du tutoriel vers autre relevé

domi
Administrateur
Messages : 1936
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar domi » mer. 24 juin 2015 22:25

Emplacement réservé pour évolution du tutoriel vers autre relevé

osan15
Messages : 2
Enregistré le : sam. 8 août 2015 01:35

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar osan15 » sam. 8 août 2015 01:55

Bonsoir,

Tout d'abord je souhaiterais te remercier domi c'est un excellent tutoriel et tout marche nikel :).
Cependant j'ai essayé de modifier le code afin que le programme en C++ écoute en permanence les messages reçus, et que le programme de l'arduino envoie un message toutes les 10 secondes.
Pour le programme de l'arduino normalement celui ci ne pose pas de problèmes par contre avec le programme en C++ impossible de récupérer un message "correct".
Second problème apparemment la méthode "available" est toujours à l'état FALSE.
Pourrais tu me donner un coup de pouce pour résoudre ce problème au cas ou tu aurais déjà eu le même soucis.

Merci d'avance ,

Je te laisse cette portion de code vraiment simple au cas ou tu verrais le problème.

Code : Tout sélectionner

while (true){
            while (!radio.available()){
               sleep(0.01);
            }
            radio.read( &answer, sizeof(payload_general_t));
            printf("La chaine trouvee est : %s \n", (char *) answer.message);
            
         }

domi
Administrateur
Messages : 1936
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar domi » sam. 8 août 2015 09:43

Bonjour,

Apparemment tu souhaites que le Raspberry écoute en permanence et que l'arduino envoi un message toutes les 10 seconde, c'est bien ça ?

Si c'est le cas, il faut mieux éviter cette technique. En effet, si le raspberry écoute en permanence, il y a de forte chance qu'il ne pourra plus rien faire d'autre, même plus répondre à une demande de connexion SSH. Le CPU risque de monter à 100% d'utilisation et saturer.
L'Arduino est lui prévu pour travailler dans une boucle permanente.
Si tu souhaites obtenir une info toutes les 10s, il suffit de créer une tache sur le Raspberry qui s’exécutera toute les 10s pour interroger l'Arduino.

osan15
Messages : 2
Enregistré le : sam. 8 août 2015 01:35

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar osan15 » jeu. 13 août 2015 01:33

Bonsoir,

Apparemment j'ai résolu le problème avec le code au dessus ça marche relativement bien et les performances du Raspberry ont l'air de tenir étant donné que j'ai en plus un serveur NodeJs qui tourne aussi dessus en même temps.
Je souhaite écouter en permanence les messages sur l'arduino car je souhaiterais mettre en place un détecteur de mouvement qui lui renverra l'info via le NRF24L01 pour indiquer "par exemple une alarme". Du coup le Raspberry reçoit le message avec le code en C, après pour éviter de rester trop longtemps dans du code en C (c'est pas trop mon fort) j'envoie une requête GET sur mon serveur NodeJs et je traite l'infos depuis le Javascript et j'établis un WebSocket qui permet de mettre à jour l'interface graphique de tous les clients connectés.

Du coup je pense pas pouvoir traiter toutes les données directement sur l'Arduino après si tu as une autre idée je suis preneur évidemment.

Merci de ta réponse,
Antoine.D

syl20duc
Messages : 1
Enregistré le : mar. 13 oct. 2015 18:11

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar syl20duc » mar. 13 oct. 2015 18:20

Bonjour,

tout d’abord merci pour ce tutoriel.

Je l’ai suivi entièrement, et lorsque j’essaie d’envoyer un message depuis le Rpi vers l’Arduino,

Code : Tout sélectionner

pi@raspberrypi ~/nrf24l01 $ sudo ./sender ‘{« to »: »1″, »message »: »set=on »}’


j’ai ce message :

Code : Tout sélectionner

{« status »: »false », »code »: »5″, »message »: »Timed-out »}


Les 2 modules MRF24 ne semblent pas arriver à communiquer ensemble.

Avez-vous un conseil à me donner afin de résoudre ce pb et faire allumer cette fameuse LED ?

Pour info, voici le contenu du moniteur Arduino :

Code : Tout sélectionner

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1    = 0x6576616c73 0x657473616d
RX_ADDR_P2-5    = 0xc3 0xc4 0xc5 0xc6
TX_ADDR       = 0x6576616c73
RX_PW_P0-6    = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA       = 0x3f
EN_RXADDR    = 0x02
RF_CH       = 0x4c
RF_SETUP    = 0x07
CONFIG       = 0x0f
DYNPD/FEATURE    = 0x3f 0x04
Data Rate    = 1MBPS
Model       = nRF24L01+
CRC Length    = 16 bits
PA Power    = PA_MAX




Merci d’avance pour votre aide.

Sylvain

ingfred
Messages : 9
Enregistré le : mer. 14 oct. 2015 07:52
Localisation : Jura
Contact :

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar ingfred » mer. 14 oct. 2015 08:02

Merci pour le tuto.
Tout fonctionne hormis une réponse {« status »: »false », »code »: »6″, »message »: »Wrong ACK »}
Sur la console de l’arduino la réponse est ok. J'ai l'impression que la communication retour de l'arduino vers le raspi n'est pas ok.
Une idée ?
Merci par avance.
Sylvain : J'ai eu ce soucis car pin pas cablés correctement sur le raspi. Pin CE que j'ai déplacé ou modifié sur un fichier de conf.

domi
Administrateur
Messages : 1936
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar domi » mer. 14 oct. 2015 08:53

Bonjour,

@Sylvain : Effectivement, le time-out indique que le Raspberry ne reçoit aucune information dans le temps maxi d'attente.
Le problème peut venir de l'Arduino que ne renvoi rien, ou du Raspberry qui envoi une commande non compréhensible par l'Aduino, et donc ne répond pas.
Si les PIN de connexion ont été changées, prendre soin de modifier le numéro de PIN dans le code.

Dans la commande que donnée ci dessus, je constate qu'il y a des double quotes » et "
Cela vient peut-être que de la copie dans le forum, mais s'assurer que la commande est bien :

Code : Tout sélectionner

sudo ./sender '{"to":"1","message":"set=on"}'


@ingfred : Le code 6 indique qu'il y a bien eu communication, mais incompréhension.
Vu que le code a été modifié, attention qu'il n'y est pas un problème de caractères spéciaux, entre l'encodage du fichier d'origine, et celui que tu utilises.

ingfred
Messages : 9
Enregistré le : mer. 14 oct. 2015 07:52
Localisation : Jura
Contact :

Re: Faire dialoguer un Raspberry et un Arduino via nRF24L01

Messagepar ingfred » mar. 20 oct. 2015 14:03

Bonjour Domi.
Et merci pour ta réponse.
J'ai remis le raspi à 0 avec une nouvelle sd car l'ancienne semblait faire des siennes.
Je recharge tout cela et vous tiens au courant.


Retourner vers « Tutoriels »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité