Transmission de donnée via TheThingsNetwork avec une carte Nucleo : Différence entre versions

De Ensiwiki
Aller à : navigation, rechercher
(Application)
Ligne 1 : Ligne 1 :
{{Infobox Logiciel
 
| nom = Création de Transmission de donnée via TheThingsNetwork avec une carte Nucleo - projet de RMA 2017/2018
 
| développeurs =  [mailto:Sebastien.Anouilh@grenoble-inp.org Anouilh Sebastien][mailto:guillaume.gremillet@grenoble-inp.org Gremillet Guillaume][mailto:valentin.mazenq@grenoble-inp.org Mazenq Valentin]
 
}}
 
 
 
[[Catégorie:Projets]]
 
[[Catégorie:Projets]]
 
[[Catégorie:Projets Réseaux Mobiles et Avancés]]
 
[[Catégorie:Projets Réseaux Mobiles et Avancés]]
 +
 +
{{
 +
Projet Étudiant
 +
|titre = Création de Transmission de donnée via TheThingsNetwork avec une carte Nucleo
 +
|cadre= Projets Réseaux Mobiles et Avancés
 +
|equipe= [mailto:Sebastien.Anouilh@grenoble-inp.org Anouilh Sebastien][mailto:guillaume.gremillet@grenoble-inp.org Gremillet Guillaume][mailto:valentin.mazenq@grenoble-inp.org Mazenq Valentin]
 +
|encadrants=[mailto:Franck.Rousseau@imag.fr Franck Rousseau]
 +
}}
  
  

Version du 9 avril 2018 à 10:58


Project schedule.png
Titre du projet Création de Transmission de donnée via TheThingsNetwork avec une carte Nucleo
Cadre Projets Réseaux Mobiles et Avancés

Équipe Anouilh SebastienGremillet GuillaumeMazenq Valentin
Encadrants Franck Rousseau


Présentation

Objectifs

Le but de ce projet et de se familiariser avec les réseaux wifi basse consommation (LoRa), en particulier le réseau TheThingsNetwork (TTN). L'objectif est de connecter un capteur (quelconque, prévu comme puce GPS à l'origine puis finalement capteur de température/humidité) L'ensemble du projet a pour but de transmettre des données via TTN pour les afficher sur une interface web.

Les acteurs

L'ensemble du projet est articulé autour de plusieurs acteurs :

  • Un capteur (température/humidité) DHT22
  • Une carte NUCLEO-L073RZ
  • Une shield P-NUCLEO-LRWAN1 pour la carte NUCLEO
  • Le réseau TTN
  • Un serveur hébergé sur Heroku
  • Une machine accédant à ce serveur

Description des acteurs

- Le capteur de température et d'humidité DHT22 est un petit composant qui suit un protocole précis. L'objectif étant de consommer le moins d'énergie possible, la carte Nucléo qui sera branchée au capteur doit se charger de réveiller le capteur et de récupérer les données. La carte fixe pour cela deux tensions de références : une tension LOW et une tension HIGH.

  • La carte envoie pendant 800µs une tension LOW au capteur. Puis il s'arrête et se met en écoute.
  • Le capteur se réveille et prépare les informations de température et d'humidité. Lorsque la carte finit sa transmission de données, le capteur l'informe de son réveil en envoyant une tension LOW pendant 80µs puis une tension HIGH pendant 80 µs.
  • Le capteur envoie ensuite 5 octets de données : les 2 premiers pour la températures, les 2 suivantes pour l'humidité et la dernière comme octet de contrôle. Le capteur se rendort par la suite.

- La carte NUCLEO est une carte de programmation embarquée (comme Arduino ou RasberryPi). Elle s'occupe de recevoir et de traiter les données.

