= Communication sans fil = == Objectif L'objectif de la séance est de lire des capteurs distants sur les !RaspberryPi. Vous allez utiliser les modules de communication NRF24L01 abordés en cours. Chaque !RaspberryPi en a un module NRF24L01. Les capteurs sont sur des Arduinos doté d'un module NRF24L01. Vous n'allez pas aborder la programmation Arduino aujourd'hui. Vous verrez ça la semaine prochaine. Vous allez travaillez sur la !RaspberryPi et continuer la construction des votre serveur WEB. Sur la !RaspberryPi, vous devrez avoir votre serveur HTTP et une application **gateway** qui devra lire les valeurs envoyées par les capteurs et les enregistrer dans un fichier. Votre serveur HTTP devra lire ce fichier et afficher la dernière valeur reçue et une graphe des dernières valeurs reçue (en utilisant Google charts). == Plan B Bon, je ne comprends pas, ce qui marchait très bien l'an passé refuse de fonctionner cette année. Je vous propose donc de suivre un plan B qui vous fera quand même progresser dans la bonne direction. Ce que je vous propose c'est de faire un faux programme `fake_gateway.c` qui simule le comportement du vrai `gateway.c`. === Comportement de fake_gateway * Ecriture chaque seconde dans un fichier `log_in` d'une ligne avec une date et une valeur aléatoire séparées par un `;`. Deux valeurs successives devront être proches (quelques %) afin que la représentation de la courbe de l'historique ne soit pas trop chaotique. Pour la représentation de la date, utilisez juste la sortie de la fonction `time()`. * Lecture sur une fifo d'une valeur que fake_gateway affiche sur le terminal et dans un fichier `log_out`. === Comportement du serveur * Affichage sur le poste client d'une page : * représentant la courbe de la dernière minute de valeurs reçues * contenant un formulaire pour envoyer une valeur vers `fake_gateway` (qui l'affichera sur le terminal). * Rafraichissement de la page toutes les 5 secondes. {{{#!protected == Récupération de la bibliothèque du NRF24L01 == Si nous voulons continuer à cross compiler, il faut installer la librairie qui va permettre de contrôler le module NRF24L01. Il existe plusieurs librairies. Celle choisie à le mérite d'être disponible dans l'environnement !RaspberryPi et !Arduino. C'est-à-dire que lorsque vous aurez compris comment l'utiliser avec la !RaspberryPi, le passage sur Arduino sera facile. * Aller sur le site https://github.com/tmrh20/RF24 * Récupérer le .zip de la branche master (bouton `clone and download -> Download ZIP`) {{{#!bash $ unzip RF24-master.zip $ cd RF24-master $ mkdir $HOME/rf24 $ ./configure --prefix=$HOME/rf24 --soc=BCM2835 --c_compiler=bcm2708hardfp-gcc --cxx_compiler=bcm2708hardfp-g++ --driver=SPIDEV --ldconfig='' $ make $ make install }}} * Vérification que la library est installée. {{{#!bash $ ls $HOME/rf24 include lib }}} Cette même bibliothèque a été installée sur les cartes !RaspberryPi car la bibliothèque est dynamique et non pas statique, donc il faut la bibliothèque sur la !RaspberryPi. == Documents de référence du module NRF24L01 == * [http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01P Site Nordic nRF24L01Plus] * [https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf Spéicification nRF24L01plus] * [https://github.com/TMRh20/RF24 Repository API TMRh20/RF24] == Communication entre le capteur et la base == La documentation de la bibliothèque est [http://tmrh20.github.io/RF24/classRF24.html ici] dont voici un résumé : * ` RF24 (uint8_t _cepin, uint8_t _cspin)`[[BR]] Configuration du module radio et du SPI, reçoit les numéros de broche cepin (radio) cspin (SPI Slave Select) * `bool begin (void)` Démarrage du module radio * `void startListening (void)` * `void stopListening (void)` * `bool available (void)`] * `void read (void *buf, uint8_t len)` * `bool write (const void *buf, uint8_t len)` * `void openWritingPipe (const uint8_t *address)` * `void openReadingPipe (uint8_t number, const uint8_t *address)` - **sensor** (sur l'Arduino) {{{#!c #include #include "RF24.h" #include "printf.h" RF24 radio(9,10); // radio(CE,CS) byte addresses[][6] = {"0Node"}; void setup() { Serial.begin(115200); printf_begin(); radio.begin(); radio.setPALevel(RF24_PA_LOW); radio.openWritingPipe(addresses[0]); radio.printDetails(); delay(1000); } void loop() { Serial.println(F("Now sending !")); unsigned long start_time = millis(); // Take the time, and send it. This will block until complete if (!radio.write( &start_time, sizeof(unsigned long) )){ Serial.println(F("failed!")); } delay(1000); } }}} - **baseSensor** (sur la raspberry pi) {{{#!c #include #include #include #include #include #include typedef uint8_t byte; using namespace std; RF24 radio(15,0); byte addresses[][6] = {"0Node","1Node","2Node","3Node","4Node","5Node"}; void setup() { radio.begin(); radio.setRetries(15,15); radio.setPALevel(RF24_PA_LOW); radio.openReadingPipe(1,addresses[0]); radio.printDetails(); radio.startListening(); } void loop() { unsigned long got_time; if( radio.available()){ radio.read( &got_time, sizeof(unsigned long) ); // Get the payload cout << got_time << endl; } } int main(int argc, char** argv){ setup(); while (1) loop(); return 0; } }}} - Makefile sur la raspberry pi {{{#!make RPI?=20 SRC=src APP=NRF24L01_base DST=lacas/nrf CROSSDIR = /users/enseig/franck/peri CROSS_COMPILE = $(CROSSDIR)/arm-bcm2708hardfp-linux-gnueabi/bin/bcm2708hardfp- INC=$(HOME)/rf24/include LIB=$(HOME)/rf24/lib CFLAGS=-Wall -Wfatal-errors -O2 -I$(INC) LDFLAGS=-L$(LIB) -lrf24 all: $(APP).x $(APP).x: $(APP).cpp $(CROSS_COMPILE)g++ -o $@ -I$(INC) $< -O2 $(LDFLAGS) upload: scp -P50$(RPI) $(APP).x pi@peri:$(DST) clean: rm -f *.o *.x *~ }}} == Travail demandé == * Le but initial est de lire la valeur envoyée par l'Arduino et de l'afficher sur le terminal de la raspberry. Il y a donc au moins 2 noeuds, un émetteur (l'arduino) et un récepteur (la raspberry). * Ensuite, l'idée est de faire une communication entre deux raspberry pi. Il va falloir que vous lisiez la documentation du NRF pour comprendre comment numéroter les noeuds. Une raspberry allume la led de sa voisine. * Comme, il n'y a pas assez de raspberry, nous allons ajouter des arduinos. * [http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.ReferenceMaxi Langage Arduino] == Programmation des Arduinos == Vous devez utiliser la dernière version d'arduino qui se trouve `/opt/arduino-1.6.8/arduino`. Vous commencerez par compiler le programme `blink` qui fait clignoter la led 13 présente sur l'arduino. Pour pouvoir compiler un programme sur le NRF24, il faut ajouter la bibliothèque. **L'usage des bibliothèques Arduino** * Ce qu'il y a de bien dans l'écosystème Arduino, c'est la volonté de faire simple. En effet, pour presque tous les "périphériques" existants il existe un et même souvent plusieurs bibliothèques de fonctions écrites par des "amateurs" souvent très doués. En plus, les sources sont ouvertes, et il est donc possible d'adapter ces codes pour des besoins spécifiques. * Les bibliothèques sont trouvées, en général, en tapant sur un moteur de recherche, la requête "nom-du-module Arduino". Les projets sont souvent sur github. Pour faire court, * Vous téléchargez la bibliothèque (un RF24-master.zip) * Vous ajoutez la bibliothèque dans l'environnement Arduino (import Library) * Vous lancer l'IDE Arduino et dans le menu '''file/exemples''' vous avez un exemple (souvent plusieurs) de la nouvelle bibliothèque. * Vous en choisissez un, vous le chargez, vous le compilez, vous l'uploadez, vous le testez :-) L'idée sera d'allumer la led de l'arduino depuis la raspberry pi ou l'inverse. }}}