IMA4 2017/2018 P5 : Différence entre versions
(→Description) |
|||
(498 révisions intermédiaires par 3 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | <include nopre noesc src="/home/pedago/pimasc/include/video-CapteurPollution-iframe.html" /> | ||
__TOC__ | __TOC__ | ||
<br style="clear: both;"/> | <br style="clear: both;"/> | ||
Ligne 8 : | Ligne 9 : | ||
==Description== | ==Description== | ||
− | Notre projet consiste à réaliser un réseau de capteurs de pollution. Ceux ci permettront au travers d'une application web et d'une application mobile de visualiser le taux de pollution aux particules fines et polluants chimiques en différents endroits. | + | Notre projet consiste à réaliser un réseau de capteurs de pollution. Ceux ci permettront, au travers d'une application web et d'une application mobile de visualiser le taux de pollution aux particules fines et polluants chimiques en différents endroits d'une carte. Le capteur devra communiquer en bluetooth avec un téléphone pour envoyer les données récoltées sur le serveur. |
− | Nous pourrons ensuite aider les utilisateurs à trouver les chemins les plus appropriés pour se déplacer en étant le moins exposé possible à la pollution. En effet, l'exposition prolongée à un taux élevé de particules fines réduit l'espérance de vie. Connaitre le taux de pollution est donc un enjeu majeur. | + | Nous pourrons ensuite, si le temps nous le permet, ajouter une fonctionnalité permettant d'aider les utilisateurs à trouver les chemins les plus appropriés pour se déplacer en étant le moins exposé possible à la pollution. En effet, l'exposition prolongée à un taux élevé de particules fines réduit l'espérance de vie. Connaitre le taux de pollution est donc un enjeu majeur. |
+ | |||
+ | ==Scénario== | ||
+ | |||
+ | Pedro est intolérant aux particules fines et est cependant un grand sportif. Jusqu’à maintenant, il se contentait de courir sur des tapis roulants dans sa salle de sport. Cependant, il se demandait chaque fois quand est-ce qu’il franchirait le pas et irait courir dehors. Cela tombe bien car sa copine vient de lui offrir un capteur de pollution miniature tenant dans sa poche qui lui permet de connaître les endroits non pollués où il peut courir. Des centaines d’utilisateurs l’utilisent en ce moment et leurs données sont renvoyées en temps réel sur la carte de pollution de la ville qui s’affiche sur son smartphone. Il peut également visualiser où se trouvent les personnes disposants du capteur si celles-ci ont décidé de l’autoriser. | ||
+ | Dans une prochaine mise à jour, Pedro se réjouit d’avance de pouvoir utiliser son application comme un véritable GPS d’air pur : en rentrant son point de départ et sa destination, il pourra obtenir la meilleure route possible selon ses conditions de tolérance. | ||
==Objectifs== | ==Objectifs== | ||
− | * | + | * Élaboration d'un capteur de pollution permettant de détecter différents polluants (particules fines, poussière, résidus de combustion) connecté au réseau LoRaWAN |
− | * Création d'une application web permettant aux utilisateurs de visualiser les taux de pollution détectés par les capteurs en différents endroits de la ville et de pouvoir déterminer le chemin le plus approprié pour leurs déplacements | + | * Création d'une application web permettant aux utilisateurs de visualiser les taux de pollution détectés par les capteurs en différents endroits de la ville et de pouvoir déterminer le chemin le plus approprié pour leurs déplacements. |
* Création d'une application mobile avec les mêmes spécificités que le site web | * Création d'une application mobile avec les mêmes spécificités que le site web | ||
+ | * Élaboration d'un algorithme de machine learning permettant de déterminer le meilleur chemin selon des anciennes données dans le cas d'une panne des capteurs. | ||
=Analyse du projet= | =Analyse du projet= | ||
Ligne 27 : | Ligne 34 : | ||
* Application plume air report donnant la qualité de l'air dans la ville demandée ainsi que des astuces pour éviter la pollution : https://plumelabs.com/en/products/air-report | * Application plume air report donnant la qualité de l'air dans la ville demandée ainsi que des astuces pour éviter la pollution : https://plumelabs.com/en/products/air-report | ||
− | ==Analyse du premier concurrent== | + | ==Analyse du premier concurrent : Bornes implantées dans la ville == |
− | ==Analyse du second concurrent== | + | |
+ | Certaines bornes peuvent permettre d'obtenir la qualité de l'air en dans la ville en temps réel. | ||
+ | Cependant, notre projet aura comme avantage de : | ||
+ | * permettre de connaître précisément le taux de pollution en tous les endroits de la ville et pas seulement en un endroit fixe. | ||
+ | * D'obtenir le taux de pollution sur son téléphone. Il n'y a donc pas besoin de se déplacer pour le connaître. | ||
+ | |||
+ | ==Analyse du second concurrent : Applications, sites web indiquant le taux de pollution== | ||
+ | |||
+ | D'autres applications et sites web permettent d'obtenir un taux de pollution comme Plume : https://air.plumelabs.com/fr/live/lille | ||
+ | Notre projet permettra cependant d'ajouter : | ||
+ | * La possibilité de connaître la pollution dans des endroits plus précis de la ville contrairement à Plume qui donne une valeur par ville. | ||
+ | * Permet à l'utilisateur de faire sa propre mesure à l'aide du capteur. | ||
+ | |||
==Scénario d'usage du produit ou du concept envisagé== | ==Scénario d'usage du produit ou du concept envisagé== | ||
Ligne 42 : | Ligne 61 : | ||
==Réponse à la question difficile== | ==Réponse à la question difficile== | ||
− | Selon certaines documentations, le capteur perd en précision lorsqu'un souffle est appliqué sur le capteur. Il faudrait donc envisager un moyen pour protéger le capteur du vent afin d'obtenir la meilleure précision. Surtout en cas de placement des capteurs sur des | + | Selon certaines documentations, le capteur perd en précision lorsqu'un souffle est appliqué sur le capteur. Il faudrait donc envisager un moyen pour protéger le capteur du vent afin d'obtenir la meilleure précision. Surtout en cas de placement des capteurs sur des véhicules. |
+ | |||
+ | Quelle quantité de données sera envoyée par le smartphone et quelle consommation aura le capteur de particule fine ? | ||
+ | |||
+ | * données doit contenir : la position GPS du capteur, l'heure de la mesure ainsi que la mesure. Cela correspond donc à quelques dizaines d'octets. En fonction du nombre de mesures faites par heure, on peut donc calculer la quantité de données envoyée par heure ou par jour. | ||
+ | * consommation de la carte : | ||
+ | ** ESP32 : environ 100mA en actif et sinon 4mA en slow speed sleep | ||
+ | ** module GPS : ????? | ||
+ | **En prenant une batterie de 2000mA pour ne pas qu'elle soit trop encombrante et en prenant en compte une consommation moyenne de 10mA, nous obtenons une autonomie de 140H. Ce qui correspond à 1 semaine d'autonomie. | ||
=Préparation du projet= | =Préparation du projet= | ||
Ligne 48 : | Ligne 75 : | ||
==Cahier des charges== | ==Cahier des charges== | ||
− | + | ===Réalisation de la carte du capteur :=== | |
+ | |||
+ | |||
+ | ===Polluants pouvant être analysés :=== | ||
* Monoxyde de carbone | * Monoxyde de carbone | ||
* Dioxyde de carbone | * Dioxyde de carbone | ||
* Ozone | * Ozone | ||
− | * Particules en suspension PM2.5,PM10 | + | * Particules en suspension PM2.5 (particules de diamètre inférieurs à 2,5 micromètres),PM10 |
* Dioxyde de souffre | * Dioxyde de souffre | ||
Ligne 60 : | Ligne 90 : | ||
'''Capteur :''' | '''Capteur :''' | ||
− | + | * ESP32 (https://www.amazon.fr/AZ-Delivery-NodeMCU-développement-dénergie-successeur/dp/B071P98VTG/ref=pd_cp_107_1?_encoding=UTF8&psc=1&refRID=Y7HFS1X1WQGBM9VCHXTW) | |
+ | * Module GPS ( si nous ne voulons pas utiliser le GPS du smartphone ) | ||
+ | * Batterie Lithium Ion (https://www.adafruit.com/product/258) | ||
+ | * Adaptateur micro USB | ||
+ | * dfrobot SEN0177 | ||
+ | La raspberry pi peut être remplacée par le module Particle Photon ( Lien [[https://www.lextronic.fr/P37394-module-particle-photon.html]] ) qui comprend un module de données | ||
+ | cellulaires qui amortirait le cout d'un dongle. Le kit de développement de Particle comprend une batterie et une carte SIM prépayée ainsi que plusieurs accessoires supplémentaires. Il serait peut être plus raisonnable d'opter pour le kit. | ||
+ | |||
+ | '''Backend''' | ||
+ | * Base de données NoSQL : RethinkDB ou MongoDB | ||
+ | * Google maps API : service de localisation avec points de cheminements pour choisir le meilleur itinéraire https://developers.google.com/maps/documentation/directions/intro?hl=fr#Waypoints | ||
+ | * Jersey : pour l'API REST et le traitement en temps réel | ||
+ | * RabbitMQ pour le système publish/subscribe | ||
'''Application mobile :''' | '''Application mobile :''' | ||
+ | * Java/Kotlin | ||
'''Application Web :''' | '''Application Web :''' | ||
Ligne 69 : | Ligne 112 : | ||
* Node/AngularJS : pour améliorer la fluidité du site. | * Node/AngularJS : pour améliorer la fluidité du site. | ||
* Bootstrap/Semantic UI : pour faciliter le développement | * Bootstrap/Semantic UI : pour faciliter le développement | ||
− | |||
==Liste des tâches à effectuer== | ==Liste des tâches à effectuer== | ||
Ligne 78 : | Ligne 120 : | ||
{| class="wikitable" | {| class="wikitable" | ||
− | !Tâche !! Prélude !! Heures S1 !! Heures S2 !! Heures S3 !! Heures S4 !! Heures S5 !! Heures S6 !! Heures S7 !! Heures S8 !! Heures S9 !! Heures S10 !! Total | + | !Tâche !! Prélude !! Heures S1 !! Heures S2 !! Heures S3 !! Heures S4 !! Heures S5 !! Heures S6 !! Heures S7 !! Heures S8 !! Heures S9 !! Heures S10 !! Heures S11 !! Heures S12 !! Total |
+ | |- | ||
+ | | Choix du matériel | ||
+ | | 2H | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | Analyse du projet + préparation oral | ||
+ | | 6H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | Création du Back-End de l'application et de l'appli web | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 2H | ||
+ | | 5H | ||
+ | | 6H | ||
+ | | 5H | ||
+ | | 3H | ||
+ | | | ||
+ | | 2H | ||
+ | | 1H | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | Site web | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 6H | ||
+ | | 10H | ||
+ | | | ||
+ | | 12H | ||
+ | | 4H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 10H | ||
+ | | | ||
+ | |- | ||
+ | | Carte/coque capteur | ||
+ | | | ||
+ | | 3H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 2H | ||
+ | | 8H | ||
+ | | 8H | ||
+ | | 6H | ||
+ | | 6H | ||
+ | | | ||
+ | |- | ||
+ | | Programme ESP32 | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 4H | ||
+ | | | ||
+ | | 3H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 2H | ||
+ | | | ||
|- | |- | ||
− | | | + | | Documentation (rethinkDB, rabbitMQ) |
− | |||
| | | | ||
+ | | | ||
+ | | 3H | ||
+ | | 2H | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | |- | ||
+ | | Documentation (Angular JS, facebook authentification, maps) | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | | ||
| | | | ||
| | | | ||
Ligne 89 : | Ligne 249 : | ||
| | | | ||
| | | | ||
+ | |- | ||
+ | | Documentation Android | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 4H | ||
+ | | 8H | ||
+ | | 2H | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 2H | ||
+ | | | ||
+ | |- | ||
+ | | Travail sur l'application Android | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 6H | ||
+ | | 2H | ||
+ | | 5H | ||
+ | | 3H | ||
+ | | 3H | ||
+ | | 5H | ||
+ | | 6H | ||
+ | | | ||
+ | |- | ||
+ | | Wiki | ||
+ | | 1H | ||
+ | | | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 1H | ||
+ | | 1H | ||
+ | | | ||
+ | | | ||
+ | | 1H | ||
+ | | 2H | ||
+ | | | ||
+ | |- | ||
+ | | Informations/Interprétation mesures | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | 1H | ||
+ | | | ||
| | | | ||
| | | | ||
Ligne 95 : | Ligne 315 : | ||
|} | |} | ||
+ | ==Prologue== | ||
+ | |||
+ | * Préparation de l'oral : | ||
+ | Description du projet : quels sont les objectifs à remplir, scénario d'usage permettant de se rendre compte de l'utilité du projet et analyse des concurrents pour connaître ce qui existe déjà et savoir ce que nous devons ajouter dans notre projet pour nous démarquer. | ||
+ | * Choix du matériel et des technologies utilisées | ||
+ | * Après l'oral : réponse à la question sur l'autonomie de la batterie ainsi que sur la quantité de données envoyées | ||
− | |||
==Semaine 1== | ==Semaine 1== | ||
+ | |||
+ | * Vérification du schéma électronique et de la carte permettant d'alimenter et de contrôler notre capteur. | ||
+ | |||
+ | * Nous avons finalement changé de batterie. En effet, une batterie de 5V nous paraissait plus adaptée au fait que nous devons alimenter le microcontrôleur en 3,7V et le capteur en 5V. Nous obtiendrons un meilleur rendement en réalisant une baisse de tension qu'une augmentation de tension. La batterie sera un peu plus volumineuse mais nous permettra d'alimenter notre capteur plus longtemps. Nous avons donc ajouté un connecteur micro-usb que nous souderons sur la carte et qui nous permettra de l'alimenter en 5V. | ||
+ | |||
==Semaine 2== | ==Semaine 2== | ||
+ | |||
+ | * Documentation sur la base de donnée rethinkDB afin de bien comprendre son fonctionnement ainsi que le gestionnaire de queue de message rabbitMQ. | ||
+ | Ces recherches vont nous permettre d'être plus efficace par la suite et de savoir quel est le meilleur moyen d'utiliser cette base de donnée. | ||
+ | |||
+ | ==Semaine 3== | ||
+ | |||
+ | * Installation des environnements de travail sur nos ordinateurs ainsi que sur un serveur pour nous permettre de travailler tous les deux sur les mêmes données : tomcat pour le serveur java, rethinkDB pour la base de données. Mais nous avons eu un problème car l'espace disponible sur le serveur que nous possédons n'est pas suffisant. | ||
+ | |||
+ | * Début de la programmation du code serveur : Mise en place de l'architecture temps-réel et mise en avant des problèmes à résoudre : documentation sur les queues et les websockets. Nous nous somme accordé sur l'architecture schématisé par la suite : <br/> | ||
+ | |||
+ | [[Fichier:SchemaBackendUnwheeze.png|500px|Architecture du back-end]] | ||
+ | <br/> | ||
+ | Problème : réaliser un code en boucle infinie pour pousser les données vers la queue, ou uniquement garder une connection WS active ? | ||
+ | |||
+ | ==Semaine 4== | ||
+ | |||
+ | ==== Site web ==== | ||
+ | |||
+ | * Création de la base de projet web. Nous avons désormais une base de projet tournant avec Node, angular, rethinkdb et avec les fonctionnalités basiques. | ||
+ | Nous avons également étudié la documentation qui va nous permettre d'implémenter une authentification du client via facebook par exemple et d'utiliser l'API de google maps. | ||
+ | * Durant la séance suivante, nous avons pu utiliser l'api de google maps pour obtenir leur carte sur notre site web. Nous avons pour cela dû nous créer une clé d'identification et insérer leur script dans la page. Puis nous avons ajusté celle ci afin qu'elle prenne l'ensemble de la largeur du site. Enfin, nous avons réussi à manipuler les marqueurs afin de pouvoir indiquer les endroits où des mesures de taux de pollution ont été effectuées. Pour le moment, ces positions ont été fixées manuellement. Mais nous modifierons prochainement le code afin que les données soient récupérées dans la base de données et affichées dynamiquement sur la carte. | ||
+ | |||
+ | ==== Serveur ==== | ||
+ | |||
+ | * Réalisation des endpoints REST pour l'utilisateur, mise en place du code associé aux actions sur la base de donnée. Mise en place des moyens de sécurisation (JWT en particulier). Réalisation de testbench pour tester ce qui à été mentionné précédemment. | ||
+ | Début de la réalisation de la partie temps réel. | ||
+ | |||
+ | ==Semaine 5== | ||
+ | |||
+ | ==== Site web ==== | ||
+ | |||
+ | * Ajout de la librairie semantic UI au projet web pour permettre un design plus agréable pour l'utilisateur mais aussi faciliter son utilisation. Cependant, nous avons eu quelques problèmes pour faire cohabiter toutes les librairies sur le projet web. Nous avons donc recréé un projet Web fonctionnant avec du javascript classique plutôt que Angular afin d'avoir une interface fonctionnelle le plus rapidement possible. En effet, nous devrons pouvoir faire des tests avec le capteur lorsque nous recevrons les composants. Nous retenterons de faire fonctionner les différents modules tous ensemble sous angular à la fin du projet si le temps nous le permet. | ||
+ | * Ajout de l'apparition des fenêtres lorsque l'utilisateur clic sur les markers de google maps correspondants aux points de mesure de pollution. Ceux ci indiqueront le taux de pollution calculé pour chaque polluant, la date et l'heure de la mesure ainsi que l'adresse à laquelle la mesure a été prise. Enfin, nous afficherons le nom et la photo de la personne qui a pris la mesure si celui ci l'accepte. La fenêtre affiche également l'adresse du point cliqué (celle ci est récupérée à l'aide d'une requête à l'API de google qui converti le point exprimé en latitude/longitude, en adresse réelle). | ||
+ | |||
+ | Nous pourrons également ajouter la météo du moment où la mesure a été prise. En effet, celle ci peut influer sur la précision de la mesure. Et nous pourrons également implémenter un système de vérification des mesures prises. Si une données est aberrante par rapport aux données prisent aux alentours par d'autres membres, nous ne la prendrons pas en compte. | ||
+ | |||
+ | ==Semaine 6== | ||
+ | |||
+ | ==== Capteur ==== | ||
+ | |||
+ | * Nous avons reçu une partie de notre commande de composants dont l'ESP32. Nous avons donc pu commencer à travailler sur celui ci. Pour le programmer, 3 choix s'offraient à nous : | ||
+ | ** Le logiciel PlatformIO : https://platformio.org/ | ||
+ | ** Le framework esp-idf disponible sur github : https://github.com/espressif/esp-idf | ||
+ | ** Le logiciel et langage arduino | ||
+ | Nous nous sommes penchés vers cette dernière solution qui étaient celle proposée dans la datasheet de notre composant sur sparkfun. Certaines sources menaient à penser que des fonctionnalités n'étaient pas encore implémentées dans le module de développement arduino. Cependant, le projet ayant bien avancé depuis la dernière année, les fonctionnalités dont nous avons besoin (notamment le bluetooth) semblent bien présentes. Nous avons donc suivi les quelques étapes décrites sur ce lien pour installer le module supplémentaire permettant de programme l'ESP32 sur le logiciel arduino : | ||
+ | https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide?_ga=1.189350435.90086807.1452767181#installing-the-esp32-arduino-core | ||
+ | |||
+ | Nous avons ensuite réalisé le programme permettant d'envoyer les données et de les recevoir via bluetooth sur l'ESP32. Pour cela, nous devons importer les librairies BLE sur arduino. Et au moyen du langage C++, nous avons défini l'appareil ainsi que le serveur BLE. Celui ci signale donc la présence de notre ESP32 comme étant un appareil bluetooth auquel on peut s'appairer. | ||
+ | De plus, nous avons défini des fonctions de callback qui permettent de signaler lorsqu'un appareil se connecte ou se déconnecte mais aussi de recevoir un caractère depuis le téléphone via bluetooth. Dans le code principal, nous envoyons un nombre flottant qui s'incrémente toutes les secondes. Et lorsqu'un caractère est reçu, il s'affiche. | ||
+ | |||
+ | Nous avons également commencé l'application android permettant de communiquer avec l'ESP32. Celle ci est pour l'instant minimaliste et ne permet que de se connecter à notre microcontrôleur, d'envoyer des données en appuyant sur un bouton ou d'en recevoir à l'aide d'un autre bouton. Cela nous a donc permis de vérifier que le système de communication bluetooth fonctionnait correctement. | ||
+ | Pour réaliser notre application et faire fonctionner la librairie BLE bluetooth d'android, il ne faut pas oublier de demander les permissions pour le bluetooth et la localisation qui sont indispensables. Sinon, le téléphone n'arrive pas à se connecter à l'ESP32. | ||
+ | Par la suite, nous modifierons l'application android pour n'avoir qu'un seul bouton pour demander une mesure et l'afficher. | ||
+ | Le code de l'Arduino lui, devra se mettre en attente tant qu'un caractère précis n'est pas reçu. Puis, lors de sa réception, communiquera avec notre capteur de pollution pour récupérer les données et les envoyer sur l'application Android. | ||
+ | |||
+ | Voici le résultat sur la vidéo suivante, qui démontre que la connexion entre notre microcontroleur et l'appli android fonctionne : | ||
+ | |||
+ | <center><include iframe src="https://youtube.com/embed/0CjwiqLO1qE" width="320px" height="320px" frameborder="0" scrolling="yes"/></center> | ||
+ | |||
+ | ==== Serveur ==== | ||
+ | |||
+ | Quant au coté serveur, les appels permettant de récupérer l'ensemble des données de l'air ou plus de détails sur une donnée particulière ont été réalisés. | ||
+ | Nous avons également mis en place le serveur websocket. Plus de documentation est nécessaire car nous ne savons toujours pas si l'API websocket gère les threads par elle même. Dans le cas contraire, il sera nécessaire de mettre en place un système de multithreading. Pour le moment, les sockets sont disposées sur deux threads. Un thread principal qui permet de recevoir les données du client (par exemple des données de l'air) et un thread secondaire, connecté aux changefeeds de rethinkdb, qui permettent de pousser tout changement sur la table vers un curseur infini. Lors de chaque changement du changefeed, les données sont envoyées aux clients. Ils sont d'abord traités par un décodeur qui permet de parser le JSON reçu, composé d'un champ old_val et new_val. Afin de simplifier, nous ne renvoyons que le champ non vide. Dans le cas ou les deux sont remplis, nous renvoyons les deux champs afin de comparer l'ancienne et nouvelle valeur. | ||
+ | |||
+ | ==Semaine 7== | ||
+ | |||
+ | ==== Site web ==== | ||
+ | [[Fichier:screen_site_web.png|400px|thumb|right|screen du site web]] | ||
+ | |||
+ | * Le site web récupère désormais les données issues de l'API REST. Nous utilisons pour cela les xhtmlHTTPrequest javascript. Cette connexion est pour l'instant effectuée en localhost en faisant tourner en parallèle la base de données rethinkDB ainsi que l'API REST. 2 requêtes sont alors nécessaires pour récupérer tous les points de mesure présents dans la base de données : | ||
+ | ** La première requête à l'adresse "http://localhost:8080/unwheeze/auth/clientToken" avec le header 'Authorization':'Basic -token-' pour récupérer une API key qui sera utilisée dans la requête suivante. | ||
+ | ** La deuxième requête à l'adresse "http://localhost:8080/unwheeze/airData/getAirCollection" avec le header 'X-Api-Key': -API key-. | ||
+ | |||
+ | Ces deux requêtes sont effectuées de manières synchrone car nous avons besoin que celles ci soient effectuées afin de pouvoir continuer le reste du processus. Mais nous pourrons l'améliorer en l'utilisant de manière asynchrone. | ||
+ | De plus, pour effectuer des requêtes en local, nous avons remarqué que nous devions lancer le navigateur en désactivant les sécurité. Par exemple : chromium-browser --disable-web-security --user-data-dir sur ubuntu avec chromium. | ||
+ | |||
+ | * Nous utilisons désormais Highchart pour afficher des graphs sur notre site web. Ces graphs afficherons l'évolution de la pollution au cours du temps au niveau du point cliqué par l'utilisateur. Ces graphs devront donc être modifiés pour prendre en compte les différents points de mesure de pollution se trouvant aux alentours du point cliqué durant les dernières 24H par exemple. Ceci fera donc l'objet d'une nouvelle requête à l'API Rest pour récupérer l'ensemble des points de mesures à afficher sur les graphs lors d'un clic. | ||
+ | Le point délicat étant de pouvoir retrouver quel point de mesure a été cliqué par l'utilisateur et pouvoir envoyer une requête appropriée à l'API. | ||
+ | Nous voulons également laisser à l'utilisateur le choix de l'étendue des points qu'il souhaite comparer ainsi que la durée temporelle sur laquelle il souhaite voir l'évolution de la pollution. | ||
+ | L'affichage des graphs a nécessité un bon moment de documentation quant a l'utilisation de l'API de Highchart mais nous sommes désormais capable d'afficher un graphique de l'évolution des 3 polluants dans la fenêtre correspondant au marker cliqué par l'utilisateur. Le graphique contient les évolutions au cours du temps des 3 polluants. L'abscisse représentant la date à laquelle la mesure a été effectuée et l'ordonnée représentant le taux de PM25, PM10 ou PM1 mesuré à cet instant en μg/m3. Une légende est également présente en haut à gauche du graphique afin d'expliquer à l'utilisateur quelle courbe correspond à quel polluant. Enfin, en dessous du graphique, on retrouve les informations relatives à la mesure effectuée en ce point précis de la carte. On peut alors trouver le taux de pollution sur chaque polluant ainsi que l'heure exacte de la mesure. | ||
+ | |||
+ | * Nous avons également implémenté la Heatmap sur la carte google map. Celle-ci nous donnera sans cliquer une indication de la pollution que l'on trouve aux différents endroits de la ville. Elle affichera en rouge les points avec le plus de pollution et en vert les zones les moins polluées et à privilégier par l'utilisateur. | ||
+ | |||
+ | ==Semaine 8== | ||
+ | ==== Capteur ==== | ||
+ | |||
+ | * Nous avons reçu notre capteur et avons commencé à l'utiliser grâce à un Arduino que nous maîtrisons davantage pour le tester. Nous avons bien réussi à récupérer les valeurs sur l'Arduino et sommes donc passé à l'ESP32. Nous avons alors dû réaliser le programme qui attend de recevoir un caractère par bluetooth depuis le téléphone pour envoyer les valeurs du capteur de pollution sur le téléphone. Ces valeurs sont récupérées via le protocole série suivant : | ||
+ | |||
+ | Baudrate: 9600, Parité: None; Stop Bits: 1; longueur du paquet : 32 octets. | ||
+ | Description du paquet : | ||
+ | |||
+ | {| class="wikitable" style="width:100%;text-align:center" | ||
+ | ! style="padding: 5px;"| | ||
+ | nom | ||
+ | | Start char 1 | ||
+ | | Start char 2 | ||
+ | | length | ||
+ | | data 1 | ||
+ | | data 2 | ||
+ | | data 3 | ||
+ | | data 4 | ||
+ | | data 5 | ||
+ | | data 6 | ||
+ | | data 7 | ||
+ | | data 8 | ||
+ | | data 9 | ||
+ | | data 10 | ||
+ | | data 11 | ||
+ | | data 12 | ||
+ | | data 13 | ||
+ | | check data sum | ||
+ | |- | ||
+ | ! style="padding: 5px;" | | ||
+ | Nombre d'octets | ||
+ | | 1 | ||
+ | | 1 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | | 2 | ||
+ | |- | ||
+ | ! style="padding: 5px;" | | ||
+ | signification | ||
+ | | 0x42 | ||
+ | | 0x4d | ||
+ | | 2*13+2=28 | ||
+ | | concentration de PM1.0 en ug/m3 | ||
+ | | concentration de PM2.5 en ug/m3 | ||
+ | | concentration de PM10.0 en ug/m3 | ||
+ | | test data interne | ||
+ | | test data interne | ||
+ | | test data interne | ||
+ | | nombre de particules de diamètre supérieur à 0.3um pour 0.1 litre d'air | ||
+ | | nombre de particules de diamètre supérieur à 0.5um pour 0.1 litre d'air | ||
+ | | nombre de particules de diamètre supérieur à 1.0um pour 0.1 litre d'air | ||
+ | | nombre de particules de diamètre supérieur à 2.5um pour 0.1 litre d'air | ||
+ | | nombre de particules de diamètre supérieur à 5.0um pour 0.1 litre d'air | ||
+ | | nombre de particules de diamètre supérieur à 10.0um pour 0.1 litre d'air | ||
+ | | test data interne | ||
+ | | somme de tous les octets précédents | ||
+ | |} | ||
+ | |||
+ | Pour vérifier qu'une mesure a été prise, on va regarder le moment où l'on reçoit le caractère 0x42 sur la liaison série. Cela signifie alors que les 31 bits qui suivent sur la liaison série représentent la trame. Celle ci est donc enregistrée dans notre variable buf qui est un tableau de char de longueur 31 pour contenir tout le reste de la trame. Nous analysons ensuite celle-ci afin de vérifier que les octets reçus représentent bien le message envoyé par le capteur et qu'aucune erreur n'a été introduite durant la transmission. Nous vérifions donc que le premier octet de la trame est bien l'octet 0x4d puis nous vérifions que le checksum final est bien égal à la somme de tous les octets de la trame. Enfin, après nous être assuré que la trame est correcte grâce aux vérifications précédentes, nous récupérons les octets 5 et 6 pour le PM1, 7 et 8 pour le PM2.5 et les octets 9 et 10 pour le PM10. | ||
+ | Ces valeurs, une fois récupérées doivent être converties en string afin de pouvoir les envoyer au téléphone qui se chargera de les enregistrer et de les afficher à l'utilisateur. | ||
+ | Nous arrivons alors à nous connecter, et recevoir sur les 3 champs différents les valeurs de PM10 PM2.5 et PM01 comme le montre la vidéo suivante : | ||
+ | |||
+ | <center><include iframe src="https://www.youtube.com/embed/XzDKDh4UMxE" width="320px" height="320px" frameborder="0" scrolling="yes"/></center> | ||
+ | |||
+ | Cependant, notre programme devra par la suite utiliser le pin SET du capteur de pollution pour le laisser en mode faible consommation d'énergie tant que nous ne l'utilisons pas. | ||
+ | |||
+ | ==== Site web ==== | ||
+ | |||
+ | [[Fichier:SiteVariationDistance.png|1000px|right|Possibilité de modifier les distances et durées prises en compte]] | ||
+ | |||
+ | <br/><br/><br/><br/> | ||
+ | * Nous avons apporté des modifications au site web afin de faire des ajustements esthétiques et permettre davantage de fonctionnalités graphique pour visualiser l'évolution de la pollution sur le site web. Il est notamment possible d'afficher les graphiques selon l'intervalle de temps et la distance choisie par l'utilisateur au moyen d'un curseur. L'utilisateur doit toujours cliquer sur un marker afin de visualiser l'évolution de la pollution autour de ce point mais il lui est désormais possible de cliquer sur le petit "+" en bas à droite de la fenêtre du marker pour ouvrir un volet sur le côté droit de la page. Celui ci affiche 3 graphiques représentant l'évolution des 3 polluants différents et permet de modifier l'intervalle de temps et de distance pris en compte pour afficher ces évolutions au moyen de 2 curseurs. | ||
+ | <br/> | ||
+ | L'utilisateur peut alors choisir le nombre d'heures durant lesquelles il souhaite que l'analyse soit réalisée (par pas de 1h allant de 1h à 24h puis par pas de 1 jour allant de 1 à 3 jours). L'utilisateur peut également sélectionner dans quel périmètre il souhaite prendre en compte les données relevées autour du point sélectionné. Ce périmètre est représenté par un cercle bleu qui s'affichage lorsque l'on maintient enfoncé le curseur de distance afin de mieux visualiser la modification en cours. Le périmètre autour du point sélectionné peut être modifié par pas de 100m de rayon allant de 0 à 2km. | ||
+ | On peut alors voir sur cette capture d'écran que le graphique est modifié en temps réel lorsque l'on actionne l'un des deux curseurs. | ||
+ | <br/><br/><br/><br/> | ||
+ | |||
+ | |||
+ | * Nous avons également modifié le système de heatmap qui est désormais réalisé à l'aide de heatmap.js. La heatmap de google que nous utilisions précédemment ne correspondait en effet pas à nos attentes car elle prenait en compte le poids de chaque point ainsi que leur concentration. Or, nous ne voulions prendre en compte que le poids de chaque point évalué afin que les localisations où beaucoup de mesures ont été effectuées ne soient pas considérés comme plus polluées que les localisations avec une seul mesure réalisée. La heatmap que nous utilisons désormais fonctionne donc sous forme d'interpolation. La densité des points n'est donc plus prise en compte et seul le poids donné à chaque point permet de modifier la couleur d'apparence sur la carte. Heatmap.js étant compatible avec la carte offert par maps comme le montre la documentation citée en bas de wiki, ceci nous a donc permis de l'implémenter plus facilement. | ||
+ | Nous avons également ajouté 4 boutons en haut à droite de la page pour permettre à l'utilisateur de choisir le type de polluant avec lequel il souhaite que la heatmap soit mise à jour. Le bouton le plus à gauche représente la moyenne des 3 polluants (Il représente la heatmap affichée par défaut lors de l'arrivée de l'utilisateur sur le site). Les 3 autres boutons permettent de mettre à jour la heatmap en fonction d'un polluant en particulier. Le type de heatmap active est indiqué par la couleur d'un des 4 boutons qui devient alors plus foncé que les autres. | ||
+ | |||
+ | ==== Analyse ==== | ||
+ | |||
+ | * Nous avons pu contacter une personne s'occupant de l'analyse des données de pollution sur Lille qui nous a expliqué comment vérifier les valeurs obtenues sur notre capteur. En effet, 2 stations de mesures sont disponibles sur Lille. Une stations de à proximité du traffic : Boulevard de Leeds 59700 Lille à coté du Crown Plaza et une station bruit de fond à coté de l'école Lakanal à fives (Groupe Lakanal Campau - Rue du long Pot 59800 Lille Fives). | ||
+ | Les valeurs sont prises à hauteur d'homme pour simuler au mieux la pollution à laquelle un être humain peut être exposé en ville. | ||
+ | |||
+ | Nous devrons donc vérifier si notre capteurs ne sous estime pas la pollution en ville ou au contraire ne la surestime pas. En effet, pour l'instant, nous avons seulement pu vérifier superficiellement que les valeurs étaient correctes. Dans notre maison, les valeurs sont entre 0 et 8 ug/m3 pour chaque polluant alors que à coté du pot d'échappement d'une voiture, nous arrivons jusqu'à des valeurs de 127ug/m3. Lorsque notre projet sera plus avancé, nous ferons donc les mesures juste à coté de ces deux stations afin de vérifier la précision de nos mesures et de vérifier que notre capteur est bien précis en comparant les valeurs avec celles disponibles sur le site de l'ATMO : http://www.atmo-hdf.fr/acceder-aux-donnees/mesures-des-stations.html | ||
+ | |||
+ | ==== API REST ==== | ||
+ | * Nous avons implémenté la quasi totalité des fonctionnalités REST. | ||
+ | |||
+ | L'API est organisée en trois différentes classes de requêtes, dont deux se révèlent particulièrement importantes pour notre projet. | ||
+ | |||
+ | L'une des deux premières classes de requêtes correspond aux requêtes de sécurité, qui permettent d'obtenir des clés d'API ou un token utilisateur afin de réaliser des actions nécessitants des privilèges. | ||
+ | Ces méthodes d'obtention de clés sont primordiales : aucune requête ne peut être réalisée sans la spécification des clés obtenues dans un header. | ||
+ | La clé d'API permet de réaliser les requêtes correspondantes à la classe des requêtes des données de l'air. Il n'est pas nécessaire d'être authentifié pour l'obtenir. | ||
+ | Le tableau suivant décrit les requêtes possibles de cette classe. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! style="font-weight:bold;" | URL | ||
+ | ! style="font-weight:bold;" | Méthode | ||
+ | ! style="font-weight:bold;" | X-Api-Key | ||
+ | ! style="font-weight:bold;" | Consomme | ||
+ | ! style="font-weight:bold;" | Produit | ||
+ | ! style="font-weight:bold;" | Commentaire | ||
+ | |- | ||
+ | | /auth/clientToken | ||
+ | | style="text-align: center;" | GET | ||
+ | | style="text-align: center;" | Non | ||
+ | | style="text-align: center;" | Aucun | ||
+ | | style="text-align: center;" | JSON | ||
+ | | Retourne un objet JSON avec un champ key | ||
+ | contenant la clé. | ||
+ | |- | ||
+ | | /auth/token | ||
+ | | GET | ||
+ | | Non | ||
+ | | style="text-align: center;" | Aucun | ||
+ | | JSON | ||
+ | | Retourne un Json Web Token (JWT) à l'utilisateur. | ||
+ | Le header doit contenir un champ Authorization contenant son email et son mot de passe | ||
+ | de la forme email:mdp encodé en base 64. Le JWT est valide uniquement pour une durée limitée. | ||
+ | |} | ||
+ | |||
+ | Le tableau suivant regroupe la liste des requêtes possibles de la classe des données de l'air. Cette classe de requêtes permet d'insérer une donnée de l'air à travers une requête POST, dont les spécifications sont précisées par la suite. Elle permet, à travers plusieurs requêtes GET de récupérer une donnée de l'air spécifique, l'ensemble des données ou encore, les données les plus proches d'un point particulier. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! style="font-weight:bold;" | URL | ||
+ | ! style="font-weight:bold;" | Méthode | ||
+ | ! style="font-weight:bold;" | X-Api-Key | ||
+ | ! style="font-weight:bold;" | Consomme | ||
+ | ! style="font-weight:bold;" | Produit | ||
+ | ! style="font-weight:bold;" | Commentaires | ||
+ | |- | ||
+ | | /airData/putAirData | ||
+ | | POST | ||
+ | | style="text-align: center;" | Oui | ||
+ | | style="text-align: center;" | JSON | ||
+ | | style="text-align: center;" | JSON | ||
+ | | Consommes un élément suivant le modèle | ||
+ | de l'objet AirData, décrit par la suite. | ||
+ | |- | ||
+ | | /airData/getAirCollection/ | ||
+ | | GET | ||
+ | | Oui | ||
+ | | Aucun | ||
+ | | JSON | ||
+ | | Renvoi un tableau JSON de tout les points mesurés | ||
+ | présents dans la base de donnée. | ||
+ | |- | ||
+ | | /airData/getAirData/{id} | ||
+ | | GET | ||
+ | | Oui | ||
+ | | Aucun | ||
+ | | JSON | ||
+ | | Retourne un point mesuré en particulier, spécifié dans | ||
+ | l'URL par son UUID. | ||
+ | |- | ||
+ | | /airData/getNearest/{location} | ||
+ | | GET | ||
+ | | Oui | ||
+ | | Aucun | ||
+ | | JSON | ||
+ | | Retourne un tableau JSON contenant | ||
+ | la liste des points les plus proches du point | ||
+ | specifié selon le format latitude,longitude dans | ||
+ | l'URL. L'objet retourné dispose de la distance dans | ||
+ | un champ dist et du point en question dans le champ | ||
+ | doc. | ||
+ | |} | ||
+ | |||
+ | L'ensemble des requêtes, comme indiqué dans le tableau, nécessitent la présence d'une clé d'API dans le header X-Api-Key. Une clé invalide renvoi un code 403 (accès refusé). La spécification du header content-type est également nécessaire dans le cas de la requête d'insertion. Les requêtes consomment du JSON, il faudra donc spécifier application/json. | ||
+ | |||
+ | Enfin, une donnée insérée doit contenir nécessairement les champs suivants : | ||
+ | { | ||
+ | "location":"104.28,32.25", | ||
+ | "pm25":254.5, | ||
+ | "pm10":500, | ||
+ | "pm1":250, | ||
+ | "geolocation": POINT(104.25,32.25), | ||
+ | "datetime":"2018-04-02T22:55:58.545Z" | ||
+ | } | ||
+ | |||
+ | L'id est généré automatiquement. Le champ geolocation contient un élement JSON de type Point défini par RethinkDb. Un java bean de cet objet JSON est disponible sous la package bean du code source de notre API, défini par la classe GeoBean. | ||
+ | Il n'est normalement pas nécessaire de se soucier des champs geolocation et datetime, l'API les ajoutants automatiquement. | ||
+ | |||
+ | Ce format d'insertion correspond également au JSON renvoyé lors des requêtes GET, à la seule différence que le champ ID est également retourné. | ||
+ | |||
+ | ==== Application mobile ==== | ||
+ | |||
+ | * L'application Android se connecte maintenant au capteur et permet de réaliser une mesure et de l'envoyer sur le serveur. Nous avons choisi BLE (introduit par Bluetooth 4.0) afin de mettre en place la liaison bluetooth et minimiser l'impact de l'utilisation sur la batterie. En effet, BLE permet de ne transférer des données que sur demande, au contraire d'une liaison bluetooth classique. Ce moyen de communication atteint un maximum d'utilisation de 15 mA, tandis que le Bluetooth classique peut drainer la batterie avec des pics à 150 mA. | ||
+ | |||
+ | * Nous utilisons le framework Volley afin de réaliser les requêtes HTTP. | ||
+ | Nous travaillons maintenant à mettre en place une connexion websocket sur le smartphone, tournant en tâche de fond et notifiant l'utilisateur lors de la réception d'un message, réalisant les actions nécessaires, telles que l'affichage sur la carte. | ||
+ | |||
+ | ==Semaine 9== | ||
+ | |||
+ | ==== Capteur ==== | ||
+ | |||
+ | * Maintenant que notre capteur de pollution fonctionne, nous avons commencé le pcb pour faire fonctionner le capteur sans breadboard. Cependant, nous n'avons pas trouvé de fichiers déjà réalisés pour modéliser notre ESP32 ainsi que notre capteur de pollution que ce soit sur altium ou eagle. Nous avons donc décidé de redessiner les fichiers schematic et pcb pour les deux composants sur altium car nous avions eu des cours sur ce logiciel l'année dernière. | ||
+ | Le premier travail fut donc de réaliser les footprints et schematic de chacun de nos composants. Le plus long était de prendre en main le logiciel et comprendre comment réaliser au mieux les fichiers de footprints des composants. | ||
+ | Pour cela, nous avons regardé des tutoriels vidéos sur internet (https://www.youtube.com/watch?v=nYI8sw__9_Y) expliquant comment créer un nouveau composant. Nous devions donc créer premièrement une schematic Library pour notre composant sur laquelle on dessine notre composant ainsi que le nom des pins qui seront utilisés sur celui ci. Par la suite, nous créons un PCB Library pour dessiner la footprint du composant. Enfin, il faut associer le fichier .pcb au fichier .schematic. Il faut alors être vigilent à ce que chaque pin sur le fichier schematic et pcb ai bien le même nom pour être reliés ensemble lors du routage. | ||
+ | |||
+ | L'empreinte de l'ESP32 fut la plus simple à réaliser car les pins étaient tous espacés de la distance réglementaire de 2,54mm. Il a donc suffit de fixer la grille à 1,27mm afin de pouvoir poser chaque pastille espacée de 2.54mm. Notre ESP32 étant composé de 20 pastilles de chaque coté. | ||
+ | |||
+ | [[Fichier:coque_capteur_pollution.png|400px|thumb|right|première esquisse de la coque du capteur de pollution]] | ||
+ | |||
+ | * Nous avons également commencé à dessiner les schémas de notre coque et un premier modèle 3D sur Freecad qui encapsulera tous les composants de notre capteur. Cette coque devra contenir la batterie, le capteur, l'ESP32 et un interrupteur pour allumer et éteindre le capteur. De plus, nous devrons ajuster la largeur de la coque à celle du PCB afin que celle ci soit la plus petite possible et que tous les composants restent bien fixés lors des déplacements de l'utilisateur. | ||
+ | |||
+ | ==== Back-end ==== | ||
+ | |||
+ | * Le back-end est quasiment complété. Il ne manque qu'à le mettre sur le cloud. Pour cela, deux choix sont possibles après discussion avec nos enseignants : soit utiliser une plateforme tierce, soit utilisée une machine virtuelle fournie par Mr Redon. Il s'agira d'une décision à prendre par la suite, lorsque nous nous assurerons que l'API et le serveur websocket fonctionnent sans aucun soucis. | ||
+ | Nous avons également fini d'implémenter les méthodes retournant un tableau JSON des points les plus proches à un point passé en paramètre de l'URL. | ||
+ | |||
+ | ==== Serveur websocket ==== | ||
+ | |||
+ | * Nous avons complété la connexion websocket sur l'application | ||
+ | |||
+ | Nous avons mis en place le serveur websocket afin de maintenir une communication bilatérale entre le serveur et les clients. Nous prenons avantage de la fonctionnalité "d'abonnement" à une table, décrite précédemment, afin d'implémenter le caractère temps réel de l'application. Ainsi, à l'ouverture de la connexion websocket, un nouveau thread est lancé afin de traiter de manière asynchrone les demandes d'abonnement à la table contenant les données relatives à l'air. | ||
+ | Ainsi, à chaque insertion ou modification d'une donnée, un message est envoyé à tout les clients abonnés, contenant le nouvel objet ajouté, selon la syntaxe décrite dans la partie précédente. | ||
+ | A la réception d'un message, le serveur insère la donnée dans la base de donnée. | ||
+ | |||
+ | Le fonctionnement interne du websocket est très simple, notamment grâce à l'implémentation native des websockets sous Jersey. | ||
+ | |||
+ | * Nous réalisons également de nombreux test afin de vérifier le bon fonctionnement de notre API. Ces tests sont réalisés en java en se plaçant dans un package test, en créant une classe ayant le nom de la classe à tester, suivie d'un suffixe 'Test' et en héritant de la classe TestCase. Chaque méthode à tester suit la même idéologie de nommage et est précédée d'une annotation @Test. | ||
+ | |||
+ | ==== Application mobile ==== | ||
+ | |||
+ | * Nous avons commencé l'écriture du service Android qui tournera en fond. Nous utiliserons un BroadcastReceiver afin de communiquer avec l'activité principale de l'application et d'afficher les valeurs reçues sur la carte. | ||
+ | * Nous avons également beaucoup travaillé sur le design de l'application afin de faire en sorte que la compréhension du fonctionnement soit intuitive. | ||
+ | |||
+ | ==Semaine 10== | ||
+ | |||
+ | ==== Capteur ==== | ||
+ | |||
+ | [[Fichier:mesuresPiedCoulisse.jpg|200px|right|vignette|upright=1.2|mesures avec le pied à coulisse]] | ||
+ | [[Fichier:pinInverseCapteur.jpg|200px|left|vignette|upright=1.2|pins inversés sur l'adaptateur du capteur de pollution]] | ||
+ | |||
+ | * Nous avons modifié le programme de l'ESP32 afin que celui ci passe en lower consumption mode lorsqu'il n'a pas besoin de faire de mesures. Lors de notre programme principal, nous attendons qu'un téléphone se connecte à l'ESP32. Si cela se produit, nous allons utiliser une boucle while pour vérifier toutes les 100ms si notre ESP32 reçoit le caractère "B" dans la variable rxValue. Tant que cela n'est pas le cas, nous laissons le capteur de pollution en mode sleep afin de consommer moins d'énergie. Cela se fait au moyen du signal sur le pin 5 de l'ESP32, relié au pin Sleep du capteur. Nous le mettons donc à l'état bas lorsqu'aucune mesure n'est demandée puis nous passons le signal à l'état haut avant de demander une mesure. Cependant, nous avons remarqué que si nous ne laissions pas un delay entre le moment où nous sortons le capteur de pollution du mode sleep et le moment où nous effectuons la mesure, celles ci étaient fausses. Après des tests avec différentes durées de delay, nous avons décidé d'imposer 5 secondes d'attente avant de prendre la mesure. Ce temps d'attente nous parait en effet acceptable au vu du gain sur l'autonomie de la batterie. | ||
+ | Nous avons également pu vérifier l'efficacité de ce changement en mesurant à l'aide d'un ampèremètre le courant effectivement consommé. En effet, lorsque le capteur est en état de fonctionnement continu, nous avons mesuré une consommation de 60mA et lorsque celui ci est au repos, nous avons mesuré moins de 10mA. Ce qui représente un grand gain en terme de longévité pour notre batterie. | ||
+ | |||
+ | * La réalisation des fichiers schématic et pcb de l'adaptateur du capteur de pollution fut un peu plus complexe que celle de l'ESP32 car nous ne possédions pas de datasheet fiable. La datasheet portait à chaque fois sur le capteur en lui même et non pas sur l'adaptateur. L'adaptateur du capteur est composé de 6 pins espacés de 2.54mm ainsi que de 2 pins représentant le sleep et le set qui, eux, furent difficiles à positionner. En effet, nous avons dû mesurer à l'aide d'un pied à coulisse (pour plus de précision) les espacements entre ces deux pins et le reste des pins de l'adaptateur afin de réaliser la footprint. De plus, les pins de set et sleep étaient positionnés dans le sens opposé au reste des pins comme le montre la photo sur la gauche. Ce positionnement ne nous arrangeait pas pour le fixer sur notre PCB. Nous avons donc décidé d'inverser les pins pour nous faciliter la tâche. Cette inversion a pu être réalisée avec l'aide de Thierry car la fixation industrielle de ces pins les rendaient difficile à désouder sans risquer de casser notre composant. | ||
+ | |||
+ | |||
+ | Le visuel des footprints réalisées est visible ci dessous : | ||
+ | |||
+ | [[Fichier:footprintSwitch.jpg|250px|left|vignette|upright=1.2|footprint ESP32]] | ||
+ | [[Fichier:FootprintESP32.jpg|150px|right|vignette|upright=1.2|footprint de l'interrupteur]] | ||
+ | [[Fichier:footprintAdapterSensor.jpg|250px|center|vignette|upright=1.2|footprint de l'adaptateur du capteur de pollution]] | ||
+ | |||
+ | <br/><br/><br/><br/><br/><br/> | ||
+ | Nous avons ensuite réalisé le schéma composé de tous nos composants afin de les relier entre eux et de pouvoir réaliser le routage de notre carte. Enfin, nous avons ajouté le plan de masse ainsi que les contours mechanicals. Notre PCB est donc terminé et nous devons désormais le graver afin de pouvoir vérifier son bon fonctionnement ainsi que sa compatibilité avec la coque en plastique. | ||
+ | [[Fichier:PCBfin.jpg|250px|right|vignette|upright=1.2|PCB terminé]] | ||
+ | [[Fichier:schematicTotal.jpg|600px|left|vignette|upright=1.2|schematic carte éléctronique]] | ||
+ | |||
+ | <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> | ||
+ | |||
+ | ==== Déploiement sur Amazon Web Service ==== | ||
+ | |||
+ | Nous avons fini par opter pour un déploiement sur Amazon Web Service (AWS) en raison du fait que la machine virtuelle n'était pas assez puissante afin de faire tourner RethinkDb. | ||
+ | Amazon Web Service, de par son service EC2, offre la possibilité de lancer des instances linux, sous les distributions de notre choix. Les instances sont connectés aux serveurs Amazon et disposent donc d'un accès internet. Nous avons du configurer une adresse IP et ouvrir les ports afin d'accéder à notre serveur Tomcat. | ||
+ | Cette configuration se fait par le biais de l'interface proposée par AWS. | ||
+ | Afin d'ouvrir les ports aux paquets entrants, nous avons du mettre en place un groupe de sécurité, dans lequel nous définissions une autorisation à tous les paquets HTTP entrants sur les ports 80 et 8080. | ||
+ | |||
+ | L'adresse IP associée à notre serveur Tomcat est : http://18.219.202.43:8080/Unwheeze/ <br/> | ||
+ | Le serveur websocket quant à lui est accessible sur le lien : ws://18.219.202.43:8080/Unwheeze/realtime/airDataFlow <br/> | ||
+ | Le site web est disponible sur : http://18.219.202.43/ <br/> | ||
+ | |||
+ | [[Fichier:AWSMain.png|600px|Interface de gestion de l'instance AWS]] | ||
+ | [[Fichier:GroupeSecuAWS.png|600px|Interface de configuration des groupes de sécurité]] | ||
+ | |||
+ | ==Semaine 11== | ||
+ | |||
+ | ==== Capteur ==== | ||
+ | * Nous avons pu graver notre PCB. Celui ci a été testé : aucun court circuit n'a été constaté. Nous avons également sélectionné les résistances qui nous permettront d'allumer les LEDs sans créer de surtension dans les LEDs. En effet, notre ESP32 transmet une tension de 3,3V. Les deux leds que nous utilisons sont la OVS0806 (jaune) qui selon la datasheet accepte au maximum 20mA pour une tension de 2.1V tandis que nous n'avions pas la datasheet pour la led sml31ovtt86p (rouge). Nous avons donc décidé de calculer la chute de tension induite par les 2 leds grâce à un multimètre. Cela nous permettait donc de remédier au manque de datasheet pour la led rouge et de vérifier celle de la led jaune. Nous avons alors trouvé que la led rouge induisait une chute de tension de 1,45V et la jaune : 1,63V. | ||
+ | Sachant que nous devions avoir un courant de 20mA au maximum dans les LEDs. Nous avons décidé d'assurer une marge de sécurité et avons donc fait nos calculs avec 12mA. | ||
+ | Le simple calcul U=RI nous donne alors des résistances de 139 Ohm pour la led rouge et 154 Ohm pour la led jaune. | ||
+ | Cependant, après quelques tests, la LED jaune nous semblait éclairer un peu fort et nous ne voulions pas que celle ci brûle durant une trop longue utilisation. Nous avons donc augmenté la valeur des résistances et avons choisi d'utiliser des résistances de 270 Ohm qui nous donnaient entière satisfaction. | ||
+ | |||
+ | Pour alimenter notre carte, nous avons décidé de connecter 2 fils directement sur la batterie afin de pouvoir miniaturiser notre capteur. Cette astuce nous permettant de gagner 4 à 5 cm de longueur sur le capteur car nous n'avons plus besoin de câble pour connecter notre capteur. Ces deux fils ont été soudés sur la carte au moyen de pins car nous avons utilisé un fil épais pour transporter le courant jusqu'à la carte. Un interrupteur permet par la suite de séparer le reste de la carte de la batterie. En effet, cela nous permet de pouvoir téléverser un nouveau programme dans l'ESP32 facilement sans risquer de poser problème entre l'alimentation par la batterie et l'alimentation usb du PC. Nous avons également positionner des headers sur la carte afin de ne pas souder directement l'ESP32 et l'adaptateur du capteur de pollution sur le PCB. Cependant, les pins utilisés sur l'ESP32 étant assez gros, il n'est pas facile de le retirer. Notre interrupteur nous permet donc de téléverser nos programmes sans risque d'endommager les pins de l'ESP32 en le retirant. | ||
+ | |||
+ | [[Fichier:soudureComposants.jpg|200px|left|vignette|soudure des composants]] | ||
+ | [[Fichier:carteFinaleRecto.jpg|300px|right|vignette|Carte finale recto]] | ||
+ | [[Fichier:carteFinaleVerso.jpg|300px|center|vignette|Carte finale verso]] | ||
+ | |||
+ | <br/><br/><br/> | ||
+ | * Nous avons terminé la réalisation de la coque sur freecad dont voici le dessin 3D : | ||
+ | |||
+ | [[Fichier:coqueCapteurFinal.png|150px|left|vignette|upright=1.2|coque capteur de pollution finale]] | ||
+ | [[Fichier:coqueCapteurInterieur.png|right|vignette|upright=1.2|visuel intérieur de la coque]] | ||
+ | [[Fichier:coqueCapteurHaut.png|center|vignette|upright=1.4|visuel du cache de la coque]] | ||
+ | |||
+ | <br/><br/><br/><br/><br/><br/><br/> | ||
+ | Vous pouvez donc voir qu'une chambre d'air a été créée en haut du capteur de pollution. Les trous dans les parois de tous les cotés permettent de laisser passer l'air à analyser tout en évitant d'avoir des trop grands afflux d'air qui peuvent perturber le capteur en cas de grand vent. De plus, le capteur est maintenu en position de chaque coté par des petits supports de plastique. Un petit support le maintient également en hauteur pour que le capteur soit bien au centre de la chambre d'air. Enfin, un trou a été laissé sur le coté afin de laisser passer les câbles du capteur jusqu'au PCB. La batterie est, elle, maintenue des deux cotés afin de ne pas bouger et des trous ont été dessinés afin de pouvoir : appuyer sur le bouton marche/arrêt et de pouvoir brancher le câble de rechargement de la batterie. | ||
+ | |||
+ | Un espace a également été prévu pour venir placer le PCB au dessus de la batterie. Celui ci sera alors maintenu par une petite partie en plastique qui ressort de chaque coté. La partie supérieure de la coque est également perforée pour laisser passer l'air et permettre de voir les LEDs qui s'éclaireront pour dire si le capteur est allumé et si il est en train de prendre une mesure. Cette partie supérieure de la coque vient ensuite se refermer sur le PCB est le bloque totalement afin que celui ci ne bouge plus. Tous les éléments sont donc bien maintenus dans la coque. | ||
+ | |||
+ | * Nous avons également essayé d'imprimer notre coque. Cependant, l'impression n'a pas fonctionné. Nous avions déjà dû relancer l'impression au soir car l'imprimante 3D s'était arrêtée puis nous l'avons laissée tourner pendant la nuit et celle ci s'est arrêtée au bout de quelques couches. Nous relancerons donc l'impression la semaine prochaine sur une autre imprimante. | ||
+ | |||
+ | ==== Application mobile ==== | ||
+ | |||
+ | * Le serveur websocket et l'API REST étant fonctionnels et en ligne, nous pouvons nous concentrer pleinement sur la réalisation de l'application mobile. | ||
+ | Nous en profitons ainsi pour perfectionner l'envoi des données et la réception de celles-ci. Ainsi, nous mettons en place un splash screen, permettant de paramétrer l'application, tout en offrant un visuel plaisant. L'activité liée au splash screen effectue de nombreuses tâches en fond, permettant de vérifier la présence des services de localisation, des autorisations nécessaires au fonctionnement de l'application, récupérant ensuite la position de l'utilisateur afin d'optimiser le positionnement de la carte dans l'activité suivante. Nous récupérons également une clé API que nous stockons dans un fichier de données propre à notre application, en compagnie des données mentionnées précédemment. | ||
+ | |||
+ | * Dans l'activité principale, nous réalisons le chargement et le stockage des données dans une base de donnée SQLite locale, en tâche de fond afin de ne pas impacter l'expérience de l'utilisateur. | ||
+ | Un bouton refresh est également mis en place afin de pouvoir recharger la carte en cas d'erreur. Le service android se charge d'ajouter les marqueurs et de stocker les données en cas de réception sur la liaison websocket. | ||
+ | |||
+ | * Nous avons rencontré quelques difficultés dans la communications entre les threads parallèles et le thread principal, les changement sur l'interface utilisateur ne pouvant s'effectuer que sur le thread principal : il nous a donc fallu rechercher le fonctionnement du multi-threading sur Android qui se base intensivement sur les handler et les loopers. | ||
+ | Nous gérons maintenant sans soucis les communications entre threads. | ||
+ | Nous avions également un problème de chargement des valeurs, qui ne chargeaient qu'après une seconde tentative. Nous suspectons que nous accédons à la base de donnée trop rapidement après la réception des valeurs. Un handler exécuté après un certain temps réglera ce problème. | ||
+ | |||
+ | [[Fichier:UnwheezeMainApp.jpg|400px|Activité principale de l'application]] | ||
+ | [[Fichier:SplashUnwheeze.jpg|400px|Activité de chargement de l'application]] | ||
+ | |||
+ | ==Semaine 12== | ||
+ | |||
+ | ==== Capteur ==== | ||
+ | * Les composants étant soudés sur notre carte, nous avons pu tester cette dernière pour vérifier qu'elle fonctionne correctement. Nous arrivons à allumer les 2 leds rouge et jaune ainsi qu'à utiliser le capteur de pollution avec l'ESP32. Enfin, nous avons dû connecter la batterie sur la carte. Cependant, nous avons rencontré un problème car si nous connections le PCB à la batterie avec un simple connecteur microUSB, nous aurions dû utiliser le câble prévu à cet effet. Ceci aurait eu pour conséquence d'augmenter la longueur de la coque du capteur de près de 5 cm afin de faire passer le câble microUSB. Nous avons donc décidé d'ouvrir la batterie afin de souder directement les fils sur celle ci. L'autre extrémité des fils étant également soudée directement sur la carte, cela nous permet donc un gain de place considérable afin de miniaturiser notre capteur. | ||
+ | |||
+ | * Au niveau de l'impression de la coque en 3D, nous avons de nouveau eu beaucoup de problèmes. En effet, l'impression s'est arrêtée comme la semaine dernière et nous avons donc dû nous y prendre à 3 fois pour enfin obtenir notre objet en 3D. La pièce correspond à nos attentes. Tous les éléments passent dans la coque et ne bougent presque pas ce qui permettra une meilleur expérience utilisateur. Cependant, nous avons souder l'ESP32 sur la carte au moyen d'un connecteur en barrette femelle afin de pouvoir l'enlever et le remettre sur notre PCB. Celui ci a donc augmenté la place prise par l'ESP32 et nous avons désormais quelques difficultés pour fermer la boite. Nous réimprimerons donc par nos propres moyen une coque pendant les vacances. | ||
+ | |||
+ | * En obtenant l'aide d'Erwan Dufresne et de son imprimante 3D personnelle, nous avons pû réimprimer notre coque. Celle ci étant un peu longue par rapport à la largeur, elle semble avoir tendance à se décoller plus facilement du plateau d'impression ce qui provoquait beaucoup d'échecs. Notre capteur est donc terminé et tous les composants rentrent parfaitement dans celui ci. Le capteur de pollution est placé à l'avant de la coque dans la chambre d'air prévue à cet effet, tandis que la batterie et le PCB qui se superposent à celle ci sont dans la partie arrière de la coque. Voici le résultat : | ||
+ | |||
+ | <br/> | ||
+ | [[Fichier:capteurFinal.jpg|600px|center|vignette|Capteur final]] | ||
+ | |||
+ | <br/> | ||
+ | |||
+ | ==== Site web ==== | ||
+ | |||
+ | <br/> | ||
+ | [[Fichier:SiteLocalisation.png|800px|left|Localisation de l'utilisateur]] | ||
+ | <br/><br/><br/> | ||
+ | |||
+ | * Pour faciliter l'expérience utilisateur, nous avons également implémenté une fonctionnalité qui n'oblige pas l'utilisateur à cliquer précisément sur un marker pour faire apparaître la fenêtre d'informations. En effet, si l'utilisateur clic simplement sur un point arbitraire de la carte, la fenêtre correspondant au point le plus proche s'ouvrira. La difficulté de cette fonctionnalité était de permettre à l'utilisateur de se déplacer sur la carte sans déclencher l'ouverture de la fenêtre du point le plus proche. Car, pour se déplacer sur la carte, il faut effectuer un appui sur la souris puis la déplacer alors que pour demander à ouvrir la fenêtre correspondant au point le plus proche, on effectue un clic. Ces deux événement pouvaient donc entrer en conflit. Un click représentant un mouseDown, suivi d'un mouseUp sans mouseMove entre les deux. Nous avons donc utilisé une variable afin de vérifier si aucun mousemove n'avait été effectué entre le mousedown et le mouseup. | ||
+ | |||
+ | * Lors de l'arrivée d'un utilisateur sur le site, le navigateur demandera désormais si il accepte de divulguer ses informations sur sa position géographique via une fenêtre en haut à gauche de l'écran. Si celui ci accepte, la carte zoomera alors sur sa position actuelle afin de pouvoir afficher les mesures de pollution effectuées autour de lui. Dans le cas contraire, nous avons décidé de faire démarrer la carte sur la ville de Lille. L'utilisateur pourra alors se déplacer librement sur la carte afin de trouver les informations sur les taux de pollution aux endroits qu'il recherche. La localisation de la personne (ou la localisation par défaut si l'utilisateur n'autorise pas la géolocalisation) est affichée en haut à droit de la page. L'utilisateur peut alors simplement cliquer sur cette information pour centrer la carte atour de sa position. L'utilisateur étant représenté par un marker rouge sur la carte. | ||
+ | |||
+ | <br/><br/><br/><br/> | ||
+ | |||
+ | ==== Application mobile ==== | ||
+ | |||
+ | * Le fonctionnement global de l'application mobile est atteint et nous nous concentrons maintenant sur l'optimisation des performances et la correction de maximums d'erreurs que nous pouvons rencontrer. Nous nous penchons également sur une interface correspondant aux guidelines du material design afin d'offrir une interface plaisante. Les valeurs sont maintenant affichées au bas de l'écran. | ||
+ | * Un clic sur la carte permet d'afficher la valeur du point mesuré le plus proche. | ||
+ | Les erreurs rencontrées ne provoquent plus un crash de l'application mais, au contraire, sont affichées de façon claire et intuitive pour l'utilisateur, afin qu'il comprenne la cause du problème et le moyen de régler ceux-ci. Le plus souvent, les erreurs sont dû à des problèmes d'activation du bluetooth et des services de localisation, ou encore, de la réception de valeurs erronées. | ||
+ | Nous tentons de régler le plus de problèmes possibles. | ||
+ | |||
+ | [[Fichier:UnwheezeDetails.jpg|400px|Détails des mesures]] | ||
+ | [[Fichier:MessageErreurUnwheeze.jpg|400px|Message d'erreur]] | ||
+ | [[Fichier:MessageWarningUnwheeze.jpg|400px|Message de warning]] | ||
+ | <br/> | ||
+ | |||
+ | * Nous avons récemment ajouté une option de mesure périodique. En cliquant sur le bouton dédié, une mesure sera réalisée chaque 30 secondes. Cela à été atteint en utilisant un thread tournant en parallèle, executant un ScheduledExecuterService. | ||
+ | Un des désavantages d'utiliser cette méthode de thread est que cette option n'est fonctionnelle que lorsque l'écran est actif. Si le smartphone passe en mode verrouillé, les mesures ne sont pas réalisés. Nous cherchons à améliorer cette fonctionnalité. | ||
+ | |||
+ | * Les différentes versions de l'application sont disponibles au téléchargement sur le lien [http://18.219.202.43:8080/Unwheeze/ suivant], accompagnées d'un numéro de version et de commentaires sur les correctifs apportés. L'application sera mise à jour continuellement jusqu'à la date du rendu. Une documentation est également disponible sur le lien fourni tant pour l'API accompagné du serveur websocket, que pour l'application mobile, moins commentée, mais dont les classes et méthodes sont représentées. | ||
+ | Nous avons tenté d'écrire un code le plus modulaire possible et de privilégier une syntaxe claire afin de faciliter toute maintenance du code. | ||
+ | |||
+ | =Mesures, Interprétation et validation de notre prototype de capteur= | ||
+ | |||
+ | Afin de vérifier que notre capteur fonctionnait correctement et fournissait bien des mesures fiables à l'utilisateur, nous avons décidé de le tester en situation réelle proche des stations de mesure de l'ATMO qui gère sur Lille les stations de Lille Leeds à côté de la gare lille europe et de Lille fives dans l'école Lakanal. | ||
+ | Nous nous sommes donc rendu juste à coté de ces stations afin de comparer nos valeurs aux mesures théoriques de cet organisme. | ||
+ | |||
+ | ==Mesures expérimentales à l'aide de notre capteur== | ||
+ | |||
+ | La première station que nous avons visité est celle de Leeds. Nous avons effectué des mesures toutes les minutes environ entre 10h et 11h. Celles si sont toutes visibles sur le site et l'application mobile en cliquant aux alentours de la station. Cela nous a donc permis de réaliser une moyenne des valeurs autours de ce point pour comparer la moyenne sur l'heure à celle de l'ATMO. | ||
+ | Nous nous sommes ensuite rendu à la station située dans l'école Lakanal qui a accepté de nous recevoir pour effectuer les mesures de 11h20 à 12h20. | ||
+ | Voici donc la moyenne des résultats que nous avons obtenu sur chaque polluant et chaque station : | ||
+ | |||
+ | [[Fichier:stationLeeds.jpg|200px|right|vignette|Station de Leeds]] | ||
+ | <br/> | ||
+ | {| class="wikitable" | ||
+ | ! style="font-weight:bold;" | Station | ||
+ | ! style="font-weight:bold;" | heure | ||
+ | ! style="font-weight:bold;" | PM10 (ug/m3) | ||
+ | ! style="font-weight:bold;" | PM2.5 (ug/m3) | ||
+ | ! style="font-weight:bold;" | PM1 (ug/m3) | ||
+ | |- | ||
+ | | Leeds | ||
+ | | 10h - 11h | ||
+ | | 25.46 | ||
+ | | 20.76 | ||
+ | | 11.57 | ||
+ | |- | ||
+ | | Fives | ||
+ | | 11h20 - 12h20 | ||
+ | | 28.08 | ||
+ | | 22.57 | ||
+ | | 12.11 | ||
+ | |} | ||
+ | |||
+ | <br/><br/><br/><br/><br/><br/> | ||
+ | |||
+ | ==Mesures théoriques relevées par l'agence ATMO== | ||
+ | |||
+ | [[Fichier:stationFives.jpg|200px|right|vignette|Station de Fives]] | ||
+ | |||
+ | Ces mesures sont disponibles après quelques heures sur le site : http://www.atmo-hdf.fr/acceder-aux-donnees/mesures-des-stations.html | ||
+ | |||
+ | * La station de Leeds à Lille europe, ne mesure que les PM2,5. Nous avons alors pu récupérer ces valeurs théoriques : | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! style="font-weight:bold;" | Station | ||
+ | ! style="font-weight:bold;" | heure | ||
+ | ! style="font-weight:bold;" | PM2.5 (ug/m3) | ||
+ | |- | ||
+ | | Leeds | ||
+ | | 10h | ||
+ | | 18.1 | ||
+ | |- | ||
+ | | Leeds | ||
+ | | 11h | ||
+ | | 21.4 | ||
+ | |} | ||
+ | |||
+ | Ayant obtenu une valeur de PM2.5 de 20.76ug/m3 aux abords de cette station, nous sommes donc très proche de cette valeur. | ||
+ | |||
+ | * La station de fives, elle, mesure le PM2.5 et le PM10. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! style="font-weight:bold;" | Station | ||
+ | ! style="font-weight:bold;" | heure | ||
+ | ! style="font-weight:bold;" | PM2.5 (ug/m3) | ||
+ | ! style="font-weight:bold;" | PM10 (ug/m3) | ||
+ | |- | ||
+ | | Fives | ||
+ | | 10h | ||
+ | | 20.8 | ||
+ | | 29.9 | ||
+ | |- | ||
+ | | Fives | ||
+ | | 11h | ||
+ | | 24.7 | ||
+ | | 30.1 | ||
+ | |- | ||
+ | | Fives | ||
+ | | 12h | ||
+ | | 23.7 | ||
+ | | 27.4 | ||
+ | |} | ||
+ | |||
+ | Ayant obtenu des valeurs de PM2.5 de 22.57 ug/m3 et de PM10 de 28.08 aux abords de cette station, nous semblons donc proche de ces valeurs. | ||
+ | |||
+ | ==Conclusion== | ||
+ | |||
+ | La datasheet de notre capteur indiquant une précision de +/- 15% de précision, nous pouvons conclure que cette intervalle de précision est respecté et offre donc une assez bonne précision à l'utilisateur. Cela permet en effet d'obtenir une bonne idée du niveau de pollution dans la ville. | ||
+ | Cependant, lors de notre entretien avec une personne responsable du service des risques urbains et sanitaires de Lille, celle ci nous avait indiqué que la station de Leeds était une station proche du traffic et donc avec un taux censé être plus élevé que la station de Fives qui est une station bruit de fond. En effet, celle ci est au fond de la cours de l'école avec très peu de traffic aux alentours. Mais nous avons pu remarquer en observant les alentours de l'école que de gros travaux étaient en cours sur un batîment juste à coté de celle-ci. De nombreuses particules fines devaient donc être présentes lors de nos mesures. Cela montre donc une nouvelle fois la fiabilité du capteur que nous avons conçu. | ||
=Documents Rendus= | =Documents Rendus= | ||
+ | |||
+ | * Fichiers des footprints et schematics réalisés sous altium : [[Media:footprints.zip|footprints et schematics]] | ||
+ | * Fichiers modélisation 3D réalisés sous freecad : [[Media:coque.zip|Modélisation 3D coque freecad]] | ||
+ | * Gitlab du projet : https://archives.plil.fr/pribeiro/unwheeze | ||
+ | * Versions de l'application mobile (la plus récente est la Beta 0.1.3) : http://18.219.202.43:8080/Unwheeze/ | ||
+ | * Rapport du projet : [[Media:UnwheezeRapport2.pdf|Rapport du projet]] | ||
+ | |||
+ | =Documentation= | ||
+ | |||
+ | * heatmap.js pour gmaps : https://www.patrick-wied.at/static/heatmapjs/example-heatmap-googlemaps.html | ||
+ | * Documentation pour installer le dev module arduino pour l'ESP32 : https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide?_ga=1.189350435.90086807.1452767181#installing-the-esp32-arduino-core | ||
+ | * Documentation google maps API for javascript : https://developers.google.com/maps/documentation/javascript/tutorial?hl=fr | ||
+ | * Semantic ui documentation pour le design du site web : https://semantic-ui.com/ | ||
+ | * tutoriel création de footprints : https://www.youtube.com/watch?v=nYI8sw__9_Y | ||
+ | * Documentation RethinkDb : https://www.rethinkdb.com/docs/ | ||
+ | * Documentation Android : https://developer.android.com/guide/ | ||
+ | * Documentation Google Maps pour Android : https://developers.google.com/maps/documentation/android-api/?hl=fr |
Version actuelle datée du 15 juin 2018 à 21:30
Sommaire
- 1 Réseau de capteurs de pollution
- 2 Présentation générale
- 3 Analyse du projet
- 4 Préparation du projet
- 5 Réalisation du Projet
- 6 Mesures, Interprétation et validation de notre prototype de capteur
- 7 Documents Rendus
- 8 Documentation
Réseau de capteurs de pollution
Présentation générale
Description
Notre projet consiste à réaliser un réseau de capteurs de pollution. Ceux ci permettront, au travers d'une application web et d'une application mobile de visualiser le taux de pollution aux particules fines et polluants chimiques en différents endroits d'une carte. Le capteur devra communiquer en bluetooth avec un téléphone pour envoyer les données récoltées sur le serveur. Nous pourrons ensuite, si le temps nous le permet, ajouter une fonctionnalité permettant d'aider les utilisateurs à trouver les chemins les plus appropriés pour se déplacer en étant le moins exposé possible à la pollution. En effet, l'exposition prolongée à un taux élevé de particules fines réduit l'espérance de vie. Connaitre le taux de pollution est donc un enjeu majeur.
Scénario
Pedro est intolérant aux particules fines et est cependant un grand sportif. Jusqu’à maintenant, il se contentait de courir sur des tapis roulants dans sa salle de sport. Cependant, il se demandait chaque fois quand est-ce qu’il franchirait le pas et irait courir dehors. Cela tombe bien car sa copine vient de lui offrir un capteur de pollution miniature tenant dans sa poche qui lui permet de connaître les endroits non pollués où il peut courir. Des centaines d’utilisateurs l’utilisent en ce moment et leurs données sont renvoyées en temps réel sur la carte de pollution de la ville qui s’affiche sur son smartphone. Il peut également visualiser où se trouvent les personnes disposants du capteur si celles-ci ont décidé de l’autoriser. Dans une prochaine mise à jour, Pedro se réjouit d’avance de pouvoir utiliser son application comme un véritable GPS d’air pur : en rentrant son point de départ et sa destination, il pourra obtenir la meilleure route possible selon ses conditions de tolérance.
Objectifs
- Élaboration d'un capteur de pollution permettant de détecter différents polluants (particules fines, poussière, résidus de combustion) connecté au réseau LoRaWAN
- Création d'une application web permettant aux utilisateurs de visualiser les taux de pollution détectés par les capteurs en différents endroits de la ville et de pouvoir déterminer le chemin le plus approprié pour leurs déplacements.
- Création d'une application mobile avec les mêmes spécificités que le site web
- Élaboration d'un algorithme de machine learning permettant de déterminer le meilleur chemin selon des anciennes données dans le cas d'une panne des capteurs.
Analyse du projet
Positionnement par rapport à l'existant
- Site web évaluant la pollution sur Lille : https://air.plumelabs.com/fr/live/lille
- Site évaluant la pollution de l'air dans différentes villes de France : http://aqicn.org/map/france/
- Carte couleur en fonction de la pollution : http://www2.prevair.org/
- Application plume air report donnant la qualité de l'air dans la ville demandée ainsi que des astuces pour éviter la pollution : https://plumelabs.com/en/products/air-report
Analyse du premier concurrent : Bornes implantées dans la ville
Certaines bornes peuvent permettre d'obtenir la qualité de l'air en dans la ville en temps réel. Cependant, notre projet aura comme avantage de :
- permettre de connaître précisément le taux de pollution en tous les endroits de la ville et pas seulement en un endroit fixe.
- D'obtenir le taux de pollution sur son téléphone. Il n'y a donc pas besoin de se déplacer pour le connaître.
Analyse du second concurrent : Applications, sites web indiquant le taux de pollution
D'autres applications et sites web permettent d'obtenir un taux de pollution comme Plume : https://air.plumelabs.com/fr/live/lille Notre projet permettra cependant d'ajouter :
- La possibilité de connaître la pollution dans des endroits plus précis de la ville contrairement à Plume qui donne une valeur par ville.
- Permet à l'utilisateur de faire sa propre mesure à l'aide du capteur.
Scénario d'usage du produit ou du concept envisagé
Sur la page d'accueil: les informations générales sur la pollution :
- La moyenne journalière de pollution sur toute la ville
- L'évolution de la pollution moyenne sur la semaine, le mois, l'année... (graphique)
Dans les autres onglets :
- Une carte de la ville de Lille présentant le niveau de pollution en fonction des données relevées sur les capteurs.
- Une interface permettant à l'utilisateur de rentrer le trajet qu'il souhaite réaliser et qui lui renvoie le meilleur itinéraire
Réponse à la question difficile
Selon certaines documentations, le capteur perd en précision lorsqu'un souffle est appliqué sur le capteur. Il faudrait donc envisager un moyen pour protéger le capteur du vent afin d'obtenir la meilleure précision. Surtout en cas de placement des capteurs sur des véhicules.
Quelle quantité de données sera envoyée par le smartphone et quelle consommation aura le capteur de particule fine ?
- données doit contenir : la position GPS du capteur, l'heure de la mesure ainsi que la mesure. Cela correspond donc à quelques dizaines d'octets. En fonction du nombre de mesures faites par heure, on peut donc calculer la quantité de données envoyée par heure ou par jour.
- consommation de la carte :
- ESP32 : environ 100mA en actif et sinon 4mA en slow speed sleep
- module GPS : ?????
- En prenant une batterie de 2000mA pour ne pas qu'elle soit trop encombrante et en prenant en compte une consommation moyenne de 10mA, nous obtenons une autonomie de 140H. Ce qui correspond à 1 semaine d'autonomie.
Préparation du projet
Cahier des charges
Réalisation de la carte du capteur :
Polluants pouvant être analysés :
- Monoxyde de carbone
- Dioxyde de carbone
- Ozone
- Particules en suspension PM2.5 (particules de diamètre inférieurs à 2,5 micromètres),PM10
- Dioxyde de souffre
Choix techniques : matériel et logiciel
Capteur :
- ESP32 (https://www.amazon.fr/AZ-Delivery-NodeMCU-développement-dénergie-successeur/dp/B071P98VTG/ref=pd_cp_107_1?_encoding=UTF8&psc=1&refRID=Y7HFS1X1WQGBM9VCHXTW)
- Module GPS ( si nous ne voulons pas utiliser le GPS du smartphone )
- Batterie Lithium Ion (https://www.adafruit.com/product/258)
- Adaptateur micro USB
- dfrobot SEN0177
La raspberry pi peut être remplacée par le module Particle Photon ( Lien [[1]] ) qui comprend un module de données cellulaires qui amortirait le cout d'un dongle. Le kit de développement de Particle comprend une batterie et une carte SIM prépayée ainsi que plusieurs accessoires supplémentaires. Il serait peut être plus raisonnable d'opter pour le kit.
Backend
- Base de données NoSQL : RethinkDB ou MongoDB
- Google maps API : service de localisation avec points de cheminements pour choisir le meilleur itinéraire https://developers.google.com/maps/documentation/directions/intro?hl=fr#Waypoints
- Jersey : pour l'API REST et le traitement en temps réel
- RabbitMQ pour le système publish/subscribe
Application mobile :
- Java/Kotlin
Application Web :
- Node/AngularJS : pour améliorer la fluidité du site.
- Bootstrap/Semantic UI : pour faciliter le développement
Liste des tâches à effectuer
Calendrier prévisionnel
Réalisation du Projet
Feuille d'heures
Tâche | Prélude | Heures S1 | Heures S2 | Heures S3 | Heures S4 | Heures S5 | Heures S6 | Heures S7 | Heures S8 | Heures S9 | Heures S10 | Heures S11 | Heures S12 | Total |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Choix du matériel | 2H | 1H | ||||||||||||
Analyse du projet + préparation oral | 6H | |||||||||||||
Création du Back-End de l'application et de l'appli web | 2H | 5H | 6H | 5H | 3H | 2H | 1H | 1H | ||||||
Site web | 6H | 10H | 12H | 4H | 10H | |||||||||
Carte/coque capteur | 3H | 2H | 8H | 8H | 6H | 6H | ||||||||
Programme ESP32 | 4H | 3H | 2H | |||||||||||
Documentation (rethinkDB, rabbitMQ) | 3H | 2H | 1H | 1H | ||||||||||
Documentation (Angular JS, facebook authentification, maps) | 1H | |||||||||||||
Documentation Android | 4H | 8H | 2H | 1H | 2H | |||||||||
Travail sur l'application Android | 6H | 2H | 5H | 3H | 3H | 5H | 6H | |||||||
Wiki | 1H | 1H | 1H | 1H | 1H | 2H | ||||||||
Informations/Interprétation mesures | 1H |
Prologue
- Préparation de l'oral :
Description du projet : quels sont les objectifs à remplir, scénario d'usage permettant de se rendre compte de l'utilité du projet et analyse des concurrents pour connaître ce qui existe déjà et savoir ce que nous devons ajouter dans notre projet pour nous démarquer.
- Choix du matériel et des technologies utilisées
- Après l'oral : réponse à la question sur l'autonomie de la batterie ainsi que sur la quantité de données envoyées
Semaine 1
- Vérification du schéma électronique et de la carte permettant d'alimenter et de contrôler notre capteur.
- Nous avons finalement changé de batterie. En effet, une batterie de 5V nous paraissait plus adaptée au fait que nous devons alimenter le microcontrôleur en 3,7V et le capteur en 5V. Nous obtiendrons un meilleur rendement en réalisant une baisse de tension qu'une augmentation de tension. La batterie sera un peu plus volumineuse mais nous permettra d'alimenter notre capteur plus longtemps. Nous avons donc ajouté un connecteur micro-usb que nous souderons sur la carte et qui nous permettra de l'alimenter en 5V.
Semaine 2
- Documentation sur la base de donnée rethinkDB afin de bien comprendre son fonctionnement ainsi que le gestionnaire de queue de message rabbitMQ.
Ces recherches vont nous permettre d'être plus efficace par la suite et de savoir quel est le meilleur moyen d'utiliser cette base de donnée.
Semaine 3
- Installation des environnements de travail sur nos ordinateurs ainsi que sur un serveur pour nous permettre de travailler tous les deux sur les mêmes données : tomcat pour le serveur java, rethinkDB pour la base de données. Mais nous avons eu un problème car l'espace disponible sur le serveur que nous possédons n'est pas suffisant.
- Début de la programmation du code serveur : Mise en place de l'architecture temps-réel et mise en avant des problèmes à résoudre : documentation sur les queues et les websockets. Nous nous somme accordé sur l'architecture schématisé par la suite :
Problème : réaliser un code en boucle infinie pour pousser les données vers la queue, ou uniquement garder une connection WS active ?
Semaine 4
Site web
- Création de la base de projet web. Nous avons désormais une base de projet tournant avec Node, angular, rethinkdb et avec les fonctionnalités basiques.
Nous avons également étudié la documentation qui va nous permettre d'implémenter une authentification du client via facebook par exemple et d'utiliser l'API de google maps.
- Durant la séance suivante, nous avons pu utiliser l'api de google maps pour obtenir leur carte sur notre site web. Nous avons pour cela dû nous créer une clé d'identification et insérer leur script dans la page. Puis nous avons ajusté celle ci afin qu'elle prenne l'ensemble de la largeur du site. Enfin, nous avons réussi à manipuler les marqueurs afin de pouvoir indiquer les endroits où des mesures de taux de pollution ont été effectuées. Pour le moment, ces positions ont été fixées manuellement. Mais nous modifierons prochainement le code afin que les données soient récupérées dans la base de données et affichées dynamiquement sur la carte.
Serveur
- Réalisation des endpoints REST pour l'utilisateur, mise en place du code associé aux actions sur la base de donnée. Mise en place des moyens de sécurisation (JWT en particulier). Réalisation de testbench pour tester ce qui à été mentionné précédemment.
Début de la réalisation de la partie temps réel.
Semaine 5
Site web
- Ajout de la librairie semantic UI au projet web pour permettre un design plus agréable pour l'utilisateur mais aussi faciliter son utilisation. Cependant, nous avons eu quelques problèmes pour faire cohabiter toutes les librairies sur le projet web. Nous avons donc recréé un projet Web fonctionnant avec du javascript classique plutôt que Angular afin d'avoir une interface fonctionnelle le plus rapidement possible. En effet, nous devrons pouvoir faire des tests avec le capteur lorsque nous recevrons les composants. Nous retenterons de faire fonctionner les différents modules tous ensemble sous angular à la fin du projet si le temps nous le permet.
- Ajout de l'apparition des fenêtres lorsque l'utilisateur clic sur les markers de google maps correspondants aux points de mesure de pollution. Ceux ci indiqueront le taux de pollution calculé pour chaque polluant, la date et l'heure de la mesure ainsi que l'adresse à laquelle la mesure a été prise. Enfin, nous afficherons le nom et la photo de la personne qui a pris la mesure si celui ci l'accepte. La fenêtre affiche également l'adresse du point cliqué (celle ci est récupérée à l'aide d'une requête à l'API de google qui converti le point exprimé en latitude/longitude, en adresse réelle).
Nous pourrons également ajouter la météo du moment où la mesure a été prise. En effet, celle ci peut influer sur la précision de la mesure. Et nous pourrons également implémenter un système de vérification des mesures prises. Si une données est aberrante par rapport aux données prisent aux alentours par d'autres membres, nous ne la prendrons pas en compte.
Semaine 6
Capteur
- Nous avons reçu une partie de notre commande de composants dont l'ESP32. Nous avons donc pu commencer à travailler sur celui ci. Pour le programmer, 3 choix s'offraient à nous :
- Le logiciel PlatformIO : https://platformio.org/
- Le framework esp-idf disponible sur github : https://github.com/espressif/esp-idf
- Le logiciel et langage arduino
Nous nous sommes penchés vers cette dernière solution qui étaient celle proposée dans la datasheet de notre composant sur sparkfun. Certaines sources menaient à penser que des fonctionnalités n'étaient pas encore implémentées dans le module de développement arduino. Cependant, le projet ayant bien avancé depuis la dernière année, les fonctionnalités dont nous avons besoin (notamment le bluetooth) semblent bien présentes. Nous avons donc suivi les quelques étapes décrites sur ce lien pour installer le module supplémentaire permettant de programme l'ESP32 sur le logiciel arduino : https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide?_ga=1.189350435.90086807.1452767181#installing-the-esp32-arduino-core
Nous avons ensuite réalisé le programme permettant d'envoyer les données et de les recevoir via bluetooth sur l'ESP32. Pour cela, nous devons importer les librairies BLE sur arduino. Et au moyen du langage C++, nous avons défini l'appareil ainsi que le serveur BLE. Celui ci signale donc la présence de notre ESP32 comme étant un appareil bluetooth auquel on peut s'appairer. De plus, nous avons défini des fonctions de callback qui permettent de signaler lorsqu'un appareil se connecte ou se déconnecte mais aussi de recevoir un caractère depuis le téléphone via bluetooth. Dans le code principal, nous envoyons un nombre flottant qui s'incrémente toutes les secondes. Et lorsqu'un caractère est reçu, il s'affiche.
Nous avons également commencé l'application android permettant de communiquer avec l'ESP32. Celle ci est pour l'instant minimaliste et ne permet que de se connecter à notre microcontrôleur, d'envoyer des données en appuyant sur un bouton ou d'en recevoir à l'aide d'un autre bouton. Cela nous a donc permis de vérifier que le système de communication bluetooth fonctionnait correctement. Pour réaliser notre application et faire fonctionner la librairie BLE bluetooth d'android, il ne faut pas oublier de demander les permissions pour le bluetooth et la localisation qui sont indispensables. Sinon, le téléphone n'arrive pas à se connecter à l'ESP32. Par la suite, nous modifierons l'application android pour n'avoir qu'un seul bouton pour demander une mesure et l'afficher. Le code de l'Arduino lui, devra se mettre en attente tant qu'un caractère précis n'est pas reçu. Puis, lors de sa réception, communiquera avec notre capteur de pollution pour récupérer les données et les envoyer sur l'application Android.
Voici le résultat sur la vidéo suivante, qui démontre que la connexion entre notre microcontroleur et l'appli android fonctionne :
Serveur
Quant au coté serveur, les appels permettant de récupérer l'ensemble des données de l'air ou plus de détails sur une donnée particulière ont été réalisés. Nous avons également mis en place le serveur websocket. Plus de documentation est nécessaire car nous ne savons toujours pas si l'API websocket gère les threads par elle même. Dans le cas contraire, il sera nécessaire de mettre en place un système de multithreading. Pour le moment, les sockets sont disposées sur deux threads. Un thread principal qui permet de recevoir les données du client (par exemple des données de l'air) et un thread secondaire, connecté aux changefeeds de rethinkdb, qui permettent de pousser tout changement sur la table vers un curseur infini. Lors de chaque changement du changefeed, les données sont envoyées aux clients. Ils sont d'abord traités par un décodeur qui permet de parser le JSON reçu, composé d'un champ old_val et new_val. Afin de simplifier, nous ne renvoyons que le champ non vide. Dans le cas ou les deux sont remplis, nous renvoyons les deux champs afin de comparer l'ancienne et nouvelle valeur.
Semaine 7
Site web
- Le site web récupère désormais les données issues de l'API REST. Nous utilisons pour cela les xhtmlHTTPrequest javascript. Cette connexion est pour l'instant effectuée en localhost en faisant tourner en parallèle la base de données rethinkDB ainsi que l'API REST. 2 requêtes sont alors nécessaires pour récupérer tous les points de mesure présents dans la base de données :
- La première requête à l'adresse "http://localhost:8080/unwheeze/auth/clientToken" avec le header 'Authorization':'Basic -token-' pour récupérer une API key qui sera utilisée dans la requête suivante.
- La deuxième requête à l'adresse "http://localhost:8080/unwheeze/airData/getAirCollection" avec le header 'X-Api-Key': -API key-.
Ces deux requêtes sont effectuées de manières synchrone car nous avons besoin que celles ci soient effectuées afin de pouvoir continuer le reste du processus. Mais nous pourrons l'améliorer en l'utilisant de manière asynchrone. De plus, pour effectuer des requêtes en local, nous avons remarqué que nous devions lancer le navigateur en désactivant les sécurité. Par exemple : chromium-browser --disable-web-security --user-data-dir sur ubuntu avec chromium.
- Nous utilisons désormais Highchart pour afficher des graphs sur notre site web. Ces graphs afficherons l'évolution de la pollution au cours du temps au niveau du point cliqué par l'utilisateur. Ces graphs devront donc être modifiés pour prendre en compte les différents points de mesure de pollution se trouvant aux alentours du point cliqué durant les dernières 24H par exemple. Ceci fera donc l'objet d'une nouvelle requête à l'API Rest pour récupérer l'ensemble des points de mesures à afficher sur les graphs lors d'un clic.
Le point délicat étant de pouvoir retrouver quel point de mesure a été cliqué par l'utilisateur et pouvoir envoyer une requête appropriée à l'API. Nous voulons également laisser à l'utilisateur le choix de l'étendue des points qu'il souhaite comparer ainsi que la durée temporelle sur laquelle il souhaite voir l'évolution de la pollution. L'affichage des graphs a nécessité un bon moment de documentation quant a l'utilisation de l'API de Highchart mais nous sommes désormais capable d'afficher un graphique de l'évolution des 3 polluants dans la fenêtre correspondant au marker cliqué par l'utilisateur. Le graphique contient les évolutions au cours du temps des 3 polluants. L'abscisse représentant la date à laquelle la mesure a été effectuée et l'ordonnée représentant le taux de PM25, PM10 ou PM1 mesuré à cet instant en μg/m3. Une légende est également présente en haut à gauche du graphique afin d'expliquer à l'utilisateur quelle courbe correspond à quel polluant. Enfin, en dessous du graphique, on retrouve les informations relatives à la mesure effectuée en ce point précis de la carte. On peut alors trouver le taux de pollution sur chaque polluant ainsi que l'heure exacte de la mesure.
- Nous avons également implémenté la Heatmap sur la carte google map. Celle-ci nous donnera sans cliquer une indication de la pollution que l'on trouve aux différents endroits de la ville. Elle affichera en rouge les points avec le plus de pollution et en vert les zones les moins polluées et à privilégier par l'utilisateur.
Semaine 8
Capteur
- Nous avons reçu notre capteur et avons commencé à l'utiliser grâce à un Arduino que nous maîtrisons davantage pour le tester. Nous avons bien réussi à récupérer les valeurs sur l'Arduino et sommes donc passé à l'ESP32. Nous avons alors dû réaliser le programme qui attend de recevoir un caractère par bluetooth depuis le téléphone pour envoyer les valeurs du capteur de pollution sur le téléphone. Ces valeurs sont récupérées via le protocole série suivant :
Baudrate: 9600, Parité: None; Stop Bits: 1; longueur du paquet : 32 octets. Description du paquet :
nom |
Start char 1 | Start char 2 | length | data 1 | data 2 | data 3 | data 4 | data 5 | data 6 | data 7 | data 8 | data 9 | data 10 | data 11 | data 12 | data 13 | check data sum |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Nombre d'octets |
1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
signification |
0x42 | 0x4d | 2*13+2=28 | concentration de PM1.0 en ug/m3 | concentration de PM2.5 en ug/m3 | concentration de PM10.0 en ug/m3 | test data interne | test data interne | test data interne | nombre de particules de diamètre supérieur à 0.3um pour 0.1 litre d'air | nombre de particules de diamètre supérieur à 0.5um pour 0.1 litre d'air | nombre de particules de diamètre supérieur à 1.0um pour 0.1 litre d'air | nombre de particules de diamètre supérieur à 2.5um pour 0.1 litre d'air | nombre de particules de diamètre supérieur à 5.0um pour 0.1 litre d'air | nombre de particules de diamètre supérieur à 10.0um pour 0.1 litre d'air | test data interne | somme de tous les octets précédents |
Pour vérifier qu'une mesure a été prise, on va regarder le moment où l'on reçoit le caractère 0x42 sur la liaison série. Cela signifie alors que les 31 bits qui suivent sur la liaison série représentent la trame. Celle ci est donc enregistrée dans notre variable buf qui est un tableau de char de longueur 31 pour contenir tout le reste de la trame. Nous analysons ensuite celle-ci afin de vérifier que les octets reçus représentent bien le message envoyé par le capteur et qu'aucune erreur n'a été introduite durant la transmission. Nous vérifions donc que le premier octet de la trame est bien l'octet 0x4d puis nous vérifions que le checksum final est bien égal à la somme de tous les octets de la trame. Enfin, après nous être assuré que la trame est correcte grâce aux vérifications précédentes, nous récupérons les octets 5 et 6 pour le PM1, 7 et 8 pour le PM2.5 et les octets 9 et 10 pour le PM10. Ces valeurs, une fois récupérées doivent être converties en string afin de pouvoir les envoyer au téléphone qui se chargera de les enregistrer et de les afficher à l'utilisateur. Nous arrivons alors à nous connecter, et recevoir sur les 3 champs différents les valeurs de PM10 PM2.5 et PM01 comme le montre la vidéo suivante :
Cependant, notre programme devra par la suite utiliser le pin SET du capteur de pollution pour le laisser en mode faible consommation d'énergie tant que nous ne l'utilisons pas.
Site web
- Nous avons apporté des modifications au site web afin de faire des ajustements esthétiques et permettre davantage de fonctionnalités graphique pour visualiser l'évolution de la pollution sur le site web. Il est notamment possible d'afficher les graphiques selon l'intervalle de temps et la distance choisie par l'utilisateur au moyen d'un curseur. L'utilisateur doit toujours cliquer sur un marker afin de visualiser l'évolution de la pollution autour de ce point mais il lui est désormais possible de cliquer sur le petit "+" en bas à droite de la fenêtre du marker pour ouvrir un volet sur le côté droit de la page. Celui ci affiche 3 graphiques représentant l'évolution des 3 polluants différents et permet de modifier l'intervalle de temps et de distance pris en compte pour afficher ces évolutions au moyen de 2 curseurs.
L'utilisateur peut alors choisir le nombre d'heures durant lesquelles il souhaite que l'analyse soit réalisée (par pas de 1h allant de 1h à 24h puis par pas de 1 jour allant de 1 à 3 jours). L'utilisateur peut également sélectionner dans quel périmètre il souhaite prendre en compte les données relevées autour du point sélectionné. Ce périmètre est représenté par un cercle bleu qui s'affichage lorsque l'on maintient enfoncé le curseur de distance afin de mieux visualiser la modification en cours. Le périmètre autour du point sélectionné peut être modifié par pas de 100m de rayon allant de 0 à 2km.
On peut alors voir sur cette capture d'écran que le graphique est modifié en temps réel lorsque l'on actionne l'un des deux curseurs.
- Nous avons également modifié le système de heatmap qui est désormais réalisé à l'aide de heatmap.js. La heatmap de google que nous utilisions précédemment ne correspondait en effet pas à nos attentes car elle prenait en compte le poids de chaque point ainsi que leur concentration. Or, nous ne voulions prendre en compte que le poids de chaque point évalué afin que les localisations où beaucoup de mesures ont été effectuées ne soient pas considérés comme plus polluées que les localisations avec une seul mesure réalisée. La heatmap que nous utilisons désormais fonctionne donc sous forme d'interpolation. La densité des points n'est donc plus prise en compte et seul le poids donné à chaque point permet de modifier la couleur d'apparence sur la carte. Heatmap.js étant compatible avec la carte offert par maps comme le montre la documentation citée en bas de wiki, ceci nous a donc permis de l'implémenter plus facilement.
Nous avons également ajouté 4 boutons en haut à droite de la page pour permettre à l'utilisateur de choisir le type de polluant avec lequel il souhaite que la heatmap soit mise à jour. Le bouton le plus à gauche représente la moyenne des 3 polluants (Il représente la heatmap affichée par défaut lors de l'arrivée de l'utilisateur sur le site). Les 3 autres boutons permettent de mettre à jour la heatmap en fonction d'un polluant en particulier. Le type de heatmap active est indiqué par la couleur d'un des 4 boutons qui devient alors plus foncé que les autres.
Analyse
- Nous avons pu contacter une personne s'occupant de l'analyse des données de pollution sur Lille qui nous a expliqué comment vérifier les valeurs obtenues sur notre capteur. En effet, 2 stations de mesures sont disponibles sur Lille. Une stations de à proximité du traffic : Boulevard de Leeds 59700 Lille à coté du Crown Plaza et une station bruit de fond à coté de l'école Lakanal à fives (Groupe Lakanal Campau - Rue du long Pot 59800 Lille Fives).
Les valeurs sont prises à hauteur d'homme pour simuler au mieux la pollution à laquelle un être humain peut être exposé en ville.
Nous devrons donc vérifier si notre capteurs ne sous estime pas la pollution en ville ou au contraire ne la surestime pas. En effet, pour l'instant, nous avons seulement pu vérifier superficiellement que les valeurs étaient correctes. Dans notre maison, les valeurs sont entre 0 et 8 ug/m3 pour chaque polluant alors que à coté du pot d'échappement d'une voiture, nous arrivons jusqu'à des valeurs de 127ug/m3. Lorsque notre projet sera plus avancé, nous ferons donc les mesures juste à coté de ces deux stations afin de vérifier la précision de nos mesures et de vérifier que notre capteur est bien précis en comparant les valeurs avec celles disponibles sur le site de l'ATMO : http://www.atmo-hdf.fr/acceder-aux-donnees/mesures-des-stations.html
API REST
- Nous avons implémenté la quasi totalité des fonctionnalités REST.
L'API est organisée en trois différentes classes de requêtes, dont deux se révèlent particulièrement importantes pour notre projet.
L'une des deux premières classes de requêtes correspond aux requêtes de sécurité, qui permettent d'obtenir des clés d'API ou un token utilisateur afin de réaliser des actions nécessitants des privilèges. Ces méthodes d'obtention de clés sont primordiales : aucune requête ne peut être réalisée sans la spécification des clés obtenues dans un header. La clé d'API permet de réaliser les requêtes correspondantes à la classe des requêtes des données de l'air. Il n'est pas nécessaire d'être authentifié pour l'obtenir. Le tableau suivant décrit les requêtes possibles de cette classe.
URL | Méthode | X-Api-Key | Consomme | Produit | Commentaire |
---|---|---|---|---|---|
/auth/clientToken | GET | Non | Aucun | JSON | Retourne un objet JSON avec un champ key
contenant la clé. |
/auth/token | GET | Non | Aucun | JSON | Retourne un Json Web Token (JWT) à l'utilisateur.
Le header doit contenir un champ Authorization contenant son email et son mot de passe de la forme email:mdp encodé en base 64. Le JWT est valide uniquement pour une durée limitée. |
Le tableau suivant regroupe la liste des requêtes possibles de la classe des données de l'air. Cette classe de requêtes permet d'insérer une donnée de l'air à travers une requête POST, dont les spécifications sont précisées par la suite. Elle permet, à travers plusieurs requêtes GET de récupérer une donnée de l'air spécifique, l'ensemble des données ou encore, les données les plus proches d'un point particulier.
URL | Méthode | X-Api-Key | Consomme | Produit | Commentaires |
---|---|---|---|---|---|
/airData/putAirData | POST | Oui | JSON | JSON | Consommes un élément suivant le modèle
de l'objet AirData, décrit par la suite. |
/airData/getAirCollection/ | GET | Oui | Aucun | JSON | Renvoi un tableau JSON de tout les points mesurés
présents dans la base de donnée. |
/airData/getAirData/{id} | GET | Oui | Aucun | JSON | Retourne un point mesuré en particulier, spécifié dans
l'URL par son UUID. |
/airData/getNearest/{location} | GET | Oui | Aucun | JSON | Retourne un tableau JSON contenant
la liste des points les plus proches du point specifié selon le format latitude,longitude dans l'URL. L'objet retourné dispose de la distance dans un champ dist et du point en question dans le champ doc. |
L'ensemble des requêtes, comme indiqué dans le tableau, nécessitent la présence d'une clé d'API dans le header X-Api-Key. Une clé invalide renvoi un code 403 (accès refusé). La spécification du header content-type est également nécessaire dans le cas de la requête d'insertion. Les requêtes consomment du JSON, il faudra donc spécifier application/json.
Enfin, une donnée insérée doit contenir nécessairement les champs suivants :
{ "location":"104.28,32.25", "pm25":254.5, "pm10":500, "pm1":250, "geolocation": POINT(104.25,32.25), "datetime":"2018-04-02T22:55:58.545Z" }
L'id est généré automatiquement. Le champ geolocation contient un élement JSON de type Point défini par RethinkDb. Un java bean de cet objet JSON est disponible sous la package bean du code source de notre API, défini par la classe GeoBean. Il n'est normalement pas nécessaire de se soucier des champs geolocation et datetime, l'API les ajoutants automatiquement.
Ce format d'insertion correspond également au JSON renvoyé lors des requêtes GET, à la seule différence que le champ ID est également retourné.
Application mobile
- L'application Android se connecte maintenant au capteur et permet de réaliser une mesure et de l'envoyer sur le serveur. Nous avons choisi BLE (introduit par Bluetooth 4.0) afin de mettre en place la liaison bluetooth et minimiser l'impact de l'utilisation sur la batterie. En effet, BLE permet de ne transférer des données que sur demande, au contraire d'une liaison bluetooth classique. Ce moyen de communication atteint un maximum d'utilisation de 15 mA, tandis que le Bluetooth classique peut drainer la batterie avec des pics à 150 mA.
- Nous utilisons le framework Volley afin de réaliser les requêtes HTTP.
Nous travaillons maintenant à mettre en place une connexion websocket sur le smartphone, tournant en tâche de fond et notifiant l'utilisateur lors de la réception d'un message, réalisant les actions nécessaires, telles que l'affichage sur la carte.
Semaine 9
Capteur
- Maintenant que notre capteur de pollution fonctionne, nous avons commencé le pcb pour faire fonctionner le capteur sans breadboard. Cependant, nous n'avons pas trouvé de fichiers déjà réalisés pour modéliser notre ESP32 ainsi que notre capteur de pollution que ce soit sur altium ou eagle. Nous avons donc décidé de redessiner les fichiers schematic et pcb pour les deux composants sur altium car nous avions eu des cours sur ce logiciel l'année dernière.
Le premier travail fut donc de réaliser les footprints et schematic de chacun de nos composants. Le plus long était de prendre en main le logiciel et comprendre comment réaliser au mieux les fichiers de footprints des composants. Pour cela, nous avons regardé des tutoriels vidéos sur internet (https://www.youtube.com/watch?v=nYI8sw__9_Y) expliquant comment créer un nouveau composant. Nous devions donc créer premièrement une schematic Library pour notre composant sur laquelle on dessine notre composant ainsi que le nom des pins qui seront utilisés sur celui ci. Par la suite, nous créons un PCB Library pour dessiner la footprint du composant. Enfin, il faut associer le fichier .pcb au fichier .schematic. Il faut alors être vigilent à ce que chaque pin sur le fichier schematic et pcb ai bien le même nom pour être reliés ensemble lors du routage.
L'empreinte de l'ESP32 fut la plus simple à réaliser car les pins étaient tous espacés de la distance réglementaire de 2,54mm. Il a donc suffit de fixer la grille à 1,27mm afin de pouvoir poser chaque pastille espacée de 2.54mm. Notre ESP32 étant composé de 20 pastilles de chaque coté.
- Nous avons également commencé à dessiner les schémas de notre coque et un premier modèle 3D sur Freecad qui encapsulera tous les composants de notre capteur. Cette coque devra contenir la batterie, le capteur, l'ESP32 et un interrupteur pour allumer et éteindre le capteur. De plus, nous devrons ajuster la largeur de la coque à celle du PCB afin que celle ci soit la plus petite possible et que tous les composants restent bien fixés lors des déplacements de l'utilisateur.
Back-end
- Le back-end est quasiment complété. Il ne manque qu'à le mettre sur le cloud. Pour cela, deux choix sont possibles après discussion avec nos enseignants : soit utiliser une plateforme tierce, soit utilisée une machine virtuelle fournie par Mr Redon. Il s'agira d'une décision à prendre par la suite, lorsque nous nous assurerons que l'API et le serveur websocket fonctionnent sans aucun soucis.
Nous avons également fini d'implémenter les méthodes retournant un tableau JSON des points les plus proches à un point passé en paramètre de l'URL.
Serveur websocket
- Nous avons complété la connexion websocket sur l'application
Nous avons mis en place le serveur websocket afin de maintenir une communication bilatérale entre le serveur et les clients. Nous prenons avantage de la fonctionnalité "d'abonnement" à une table, décrite précédemment, afin d'implémenter le caractère temps réel de l'application. Ainsi, à l'ouverture de la connexion websocket, un nouveau thread est lancé afin de traiter de manière asynchrone les demandes d'abonnement à la table contenant les données relatives à l'air. Ainsi, à chaque insertion ou modification d'une donnée, un message est envoyé à tout les clients abonnés, contenant le nouvel objet ajouté, selon la syntaxe décrite dans la partie précédente. A la réception d'un message, le serveur insère la donnée dans la base de donnée.
Le fonctionnement interne du websocket est très simple, notamment grâce à l'implémentation native des websockets sous Jersey.
- Nous réalisons également de nombreux test afin de vérifier le bon fonctionnement de notre API. Ces tests sont réalisés en java en se plaçant dans un package test, en créant une classe ayant le nom de la classe à tester, suivie d'un suffixe 'Test' et en héritant de la classe TestCase. Chaque méthode à tester suit la même idéologie de nommage et est précédée d'une annotation @Test.
Application mobile
- Nous avons commencé l'écriture du service Android qui tournera en fond. Nous utiliserons un BroadcastReceiver afin de communiquer avec l'activité principale de l'application et d'afficher les valeurs reçues sur la carte.
- Nous avons également beaucoup travaillé sur le design de l'application afin de faire en sorte que la compréhension du fonctionnement soit intuitive.
Semaine 10
Capteur
- Nous avons modifié le programme de l'ESP32 afin que celui ci passe en lower consumption mode lorsqu'il n'a pas besoin de faire de mesures. Lors de notre programme principal, nous attendons qu'un téléphone se connecte à l'ESP32. Si cela se produit, nous allons utiliser une boucle while pour vérifier toutes les 100ms si notre ESP32 reçoit le caractère "B" dans la variable rxValue. Tant que cela n'est pas le cas, nous laissons le capteur de pollution en mode sleep afin de consommer moins d'énergie. Cela se fait au moyen du signal sur le pin 5 de l'ESP32, relié au pin Sleep du capteur. Nous le mettons donc à l'état bas lorsqu'aucune mesure n'est demandée puis nous passons le signal à l'état haut avant de demander une mesure. Cependant, nous avons remarqué que si nous ne laissions pas un delay entre le moment où nous sortons le capteur de pollution du mode sleep et le moment où nous effectuons la mesure, celles ci étaient fausses. Après des tests avec différentes durées de delay, nous avons décidé d'imposer 5 secondes d'attente avant de prendre la mesure. Ce temps d'attente nous parait en effet acceptable au vu du gain sur l'autonomie de la batterie.
Nous avons également pu vérifier l'efficacité de ce changement en mesurant à l'aide d'un ampèremètre le courant effectivement consommé. En effet, lorsque le capteur est en état de fonctionnement continu, nous avons mesuré une consommation de 60mA et lorsque celui ci est au repos, nous avons mesuré moins de 10mA. Ce qui représente un grand gain en terme de longévité pour notre batterie.
- La réalisation des fichiers schématic et pcb de l'adaptateur du capteur de pollution fut un peu plus complexe que celle de l'ESP32 car nous ne possédions pas de datasheet fiable. La datasheet portait à chaque fois sur le capteur en lui même et non pas sur l'adaptateur. L'adaptateur du capteur est composé de 6 pins espacés de 2.54mm ainsi que de 2 pins représentant le sleep et le set qui, eux, furent difficiles à positionner. En effet, nous avons dû mesurer à l'aide d'un pied à coulisse (pour plus de précision) les espacements entre ces deux pins et le reste des pins de l'adaptateur afin de réaliser la footprint. De plus, les pins de set et sleep étaient positionnés dans le sens opposé au reste des pins comme le montre la photo sur la gauche. Ce positionnement ne nous arrangeait pas pour le fixer sur notre PCB. Nous avons donc décidé d'inverser les pins pour nous faciliter la tâche. Cette inversion a pu être réalisée avec l'aide de Thierry car la fixation industrielle de ces pins les rendaient difficile à désouder sans risquer de casser notre composant.
Le visuel des footprints réalisées est visible ci dessous :
Nous avons ensuite réalisé le schéma composé de tous nos composants afin de les relier entre eux et de pouvoir réaliser le routage de notre carte. Enfin, nous avons ajouté le plan de masse ainsi que les contours mechanicals. Notre PCB est donc terminé et nous devons désormais le graver afin de pouvoir vérifier son bon fonctionnement ainsi que sa compatibilité avec la coque en plastique.
Déploiement sur Amazon Web Service
Nous avons fini par opter pour un déploiement sur Amazon Web Service (AWS) en raison du fait que la machine virtuelle n'était pas assez puissante afin de faire tourner RethinkDb. Amazon Web Service, de par son service EC2, offre la possibilité de lancer des instances linux, sous les distributions de notre choix. Les instances sont connectés aux serveurs Amazon et disposent donc d'un accès internet. Nous avons du configurer une adresse IP et ouvrir les ports afin d'accéder à notre serveur Tomcat. Cette configuration se fait par le biais de l'interface proposée par AWS. Afin d'ouvrir les ports aux paquets entrants, nous avons du mettre en place un groupe de sécurité, dans lequel nous définissions une autorisation à tous les paquets HTTP entrants sur les ports 80 et 8080.
L'adresse IP associée à notre serveur Tomcat est : http://18.219.202.43:8080/Unwheeze/
Le serveur websocket quant à lui est accessible sur le lien : ws://18.219.202.43:8080/Unwheeze/realtime/airDataFlow
Le site web est disponible sur : http://18.219.202.43/
Semaine 11
Capteur
- Nous avons pu graver notre PCB. Celui ci a été testé : aucun court circuit n'a été constaté. Nous avons également sélectionné les résistances qui nous permettront d'allumer les LEDs sans créer de surtension dans les LEDs. En effet, notre ESP32 transmet une tension de 3,3V. Les deux leds que nous utilisons sont la OVS0806 (jaune) qui selon la datasheet accepte au maximum 20mA pour une tension de 2.1V tandis que nous n'avions pas la datasheet pour la led sml31ovtt86p (rouge). Nous avons donc décidé de calculer la chute de tension induite par les 2 leds grâce à un multimètre. Cela nous permettait donc de remédier au manque de datasheet pour la led rouge et de vérifier celle de la led jaune. Nous avons alors trouvé que la led rouge induisait une chute de tension de 1,45V et la jaune : 1,63V.
Sachant que nous devions avoir un courant de 20mA au maximum dans les LEDs. Nous avons décidé d'assurer une marge de sécurité et avons donc fait nos calculs avec 12mA. Le simple calcul U=RI nous donne alors des résistances de 139 Ohm pour la led rouge et 154 Ohm pour la led jaune. Cependant, après quelques tests, la LED jaune nous semblait éclairer un peu fort et nous ne voulions pas que celle ci brûle durant une trop longue utilisation. Nous avons donc augmenté la valeur des résistances et avons choisi d'utiliser des résistances de 270 Ohm qui nous donnaient entière satisfaction.
Pour alimenter notre carte, nous avons décidé de connecter 2 fils directement sur la batterie afin de pouvoir miniaturiser notre capteur. Cette astuce nous permettant de gagner 4 à 5 cm de longueur sur le capteur car nous n'avons plus besoin de câble pour connecter notre capteur. Ces deux fils ont été soudés sur la carte au moyen de pins car nous avons utilisé un fil épais pour transporter le courant jusqu'à la carte. Un interrupteur permet par la suite de séparer le reste de la carte de la batterie. En effet, cela nous permet de pouvoir téléverser un nouveau programme dans l'ESP32 facilement sans risquer de poser problème entre l'alimentation par la batterie et l'alimentation usb du PC. Nous avons également positionner des headers sur la carte afin de ne pas souder directement l'ESP32 et l'adaptateur du capteur de pollution sur le PCB. Cependant, les pins utilisés sur l'ESP32 étant assez gros, il n'est pas facile de le retirer. Notre interrupteur nous permet donc de téléverser nos programmes sans risque d'endommager les pins de l'ESP32 en le retirant.
- Nous avons terminé la réalisation de la coque sur freecad dont voici le dessin 3D :
Vous pouvez donc voir qu'une chambre d'air a été créée en haut du capteur de pollution. Les trous dans les parois de tous les cotés permettent de laisser passer l'air à analyser tout en évitant d'avoir des trop grands afflux d'air qui peuvent perturber le capteur en cas de grand vent. De plus, le capteur est maintenu en position de chaque coté par des petits supports de plastique. Un petit support le maintient également en hauteur pour que le capteur soit bien au centre de la chambre d'air. Enfin, un trou a été laissé sur le coté afin de laisser passer les câbles du capteur jusqu'au PCB. La batterie est, elle, maintenue des deux cotés afin de ne pas bouger et des trous ont été dessinés afin de pouvoir : appuyer sur le bouton marche/arrêt et de pouvoir brancher le câble de rechargement de la batterie.
Un espace a également été prévu pour venir placer le PCB au dessus de la batterie. Celui ci sera alors maintenu par une petite partie en plastique qui ressort de chaque coté. La partie supérieure de la coque est également perforée pour laisser passer l'air et permettre de voir les LEDs qui s'éclaireront pour dire si le capteur est allumé et si il est en train de prendre une mesure. Cette partie supérieure de la coque vient ensuite se refermer sur le PCB est le bloque totalement afin que celui ci ne bouge plus. Tous les éléments sont donc bien maintenus dans la coque.
- Nous avons également essayé d'imprimer notre coque. Cependant, l'impression n'a pas fonctionné. Nous avions déjà dû relancer l'impression au soir car l'imprimante 3D s'était arrêtée puis nous l'avons laissée tourner pendant la nuit et celle ci s'est arrêtée au bout de quelques couches. Nous relancerons donc l'impression la semaine prochaine sur une autre imprimante.
Application mobile
- Le serveur websocket et l'API REST étant fonctionnels et en ligne, nous pouvons nous concentrer pleinement sur la réalisation de l'application mobile.
Nous en profitons ainsi pour perfectionner l'envoi des données et la réception de celles-ci. Ainsi, nous mettons en place un splash screen, permettant de paramétrer l'application, tout en offrant un visuel plaisant. L'activité liée au splash screen effectue de nombreuses tâches en fond, permettant de vérifier la présence des services de localisation, des autorisations nécessaires au fonctionnement de l'application, récupérant ensuite la position de l'utilisateur afin d'optimiser le positionnement de la carte dans l'activité suivante. Nous récupérons également une clé API que nous stockons dans un fichier de données propre à notre application, en compagnie des données mentionnées précédemment.
- Dans l'activité principale, nous réalisons le chargement et le stockage des données dans une base de donnée SQLite locale, en tâche de fond afin de ne pas impacter l'expérience de l'utilisateur.
Un bouton refresh est également mis en place afin de pouvoir recharger la carte en cas d'erreur. Le service android se charge d'ajouter les marqueurs et de stocker les données en cas de réception sur la liaison websocket.
- Nous avons rencontré quelques difficultés dans la communications entre les threads parallèles et le thread principal, les changement sur l'interface utilisateur ne pouvant s'effectuer que sur le thread principal : il nous a donc fallu rechercher le fonctionnement du multi-threading sur Android qui se base intensivement sur les handler et les loopers.
Nous gérons maintenant sans soucis les communications entre threads. Nous avions également un problème de chargement des valeurs, qui ne chargeaient qu'après une seconde tentative. Nous suspectons que nous accédons à la base de donnée trop rapidement après la réception des valeurs. Un handler exécuté après un certain temps réglera ce problème.
Semaine 12
Capteur
- Les composants étant soudés sur notre carte, nous avons pu tester cette dernière pour vérifier qu'elle fonctionne correctement. Nous arrivons à allumer les 2 leds rouge et jaune ainsi qu'à utiliser le capteur de pollution avec l'ESP32. Enfin, nous avons dû connecter la batterie sur la carte. Cependant, nous avons rencontré un problème car si nous connections le PCB à la batterie avec un simple connecteur microUSB, nous aurions dû utiliser le câble prévu à cet effet. Ceci aurait eu pour conséquence d'augmenter la longueur de la coque du capteur de près de 5 cm afin de faire passer le câble microUSB. Nous avons donc décidé d'ouvrir la batterie afin de souder directement les fils sur celle ci. L'autre extrémité des fils étant également soudée directement sur la carte, cela nous permet donc un gain de place considérable afin de miniaturiser notre capteur.
- Au niveau de l'impression de la coque en 3D, nous avons de nouveau eu beaucoup de problèmes. En effet, l'impression s'est arrêtée comme la semaine dernière et nous avons donc dû nous y prendre à 3 fois pour enfin obtenir notre objet en 3D. La pièce correspond à nos attentes. Tous les éléments passent dans la coque et ne bougent presque pas ce qui permettra une meilleur expérience utilisateur. Cependant, nous avons souder l'ESP32 sur la carte au moyen d'un connecteur en barrette femelle afin de pouvoir l'enlever et le remettre sur notre PCB. Celui ci a donc augmenté la place prise par l'ESP32 et nous avons désormais quelques difficultés pour fermer la boite. Nous réimprimerons donc par nos propres moyen une coque pendant les vacances.
- En obtenant l'aide d'Erwan Dufresne et de son imprimante 3D personnelle, nous avons pû réimprimer notre coque. Celle ci étant un peu longue par rapport à la largeur, elle semble avoir tendance à se décoller plus facilement du plateau d'impression ce qui provoquait beaucoup d'échecs. Notre capteur est donc terminé et tous les composants rentrent parfaitement dans celui ci. Le capteur de pollution est placé à l'avant de la coque dans la chambre d'air prévue à cet effet, tandis que la batterie et le PCB qui se superposent à celle ci sont dans la partie arrière de la coque. Voici le résultat :
Site web
- Pour faciliter l'expérience utilisateur, nous avons également implémenté une fonctionnalité qui n'oblige pas l'utilisateur à cliquer précisément sur un marker pour faire apparaître la fenêtre d'informations. En effet, si l'utilisateur clic simplement sur un point arbitraire de la carte, la fenêtre correspondant au point le plus proche s'ouvrira. La difficulté de cette fonctionnalité était de permettre à l'utilisateur de se déplacer sur la carte sans déclencher l'ouverture de la fenêtre du point le plus proche. Car, pour se déplacer sur la carte, il faut effectuer un appui sur la souris puis la déplacer alors que pour demander à ouvrir la fenêtre correspondant au point le plus proche, on effectue un clic. Ces deux événement pouvaient donc entrer en conflit. Un click représentant un mouseDown, suivi d'un mouseUp sans mouseMove entre les deux. Nous avons donc utilisé une variable afin de vérifier si aucun mousemove n'avait été effectué entre le mousedown et le mouseup.
- Lors de l'arrivée d'un utilisateur sur le site, le navigateur demandera désormais si il accepte de divulguer ses informations sur sa position géographique via une fenêtre en haut à gauche de l'écran. Si celui ci accepte, la carte zoomera alors sur sa position actuelle afin de pouvoir afficher les mesures de pollution effectuées autour de lui. Dans le cas contraire, nous avons décidé de faire démarrer la carte sur la ville de Lille. L'utilisateur pourra alors se déplacer librement sur la carte afin de trouver les informations sur les taux de pollution aux endroits qu'il recherche. La localisation de la personne (ou la localisation par défaut si l'utilisateur n'autorise pas la géolocalisation) est affichée en haut à droit de la page. L'utilisateur peut alors simplement cliquer sur cette information pour centrer la carte atour de sa position. L'utilisateur étant représenté par un marker rouge sur la carte.
Application mobile
- Le fonctionnement global de l'application mobile est atteint et nous nous concentrons maintenant sur l'optimisation des performances et la correction de maximums d'erreurs que nous pouvons rencontrer. Nous nous penchons également sur une interface correspondant aux guidelines du material design afin d'offrir une interface plaisante. Les valeurs sont maintenant affichées au bas de l'écran.
- Un clic sur la carte permet d'afficher la valeur du point mesuré le plus proche.
Les erreurs rencontrées ne provoquent plus un crash de l'application mais, au contraire, sont affichées de façon claire et intuitive pour l'utilisateur, afin qu'il comprenne la cause du problème et le moyen de régler ceux-ci. Le plus souvent, les erreurs sont dû à des problèmes d'activation du bluetooth et des services de localisation, ou encore, de la réception de valeurs erronées. Nous tentons de régler le plus de problèmes possibles.
- Nous avons récemment ajouté une option de mesure périodique. En cliquant sur le bouton dédié, une mesure sera réalisée chaque 30 secondes. Cela à été atteint en utilisant un thread tournant en parallèle, executant un ScheduledExecuterService.
Un des désavantages d'utiliser cette méthode de thread est que cette option n'est fonctionnelle que lorsque l'écran est actif. Si le smartphone passe en mode verrouillé, les mesures ne sont pas réalisés. Nous cherchons à améliorer cette fonctionnalité.
- Les différentes versions de l'application sont disponibles au téléchargement sur le lien suivant, accompagnées d'un numéro de version et de commentaires sur les correctifs apportés. L'application sera mise à jour continuellement jusqu'à la date du rendu. Une documentation est également disponible sur le lien fourni tant pour l'API accompagné du serveur websocket, que pour l'application mobile, moins commentée, mais dont les classes et méthodes sont représentées.
Nous avons tenté d'écrire un code le plus modulaire possible et de privilégier une syntaxe claire afin de faciliter toute maintenance du code.
Mesures, Interprétation et validation de notre prototype de capteur
Afin de vérifier que notre capteur fonctionnait correctement et fournissait bien des mesures fiables à l'utilisateur, nous avons décidé de le tester en situation réelle proche des stations de mesure de l'ATMO qui gère sur Lille les stations de Lille Leeds à côté de la gare lille europe et de Lille fives dans l'école Lakanal. Nous nous sommes donc rendu juste à coté de ces stations afin de comparer nos valeurs aux mesures théoriques de cet organisme.
Mesures expérimentales à l'aide de notre capteur
La première station que nous avons visité est celle de Leeds. Nous avons effectué des mesures toutes les minutes environ entre 10h et 11h. Celles si sont toutes visibles sur le site et l'application mobile en cliquant aux alentours de la station. Cela nous a donc permis de réaliser une moyenne des valeurs autours de ce point pour comparer la moyenne sur l'heure à celle de l'ATMO. Nous nous sommes ensuite rendu à la station située dans l'école Lakanal qui a accepté de nous recevoir pour effectuer les mesures de 11h20 à 12h20. Voici donc la moyenne des résultats que nous avons obtenu sur chaque polluant et chaque station :
Station | heure | PM10 (ug/m3) | PM2.5 (ug/m3) | PM1 (ug/m3) |
---|---|---|---|---|
Leeds | 10h - 11h | 25.46 | 20.76 | 11.57 |
Fives | 11h20 - 12h20 | 28.08 | 22.57 | 12.11 |
Mesures théoriques relevées par l'agence ATMO
Ces mesures sont disponibles après quelques heures sur le site : http://www.atmo-hdf.fr/acceder-aux-donnees/mesures-des-stations.html
- La station de Leeds à Lille europe, ne mesure que les PM2,5. Nous avons alors pu récupérer ces valeurs théoriques :
Station | heure | PM2.5 (ug/m3) |
---|---|---|
Leeds | 10h | 18.1 |
Leeds | 11h | 21.4 |
Ayant obtenu une valeur de PM2.5 de 20.76ug/m3 aux abords de cette station, nous sommes donc très proche de cette valeur.
- La station de fives, elle, mesure le PM2.5 et le PM10.
Station | heure | PM2.5 (ug/m3) | PM10 (ug/m3) |
---|---|---|---|
Fives | 10h | 20.8 | 29.9 |
Fives | 11h | 24.7 | 30.1 |
Fives | 12h | 23.7 | 27.4 |
Ayant obtenu des valeurs de PM2.5 de 22.57 ug/m3 et de PM10 de 28.08 aux abords de cette station, nous semblons donc proche de ces valeurs.
Conclusion
La datasheet de notre capteur indiquant une précision de +/- 15% de précision, nous pouvons conclure que cette intervalle de précision est respecté et offre donc une assez bonne précision à l'utilisateur. Cela permet en effet d'obtenir une bonne idée du niveau de pollution dans la ville. Cependant, lors de notre entretien avec une personne responsable du service des risques urbains et sanitaires de Lille, celle ci nous avait indiqué que la station de Leeds était une station proche du traffic et donc avec un taux censé être plus élevé que la station de Fives qui est une station bruit de fond. En effet, celle ci est au fond de la cours de l'école avec très peu de traffic aux alentours. Mais nous avons pu remarquer en observant les alentours de l'école que de gros travaux étaient en cours sur un batîment juste à coté de celle-ci. De nombreuses particules fines devaient donc être présentes lors de nos mesures. Cela montre donc une nouvelle fois la fiabilité du capteur que nous avons conçu.
Documents Rendus
- Fichiers des footprints et schematics réalisés sous altium : footprints et schematics
- Fichiers modélisation 3D réalisés sous freecad : Modélisation 3D coque freecad
- Gitlab du projet : https://archives.plil.fr/pribeiro/unwheeze
- Versions de l'application mobile (la plus récente est la Beta 0.1.3) : http://18.219.202.43:8080/Unwheeze/
- Rapport du projet : Rapport du projet
Documentation
- heatmap.js pour gmaps : https://www.patrick-wied.at/static/heatmapjs/example-heatmap-googlemaps.html
- Documentation pour installer le dev module arduino pour l'ESP32 : https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide?_ga=1.189350435.90086807.1452767181#installing-the-esp32-arduino-core
- Documentation google maps API for javascript : https://developers.google.com/maps/documentation/javascript/tutorial?hl=fr
- Semantic ui documentation pour le design du site web : https://semantic-ui.com/
- tutoriel création de footprints : https://www.youtube.com/watch?v=nYI8sw__9_Y
- Documentation RethinkDb : https://www.rethinkdb.com/docs/
- Documentation Android : https://developer.android.com/guide/
- Documentation Google Maps pour Android : https://developers.google.com/maps/documentation/android-api/?hl=fr