- Le shield est un transmetteur de données. La transmission de données est régulé par les protocoles LoRa et LoRaWan. LoRa définit la manière dont seront envoyé les données. Ce protocole fait la balance entre le débit et la portée. Plus le débit est élevé, plus la portée est faible, et inversement. Ceci est réalisé toujours dans le but d'économie d'énergie et des composants. LoRaWan s'occupe de la construction des messages à envoyer au gateway.

- Pour permettre une connexion en LoRaWan, on utilise un important réseau collaboratif nommé TheThingsNetwork. C'est une plate-forme permettant à un utilisateur de profiter d'un réseau Lora, et de collaborer en déployant sa propre gateway. Sur Grenoble, on peut recenser plus de 15 gateways permettant de couvrir presque intégralement la ville.

- Heroku est un service de cloud s'appuyant sur l'infrastructure d'Amazon Web Service pour proposer le déploiement de multiples applications. On utilise dans ce projet un serveur Heroku pour afficher l'interface avec la température et l'humidité.

Architecture

Nous souhaitons donc recevoir la température et le taux d'humidité sur notre PC connecté à internet. L'architecture (visible à droite) montre comment l'information passe du capteur DHT22 à l'écran de notre ordinateur.

Le capteur de température est branché à la carte NUCLEO-L073RZ, qui s'occupe de recevoir et traiter les données envoyées par celui-ci. Cette carte Nucléo est montée sur un shield P-NUCLEO-L073RZ qui est une carte de traitement branchée à une antenne. C'est cette carte qui va permettre la connexion entre le réseau TheThingsNetwork et le capteur de température. Via le réseau collaboratif, le shield trouve un gateway et envoie les informations sur ce réseau. En configurant l'application sur le site de TTN, on arrive à rediriger les informations sur un serveur Heroku. Il suffit simplement de connecter son PC sur ce serveur Heroku pour obtenir la température et l'humidité de la pièce à distance.

Architecture globale du projet

Prérequis

  • Une carte NUCLEO-L073RZ
  • Une shield P-NUCLEO-LRWAN1 pour la carte NUCLEO pour la connexion au réseau Lora
  • Un compte https://www.thethingsnetwork.org pour vous permettre d'envoyer et recevoir des données sur le réseau Lora
  • Un compte https://developer.mbed.org/ pour utiliser l'environnement de développement en ligne.
  • Un ordinateur pour compiler et déployer le code sur le carte Nucleo


Configuration du compte The Things Network

Connectez vous à votre compte préalablement créé sur The Things Network Créer une nouvelle application en passant par Console -> Applications -> add application Puis renseigner les différents champs de la façon suivante :

 Application ID: Name_Of_Your_Application 
 Description: Description_Of_Your_Application
 Application EUI: Laisser vide
 Handler registration : ttn-handler-eu

Enregistrer ensuite un device à votre application

 Device ID: saisisser_un_id_unique_pour_votre_device
 Device EUI: passer ce champ en génération automatique
 App Key: passer le champ en génération automatique
 App EUI: ne pas toucher

Préparation de la carte STM32

JP1 et JP6 Closed, JP5 sur E5V

S'assurer que les jumper JP1 et JP6 sont fermés et que le jumper JP5 est positionné sur E5V.
Pluger ensuite le shield LoraWan1 sur la carte Nucleo.
Visser l'antenne sur le shield si ce n'est déjà fait.
Brancher la carte au pc .



Déploiement de la solution logiciel

Connectez-vous sur https://developer.mbed.org/
Puis suivre le lien suivant [1]
C'est une demo qui permet de contrôler une LED 3 couleurs et un capteur de luminosité.

L'ensemble de notre implémentation sur la carte est un fork de ce projet de démonstration fourni par Semtech car il nous permet de monitorer l'ensemble des variables (envoi, trame, état du service...) tout en utilisant un code sous licence "Revised BSD".

Le projet dans son ensemble est disponible en téléchargement, import en cliquant ici [2]

Une vue d'ensemble de la carte vous est alors présenté.
Sur la droite un lien vous permet d'importer le projet dans le compilateur, faites le.
Ouvrer ensuite le compilateur en ligne "Mbed compiler" et ouvrez le projet précédemment importer.

Configuration

Nous allons configurer le projet pour que la carte puisse rejoindre le réseau Lora, dans :

 app/commissioning.h 

Et renseigner les variables suivantes avec les informations que vous récupererez sur The Things Network dans console->Applications->votre_app->Devices->votre_device

 LORAWAN_DEVICE_EUI                        
 LORAWAN_APPLICATION_EUI  
 LORAWAN_APPLICATION_KEY
 LORAWAN_DEVICE_ADDRESS
 LORAWAN_NWKSKEY
 LORAWAN_APPSKEY
 #define OVER_THE_AIR_ACTIVATION                     0

Vous pouvez à présent émettre des données sur le réseau en écrivant votre code dans main.cpp

Application

Nous allons implémenter la connexion et la communication avec le réseau dans le fichier :

   app/main.cpp

Cette implémentation nécessite l'import des bibliothèques

   mbed.h
   board.h
   LoRaMac.h /* Communication avec le réseau LoRaWa */
   DHT.h /* Communication avec le capteur dans notre cas */

On déclare un enum d'états possibles de la machine :

   static enum eDeviceState {
       DEVICE_STATE_INIT,
       DEVICE_STATE_JOIN,
       DEVICE_STATE_SEND,
       DEVICE_STATE_CYCLE,
       DEVICE_STATE_SLEEP
   } DeviceState;

On commence par appeler la fonction

   BoardInit()

fournie par la librairie board.h

Dans le code ci-dessous, les blocs de code verbeux ont été éludés par un commentaire multi-lignes

On initialise une variable DeviceState à DEVICE_STATE_INIT On entre ensuite dans une boucle infinie dans la quelle on effectue un switch sur la variable DeviceState, le but étant d'effectuer dans l'ordre ces opération :

   switch (DeviceState) {
   case DEVICE_STATE_INIT:
     {
       /* ----------
          Init LoRa 
          ---------- */
   
       LoRaMacDownlinkStatus.DownlinkCounter = 0;
   
       DeviceState = DEVICE_STATE_JOIN;
       break;
     }

Après avoir initialisé la connexion au réseau, on essaye de le rejoindre

   case DEVICE_STATE_JOIN:
     {
       /* ----------
          Join OTTA or ABP
          ---------- */
   
   #if (OVER_THE_AIR_ACTIVATION != 0)
   
       /* --------------------------------------
          To Join OTAA - Setup a MlmeReq_t query
          -------------------------------------- */
         if (NextTx == true) {
           LoRaMacMlmeRequest( & mlmeReq);
         }
       DeviceState = DEVICE_STATE_SLEEP;#
       else
   
       /* --------------------------------------
   	   To Join ABP - Setup mibReq
   	   -------------------------------------- */
         LoRaMacMibSetRequestConfirm( & mibReq);
       DeviceState = DEVICE_STATE_SEND;
   #endif
       IsNetworkJoinedStatusUpdate = true;
       break;
     }

On envoie ensuite une requête de connexion et envoie la trame/attend la réponse

   case DEVICE_STATE_SEND:
     {
       if (NextTx == true) {
         PrepareTxFrame(AppPort);
         NextTx = SendFrame();
       }
       // Schedule next packet transmission
       TxDutyCycleTime = APP_TX_DUTYCYCLE + randr(-APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND);
       DeviceState = DEVICE_STATE_CYCLE;
       break;
     }

Une fois le paquet envoyé, on programme le réveil pour le prochain envoi de paquet

   case DEVICE_STATE_CYCLE:
     {
       DeviceState = DEVICE_STATE_SLEEP;
   
       // Schedule next packet transmission
       TimerSetValue( & TxNextPacketTimer, TxDutyCycleTime);
       TimerStart( & TxNextPacketTimer);
       break;
     }

On se met en boucle d'attente jusqu'au réveil

   case DEVICE_STATE_SLEEP:
     {
       // Wake up through events
       break;
     }
   default:
     {
       DeviceState = DEVICE_STATE_INIT;
       break;
     }
   
   }
   

Dans tous les cas, on effectue une lecture des donnée du capteur, au cas où ces dernières devraient être envoyées dans la prochaine itération

   // Read DHT22 values
   int err = sensor.readData();
   
   if (err == 0) {
     // Read temperature value
     Temperature = sensor.ReadTemperature(KELVIN);
     Humidity = sensor.ReadHumidity();
   }
   wait(10); // Increase this value for actual use. It's low for testing !

Verification

A partir de la on va pouvoir vérifier que les données sont bien émises sur le réseau.
Pour se faire rendez-vous sur The Things Network, dans l'onglet data de votre device (https://console.thethingsnetwork.org/applications/APPLICATION_ID/data).
Si tout fonctionne vous devriez voir dans les logs les données émises. Félicitation votre carte est donc connecté au réseau Lora !

Intégration

Prérequis

  • Un compte Heroku
  • Avoir initialisé une application nodeJs sur Heroku

Configuration

On veut maintenant récupérer les données émises sur le réseau Lora par notre carte Nucleo.
On va demander à The Thing Network d'envoyer les données sous forme de requêtes POST sur notre serveur.

Sur The Things Network se rendre dans l'onglet intégration de votre device (https://console.thethingsnetwork.org/applications/APPLICATION_ID/integrations)
Créer une nouvelle intégration de type HTTP :

 Process ID
 Access Key default key
 URL URL_DE_VOTRE_APP_HEROKU
 Method POST

Terminez en cliquant sur add intégration
Votre serveur Heroku reçoit maintenant régulièrement des requêtes POST contenant les données émises par votre carte Nucleo

Traitement des données

Il ne vous reste plus qu'à écrire votre application NodeJs pour traiter les données reçues.
La trame reçu à le format suivant :

 { app_id: 'APP_ID',
   dev_id: 'DEV_ID',
   hardware_serial: 'XXXXXXXXXXXX',
   port: 1,
   counter: 0,
   payload_raw: 'VALEUR_EN_BASE64',
   metadata: { time: '2018-01-24T09:59:25.070040542Z' },
   downlink_url: 'https://integrations.thethingsnetwork.org/ttn-eu/api/v2/... 
 }

Les données qui nous intéresses se trouvent donc dans le champs playload_raw
Pour les récupérer il suffit d'exécuter la routine suivante :

  • Conversion du payload_raw de base64 vers Hexa
  • On découpe notre code Hexa en 2 parties, de 0 à 8 (la température en Hexa) puis de 10 à 18 (L'humidité en Hexa)
  • On parse chacune des valeurs Hexa en float (Vous pouvez pour cela utiliser la fonction ci-dessous qui prend en entrée une valeur Hexadecimal et donne en sortie le float correspondant)
 function parseFloat(str) {
   var float = 0,
     sign, order, mantiss, exp,
     int = 0,
     multi = 1;
   if (/^0x/.exec(str)) {
     int = parseInt(str, 16);
   } else {
     for (var i = str.length - 1; i >= 0; i -= 1) {
       if (str.charCodeAt(i) > 255) {
         return false;
       }
       int += str.charCodeAt(i) * multi;
       multi *= 256;
     }
   }
   sign = (int >>> 31) ? -1 : 1;
   exp = (int >>> 23 & 0xff) - 127;
   mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
   for (i = 0; i < mantissa.length; i += 1) {
     float += parseInt(mantissa[i]) ? Math.pow(2, exp) : 0;
     exp--;
   }
   return float * sign;
 }

Vous savez maintenant récupérer les valeurs sur le réseau Lora, il ne vous reste plus qu'a les afficher.
Pour ce faire, nous avons décidé d'utiliser la librairie chart.js[3].