P26 Réseau de capteurs de pollution

De Wiki de Projets IMA
Révision datée du 21 février 2018 à 14:21 par Mbutaye (discussion | contributions) (Carte Google Map sur Android)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)

Etudiante : Marianne Butaye
Encadrants : Alexandre Boé, Xavier Redon & Thomas Vantroys

Présentation générale du projet

Actuellement, seuls deux capteurs de pollution sont présents sur la métropole, un à Lille et l'autre à Fives. Une carte de pollution de la zone est générée à partir de ces deux capteurs et d'un algorithme tenant compte des déplacements des nuages. L'objectif serait de pouvoir avoir une carte de la pollution en temps réel dont les données seraient obtenues à partir d'objets connectés. Chaque personne se déplaçant avec un de ces objets contribuerait à fournir des informations pour compléter la carte de pollution.

L'objet connecté prendrait la forme d'une carte portative, qui pourrait être attachée sur un brassard ou un vélo. La carte portative enverrait des relevés par bluetooth à un téléphone Android, qui lui-même les enverrait ensuite par la 3G à une base de données. Il sera également possible d'effectuer ces transmissions par une puce LORA, au choix de l'utilisateur.

Schéma de fonctionnement du projet

La carte électronique sera composée au minimum d'un capteur de particules, d'un micro-contrôleur, d'une puce bluetooth et d'une puce LORA. On pourrait éventuellement rajouter d'autres capteurs comme un capteur de pression atmosphérique, un accéléromètre etc.

Cahier des charges

Tâches à réaliser

Ce projet se découpe en différentes parties :

  • Mini état de l'art
  • Réalisation de la carte électronique
    • Programmation
    • Design sur ordinateur
    • Gravure & soudage
    • Tests
  • Application Android
  • API REST et base de données

Matériel fourni

  • 1 boîte en plastique pour stocker le matériel
  • 1 câble USB/mini USB
  • 1 carte STM32F401RE nucleo
  • 1 shield Bluetooth nucleo (BLE IDB04A1)
  • 1 kit d'évaluation ST microelectronics. La carte possède une puce Bluetooth et un STM32 ainsi que des capteurs divers. Une application Android est disponible sur le site de ST microelectronics.
  • 1 téléphone Android LG G4C
  • 2 capteurs de particules
  • 1 board pour passer du câble à des PINs
  • Des convertisseurs 3.3V -> 5V
  • 1 SensorTile Module (STM32 + bluetooth + capteurs + antenne)
  • 1 module GPS programmable DS-GPM
  • des câbles MM et FF

Planning

Répartition du travail effectué
Tâche Sous-tâche Semaine 1 Semaine 2 Semaine 3 Semaine 4 Semaine 5 Semaine 6 Semaine 7
Réunion avec les encadrants x x
État de l'art x
Carte électronique Programmation du micro-contrôleur x x x x x x
Design sur ordinateur x x x x
Gravure & soudage x
Tests x
Application Android x x x x x
API REST et base de données x

Avancement du projet

Semaine 1 (du 08/01/2018 au 14/01/2018)

Je commence par rencontrer mes encadrants de projet afin d'établir le contexte et les objectifs de celui-ci, de récupérer le matériel et le travail déjà commencé auparavant.

La première chose à faire est de réaliser un mini état de l'art, pour mieux s'approprier le sujet.

État de l'art

Les équipements pour mesurer la pollution étant trop chers et donc réservés aux experts, les micro-capteurs de pollution ont fait leur apparition. Ceux-ci sont plus légers, portables, peu chers, faciles à utiliser et connectés. Les capteurs de particules fonctionnent par détection optique par diode laser. On aspire d'abord l'air par un ventilateur, qui circule ensuite dans une chambre de détection. La chambre permet de séparer les particules pour ne garder que les plus fines (les plus dangereuses). Le flux d'air chargé de particules traverse ensuite le signal optique émis par une diode laser dont le faisceau est diffracté par une lentille. Un photodétecteur placé face au faisceau émis recueille les baisses de luminosité liées au passage des particules. Il compte leur nombre par plages de tailles. À partir du débit de l'air, on peut remonter à une concentration en nombre puis en masse.

On repère plusieurs types de capteurs de pollution : les stations connectées et les capteurs nomades.

Dans les stations connectées, on retrouve les produits Footbot et Koto Air. La première mesure tous les niveaux de pollution, tandis que la seconde n'en mesure pas autant mais relève aussi l'humidité, la température, la luminosité et le niveau de bruit.

Ce projet est de la catégorie des capteurs nomades. On trouve dans cette catégorie le capteur français Flow de la société PlumeLabs, l'Atmo tube, Clarity, un capteur chinois et le Tzoa. Ces capteurs relèvent la plupart différentes pollutions, telles que les particules fines, le monoxyde d'azote, le monoxyde de carbone, l'ozone et les composés organiques volatiles (provenant de la pollution intérieure : moquettes, peintures, colles, plantes etc.). Certains embarquent aussi d'autres capteurs pour par exemple mesurer la température, l'humidité etc. Ces capteurs nomades ont pour principe de relever et traiter les données par le capteur, puis ensuite de les transmettre à une application mobile. Certains ont même vocation à les transmettre à une base de données selon le principe du "crowdsourcing", où les données récoltées sont partagées entre tous les utilisateurs; c'est le cas des capteurs Flow et Clarity.

Enfin, on trouve des capteurs nomades avec une forme un peu plus originale, comme c'est le cas des pulls réalisés par Nikolas Beltel, designer du groupe Aerochromics; ces pulls changent de couleur en fonction du taux de pollution pour des pollutions telles que les particules fines, le monoxyde de carbone ou encore la radioactivité.

Connexion bluetooth entre la carte STM32 et le téléphone

J'ai ensuite abordé en premier la connexion entre la carte STM32 et le téléphone, n'ayant pas encore eu une partie du matériel (le capteur de particules entre autres).

La carte STM32 est programmable grâce à un IDE disponible sur le site de MBed. Cet IDE est disponible en deux versions : en ligne ou à télécharger. J'ai décidé d'utiliser la version en ligne, celle-ci étant facile d'accès. Il suffit de créer un programme en ligne et de le compiler. Le fichier binaire ainsi créé est ensuite automatiquement téléchargé par le navigateur, et un drag&drop sur la carte STM32 (branchée par USB à l'ordinateur) permet de la reprogrammer.

La carte nécessite l'ajout d'un Shield Bluetooth pour la communication. On utilise ici le modèle BLE IDB04A1, un modèle aujourd'hui obsolète, ce qui a posé quelques problèmes pour la connexion à la carte. Le site de MBed a en effet beaucoup d'exemples et librairies disponibles en ligne, mais les projets BLE_HeartRate_IDB0XA1 et BLE_HeartRate_IDB04A1 ne fonctionnent pas avec ce modèle. Cette version-ci par contre fonctionne en partie. J'ai ainsi pu établir une connexion partielle, en suivant ces instructions puis celles-ci pour la partie Android.

Il s'est avéré que même l'exemple fonctionnant partiellement posait problème lors de l'initialisation du module Bluetooth. Un débogage manuel a permis de déterminer exactement d'où venait l'erreur : le problème se produit lors de l'initialisation de la communication SPI entre les deux objets. Le problème vient en fait de l'utilisation de la LED : il n'est pas possible de l'utiliser en même temps que le Shield Bluetooth. Il faut, pour résoudre ce problème, connecter deux PINs ensemble (le 11 et le 31 du côté CN10 de la carte) par un jumper.

Une fois le problème résolu, on peut voir s'afficher la configuration du module au démarrage de celui-ci sur un terminal connecté en série à la carte.

Une application Android est disponible pour tester les exemples. J'ai ainsi téléchargé l'application STM BLE Profiles sur le Play store. Le dispositif est reconnu et je peux accéder aux informations programmées dans la carte et transmises par Bluetooth.

Un service de l'application Android STM BLE Profiles transmis par la carte

L'intallation d'Android Studio étant particulièrement longue, je n'ai pas encore pu tester la connexion par Bluetooth avec une application Android se connectant aux services que j'ai créé dans le programme de la carte.

Semaine 2 (du 15/01/2018 au 21/01/2018)

Programmation du capteur de particules

Le capteur de particules est le SEN0177. On peut le connecter à un micro-contrôleur par 4 fils : VCC (5V), GND, TX et RX. Ce capteur est livré avec une carte adaptateur pour passer du connecteur à des PINs traditionnels. Il fonctionne selon une trame préétablie que l'on peut récupérer sur le site du constructeur (voir la bibliographie). On y trouve également un programme d'exemple pour Arduino que je me suis chargée de transcrire pour le faire fonctionner sur l'environnement de développement MBed.

Connexion du capteur de particules SEN0177 à la carte STM32

Une chose importante est de ne pas se tromper sur le branchement des fils : le RX de l'adaptateur doit être connecté au TX de la STM32 et son TX au RX de la STM32. Il a aussi fallu faire attention à ne pas mettre trop de printf dans le code du programme : en effet, ceux-ci ralentissent le programme et on peut ainsi ne récupérer aucune donnée par la connexion série même si le programme est correct. Enfin, une dernière difficulté a été de trouver les bons noms des PINs à utiliser dans le programme; il est ainsi nécessaire de n'utiliser que les noms des PINs en vert ou en bleu du Pinout.

Pour récupérer les valeurs des particules fines de type 1.0, 2.5 et 10, il faut commencer par détecter si on a bien le début de la trame en liaison série, c'est-à-dire 0x42 suivi de 0x4D. On pourra ensuite trouver les valeurs dans les données reçues.

Dans les bâtiments de l'école, j'obtiens les valeurs de pollution suivantes, qui sont assez faibles.

PM1.0: 2 ug/m3
PM2.5: 5 ug/m3
PM10: 6 ug/m3
PM1.0: 3 ug/m3 PM2.5: 5 ug/m3 PM10: 5 ug/m3
PM1.0: 3 ug/m3 PM2.5: 5 ug/m3 PM10: 5 ug/m3
PM1.0: 3 ug/m3 PM2.5: 5 ug/m3 PM10: 5 ug/m3
PM1.0: 4 ug/m3 PM2.5: 6 ug/m3 PM10: 6 ug/m3

Le capteur contient un ventilateur qui aspire les particules et une sortie d'air, il ne faut donc pas les obstruer pour obtenir de bonnes valeurs.

Programmation du module GPS

Je ne peux pas programmer le véritable module GPS pour le moment car celui-ci est trop petit. C'est pour cela que j'ai effectué la programmation du module en utilisant un autre module à taille plus grande en attendant de pouvoir réaliser la carte. Le module obtenu est un DS-GPM. Celui-ci fonctionne sous une tension allant de 7 à 16V, je vais donc le connecter à une pile 9V.

Les GPS sont en général connectés par des liaisons classiques : séries avec RX et TX, SPI ou I2C. Ce module fonctionne en I2C, on va donc brancher 4 PINs : VCC(7->16V), GND, SDA et SDL.

Connexion du module GPS DS-GPM à la carte STM32

De même, le site du constructeur permet le téléchargement d'un programme d'exemple Arduino et de la Datasheet. Les valeurs du GPS sont facilement récupérables : les données sont contenues dans 112 registres. Il suffit de récupérer ceux souhaités. L'interface I2C sur MBed permet également de récupérer d'un seul coup la totalité des registres.

Ce capteur ne fonctionne pas en intérieur. J'ai réussi à lire les registres mais étant en intérieur, je n'ai pas pu obtenir de valeurs exploitables.

Création du schematic de la carte sous Altium Designer

J'ai reçu la liste du matériel disponible entre temps, ainsi qu'une librairie pour Altium contenant certains composants déjà réalisés. J'ai ainsi commencé par faire ceux qui manquaient puis par réaliser un début de schéma.

Pour le composant Sensor Tile (ou ultra low power DSP STM32L476JGY6), qui contient à la fois un micro-contrôleur STM32, un module bluetooth et des capteurs divers, j'ai dû consulter le peu de datasheet existant puis me référer à la datasheet du composant STM32L476.

Liste des composants :

  • HDC1080DMBR (capteur d'humidité et de température)
  • TMP302DDRLR (switch de température)
  • DPS310XTSA1 (baromètre et capteur de température)
  • PCF8563T (horloge et calendrier temps réel)
  • 538-47346-1001 (connecteur micro-USB)
  • AMCA31-2R450G-S1F-T (antenne Bluetooth/WiFi)
  • 146235-0001 (antenne GPS)
  • AP3417CKTR-G1 (régulateur de tension)
  • SN74LV1T34DCKR (buffer et modificateur de tension)
  • BSS84-7-F (switch MOSFET)
  • MAX4378TAUD+ (mesure de consommation)
  • STLCS02V1 - SensorTile (microcontrôleur STM32 + module Bluetooth + micro + baromètre + capteur de température + accéléromètre + magnétomètre + gyroscope)
Pins et fonctions du composant Sensor Tile
Connexion par Bluetooth entre STM32 + module bluetooth et téléphone Android

J'ai également poursuivi le travail sur la connexion par Bluetooth. Maintenant que la carte est capable de transmettre des données, j'ai créé une application Android capable de communiquer en BLE (Bluetooth Low Energy). J'ai d'abord commencé par télécharger des applications existantes sur le Play Store pour essayer de détecter la combinaison carte + module bluetooth.

J'ai notamment découvert par expérimentations que le nom de l'application ne doit pas dépasser 14 caractères ni ne contenir d'espaces, ou que les dernières versions de librairies mbed ne permettaient pas au module BLE de fonctionner correctement. Il est donc important de ne pas mettre à jour les librairies lors de l'importation du projet, et de ne pas oublier de connecter le jumper (voir semaine 1).

Une fois l'appareil Pollution détecté dans la liste des appareils connectés en Bluetooth, il est possible de le sélectionner et d'afficher la liste des services qu'il publie. En effet, chaque appareil bluetooth publie des services. Un service regroupe des caractéristiques qui vont bien ensemble. Ces caractéristiques peuvent ensuite être de type lecture, écriture ou les deux. Pour les caractéristiques que l'on peut lire, on peut ainsi obtenir la ou les valeurs associées. Par exemple, pour un service Service Pollution, on pourrait avoir une caractéristique Niveau de pollution ainsi qu'une autre Niveau d'humidité.

Après de nombreux essais, j'ai enfin réussi à détecter le service de pollution envoyé par la carte. C'est grâce à l'ajout de l'adresse 0xFFFF dans la liste de diffusion des services, ce qui semble avoir mis à jour le cache. La carte peut en effet annoncer les services qu'elle contient. Cela n'est pas obligatoire pour que le bluetooth fonctionne mais permet de donner une bonne indication du fonctionnement de l'application. L'adresse 0xFFFF est réservée au développement.

J'ai enfin créé ma propre application Android par la suite pour récupérer correctement la valeur de la pollution. Celle-ci est par défaut considérée comme de l'hexadécimal, or nous souhaitons obtenir un entier. J'ai aussi ajouté le service de niveau de batterie (utile pour un objet connecté qui fonctionnera possiblement sur piles ou autres et dont on voudra vérifier la durée de vie) et le service d'information sur l'appareil (ici, la carte électronique).

Semaine 3 (du 22/01/2018 au 28/01/2018)

Suite du travail sur le schematic de la carte

Cette semaine, j'ai commencé par poursuivre le schematic de la carte électronique sous Altium. J'ai pour cela téléchargé et consulté les différentes datasheets des composants. Cela m'a permis d'établir une liste de points/questions à aborder avec mes tuteurs, parmi lesquels l'obtention de références manquantes de composants, comment effectuer la connexion/déconnexions entre les différents éléments du schéma etc. J'ai aussi créé la partie PCB de la carte sous Altium pour commencer à entrer la configuration des règles à respecter et d'ores et déjà créer des plans de masse.

Suite du travail sur l'application Android

J'ai également poursuivi le travail sur l'application Android pour la communication en Bluetooth. En effet, l'application a été créée à partir d'un projet d'exemple généré automatiquement, j'ai donc d'abord nettoyé un peu le code qui ne servirait pas ou plus.

La carte comportera plusieurs capteurs, il est donc important de pouvoir afficher et récupérer plusieurs caractéristiques du service de pollution. J'ai donc dans ce but ajouté une liste des éléments sur la page d'accueil et affiché les deux caractéristiques principales pour le moment, le niveau de particules et la batterie restante. Le bluetooth Low-Energy sous Android est fait de telle manière que seule une action de lecture ou d'écriture est possible à la fois. Cela signifie surtout que pour pouvoir obtenir les valeurs des deux caractéristiques citées précédemment, il faut mettre en place une file d'attente (ou queue en anglais) pour que les actions soient effectuées les unes à la suite des autres. Il existe différents types de files d'attentes sous Java ou Android, j'ai pour ma part employé une liste de type FIFO (First In First Out). La LinkedList de Java convient parfaitement dans ce cas-ci.

Un autre point important concerne l'affichage de la liste. En effet, une fois les bonnes valeurs des capteurs récupérées par Bluetooth, on souhaite pouvoir les mettre à jour dans la liste. Il a donc été nécessaire de rafraîchir l'affichage de la liste pour obtenir ces changements.

Services de pollution et de batterie sur l'application Android

J'ai aussi travaillé sur les notifications. J'ai d'abord commencé par modifier le programme du module bluetooth, pour lui faire envoyer des mises à jour des valeurs des capteurs. La LED clignotante permet de vérifier que les mises à jours sont bien envoyées. Il est possible, sous Android, de souscrire à des notifications pour être tenu au courant des changements de valeurs des capteurs. Il est pour cela nécessaire d'indiquer que l'on souhaite recevoir les notifications et il faut donner une valeur à un descripteur particulier (les descripteurs permettent d'ajouter des configurations sur les caractéristiques). Je n'ai malheureusement pas encore réussi à observer de réception des notifications.

Semaine 4 (du 29/01/2018 au 04/02/2018)

Réunion avec mes tuteurs

La semaine a commencé avec une réunion avec M. Boé, sur le sujet de la carte électronique. J'ai ainsi pu obtenir les références manquantes des modules GPS et LORA.

J'avais également quelques questions à lui poser et cette réunion m'a permis d'obtenir les informations suivantes :

  • Les différents éléments doivent pouvoir être connectés ou déconnectés facilement. Pour ceci, on utilisera des jumpers et des headers. Les headers seront mis sur la carte pour simuler une ligne coupée et les jumpers permettront de connecter/déconnecter cette ligne.
  • Le switch de température donné dans la liste de composants ne sera pas utilisé.
  • On pourra accéder aux sorties de mesures de courant grâce à des headers.
  • Le module SensorTile sera alimenté en 3.3V. Il est normalement alimenté en 1.8V, mais il (et tous ses capteurs) est capable de supporter du 3.3V, alors qu'au contraire certains capteurs ne fonctionneront pas avec une tension inférieure à 3V. L'alimentation se fera sur la broche VDD sur SensorTile.
  • La carte pourra soit être alimentée en 5V, tension qui grâce au régulateur de tension sera transformée en 3.3V, soit directement en 3.3V. Les tensions 5V et 3.3V peuvent être obtenues par des headers ou pour le 5V par le port micro-USB.
  • Le module SensorTile dispose d'un pin pour la fonctionnalité USB On-The-Go, qui ne sera pas utilisée pour le moment. Un header permettra quand même une possible future utilisation de celui-ci. Ce port doit être alimenté en 3.3V.
  • On n'utilisera pas le baromètre de la liste de matériel, car le SensorTile dispose déjà d'un capteur similaire.

Liste des composants supplémentaires :

  • M10578-A2 (module GPS)
  • RN2483A-I/RM103 (module LORA)
Réalisation du schematic et du PCB

J'ai ensuite continué et terminé la réalisation du schematic et du PCB associé, et ai envoyé ceux-ci pour validation auprès de M. Boé. Ce fut la première version de la carte (visible ci-dessous).

La révision de M.Boé m'a permis de remarquer quelques problèmes et changements a effectuer (notamment la taille des composants SMD comme les résistances et les capacités, ou le fait que le capteur de particules fonctionne sur du 5V). C'est la troisième version qui sera la finale, après quelques modifications supplémentaires au niveau des vias de masse et des antennes.

L'étape suivante consiste à imprimer la carte sur papier en taille réelle et poser les composants dessus pour vérifier les tailles des empreintes. Je n'ai malheureusement pas les composants, cette vérification devra donc attendre la semaine suivante.

Suite de la programmation de la carte STM32

La carte embarque de nombreux capteurs, il faudra donc pouvoir relever et transmettre ces valeurs au téléphone Android. J'ai donc commencé par créer de nombreux programmes, un pour chaque capteur, dans le but de relever leurs valeurs. Ainsi, certains d'entre eux communiquent avec le protocole I2C, comme c'est le cas du capteur d'humidité, de pression barométrique ou du RTC. Pour lire ces valeurs, il faut connaître l'adresse du capteur et faire une écriture sur le registre que l'on souhaite lire. On peut ensuite y faire une lecture et récupérer son contenu. Certains capteurs nécessitaient aussi une configuration préalable qui consistait à écrire certaines valeurs dans les registres de configuration.

D'autres capteurs (notamment le GPS, le module LORA et le capteur de particules) fonctionnent en écriture/lecture sur le port série. Ceux-ci se lisent plutôt facilement et on peut distinguer à qui appartiennent les valeurs en lecture par le début de chaque trame. Le capteur de particules par exemple écrira d'abord 0x42, alors que le GPS écrira '$'.

Le GPS, d'ailleurs, suit un protocole spécifique pour la forme de ses données; c'est le protocole NMEA 0183. Ce protocole permet de recevoir des trames de différents formes, une des plus connues étant la forme GGA. Je ne sais pas encore quels types de trames envoie ce module GPS car je ne peux pas tester mes programmes, n'ayant pas encore gravé la carte; mais je suis partie du principe pour réaliser le code que la trame était de forme GGA. Un exemple de trame se trouve ci-dessous :

$GPGGA,064036.289,4836.5375,N,00740.9373,E,1,04,3.2,200.2,M,,,,0000*0E

On y retrouve ainsi le type de la trame, l'heure d'envoi de celle-ci, la latitude, la longitude, l'altitude, le nombre de satellites utilisés pour calculer les coordonnées et d'autres informations diverses et variées.


Il est ensuite important de pouvoir transmettre ces données. J'ai donc créé de nouveaux services et caractéristiques pour l'envoi via le Bluetooth. J'ai essayé au maximum de reprendre les services qui existaient déjà pour cela.

Il existe ainsi un service Environmental Sensing Service qui peut embarquer de nombreuses caractéristiques, notamment la température, l'humidité ou la pression atmosphérique. J'ai malheureusement découvert au cours de mes expérimentations que je n'arrivais pas à transmettre plus de deux caractéristiques par services. La troisième se transformait automatiquement en valeur supplémentaire de la seconde caractéristique déclarée. Je me suis donc arrangée en laissant l'humidité et la pression au service ci-dessus et j'ai transféré la température dans le Pollution Service créé précédemment.

Un autre service est le Location and Navigation Service qui lui contient les données relatives à la position telles que celles transmises par le GPS. Pour cette caractéristique, et afin de respecter la limite de deux caractéristiques par service, j'ai dû créer et envoyer des données sous forme de structure de données. En effet, cette structure (qui correspond au contenu de la caractéristique déclarée dans la documentation officielle) commence par des bits indiquant les valeurs à suivre, puis on y retrouvera à la suite la latitude, la longitude et l'altitude. La documentation indiquait cependant qu'une transformation devait être appliquée aux données issues des capteurs, afin de les transmettre sous forme d'entiers alors qu'elles étaient sous forme décimale. Dans ce cas-là, il fallait faire valeur x 10^7 pour le GPS d'après la documentation, mais j'ai été obligée de me limiter à 10^5, les valeurs n'ayant plus de sens au-delà.

Enfin, le dernier service utilisé est le Current Time Service qui permet de stocker la date et l'heure obtenus à partir du RTC. J'ai pu débugger ces services et caractéristiques en utilisant des applications Android de base pour le Bluetooth Low Energy qui connaissent tous ces services standards (ici, j'ai utilisé l'application nRF Connect).

Débuggage des services et caractéristiques par une application Android
Suite de la programmation sur Android

Suite à l'ajout de services sur la carte STM32, j'ai également dû modifier le code Java pour Android afin de recevoir et d'afficher ces valeurs. J'ai ainsi ajouté de quoi recevoir ces données en déclarant les nouveaux services mais j'ai aussi dû appliquer les mêmes transformations que sur la STM32 mais à l'inverse. Ainsi, si avant j'appliquais valeur x 10^5, j'applique maintenant valeur reçue / 10^5.

L'envoi par Bluetooth transforme également les trames des structures de données en inversant les bytes. Ainsi, par exemple si on décide d'envoyer la trame 200 3000 par la STM32, les bytes transmis seront 00 C8 0B B8. Or ceux-ci seront reçus dans l'ordre suivant sur Android : C8 00 B8 0B. Il faut donc commencer par découper la trame en les différentes valeurs qui nous intéressent puis inverser le tableau obtenu pour chaque valeur.

J'ai rencontré quelques difficultés lors de l'ajout de services supplémentaires lorsqu'ils étaient composés d'une trame de données. La réception n'est pas plus dure, mais la trame contient plusieurs valeurs, il faut donc en général mettre plusieurs affichages à jour. J'avais tout d'abord essayé de publier (par la méthode sendBroadcast) plusieurs fois dans la même fonction broadcastUpdate. Il s'est cependant vite avéré que c'était une mauvaise idée : si on a par exemple deux ordres de lecture dans la file d'attente A puis B; et que A effectue deux sendBroadcast, alors on aura :

A et B sont dans la file d'attente
On lit la 1ère valeur, A.
A effectue deux sendBroadcast, A1 et A2 et est supprimé de la file d'attente.
A1 indique que des données sont disponibles et qu'il faut les afficher. La file d'attente n'est pas vide, on lit B, qui effectue un sendBroadcast B1 et est supprimé de la file d'attente.
en parallèle || Pendant ce temps-là, A2 indique que des données sont disponibles et qu'il faut les afficher. La file d'attente est vide.
             || B1 n'est pas lisible car A2 est en train d'être lu

J'ai réussi à résoudre le problème en créant un nouveau type, BLENumberedCharacteristic qui est une simple combinaison d'une BluetoothGattCharacteristic et d'un entier représentant le numéro de la valeur de la caractéristique à lire/afficher. Cette classe remplace la précédente dans la file d'attente et on met l'entier de la valeur de caractéristiques dans une variable à chaque utilisation de la fonction updateNextCharacteristic. J'ai été obligé de programmer cela de cette manière car je ne pouvais pas ajouter ce numéro en paramètre à la fonction onCharacteristicRead, qui est une fonction de Callback overridée et donc prédéfinie. Ainsi, pour une position reçue par le GPS, lors de la mise en file d'attente, on mettra en fait trois instances de la même caractéristique en file d'attente, chacune avec un numéro différent; 1 pour la latitude, 2 pour la longitude et 3 pour l'altitude.

Les différentes valeurs reçues sur l'application Android

Semaine 5 (du 05/02/2018 au 11/02/2018)

Création de l'API REST et base de données

Dans ce projet, il faut pouvoir transmettre les données de l'application Android à une base de données pour pouvoir ensuite consulter les niveaux de pollution sur une carte. Pour cela, on créé une API REST, c'est-à-dire un protocole de communication entre les deux. Une API ("Application Programming Interface") est une interface de programmation applicative composée de classes, méthodes ou fonctions servant de façade pour qu'un logiciel propose des services à d'autres logiciels. REST signifie "Representational State Transfer".

Cela consiste ici en la création de méthodes HTTP, telles qu'un PUT pour la création d'une nouvelle donnée et un GET pour pouvoir récupérer toutes les données à afficher. J'ai créé cette application dans le logiciel Eclipse avec le langage Java, la librairie Spring et la base de données MongoDB. Des tests ont également été créés. MongoDB est fait en NoSQL, ce qui signifie que les données sont stockées sous forme de documents JSON, facilitant leur lecture, et qu'elle est très rapide à mettre en place. On souhaite dans ce cas-ci enregistrer la latitude, la longitude, l'altitude, le degré de pollution et la date actuelle.

Je n'ai pas fait la distinction des données à récupérer en fonction de la date car ce n'était pas ce qu'il y avait de plus important à avancer. Le GET permet de récupérer pour le moment toutes les positions de la base. Les API sont les suivantes :

{
   "latitude": 1.2,
   "longitude": 1.3,
   "altitude": 1.4,
   "pollution": 4.0
 }

L’API n’est déployée qu’en local pour le moment, on ne pourra donc pas encore afficher les valeurs de la base de données dans l’application Android. En attendant, des données d’exemple ont été créées et chargées dans l’application Android lorsque l’adresse de l’API contient le mot localhost. Pour démarrer le tout, il faut d’abord démarrer la base de données MongoDB (après l’avoir installée) avec les commandes (on remplacera bien sûr les chemins d’installations s’ils diffèrent) :

$ "C:\Program Files\MongoDB\Server\3.6\bin\mongod.exe"
$ "C:\Program Files\MongoDB\Server\3.6\bin\mongo.exe"

Ensuite, on démarre l’application sur Eclipse ou par ligne de commande si on a installé au préalable le plugin spring-boot :

$ mvn spring-boot:run 
   -Drun.jvmArguments=" -Xdebug 
   -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
Création de la carte électronique

La carte électronique a été réalisée par gravure au service EEI de Polytech'Lille. Avant cela, il a été nécessaire de vérifier que les différents composants correspondaient bien à l'empreinte qui allait être gravée sur des copies papier du circuit, imprimées la semaine dernière.

Une fois la gravure réalisée, Thierry (qui gère le service EEI) l'a terminée au cutter dans les endroits mal finis. En effet, les antennes nécessitant des pistes d'impédance 50Ω, il a fallu leur donner une certaine largeur qui dépend également du matériau utilisé dans la carte et de son épaisseur. Les calculs ont été réalisés avec une épaisseur de 0.8mm (l'épaisseur habituelle étant 1.6mm) pour ne pas avoir une piste trop large. Le matériau était également plus dur que d'habitude (car c'était les seules plaques de 0.8mm qui restaient), la machine n'a pas réussi à retirer certains morceaux de cuivre dans les coins.

Ce matériau étant enduit de résine (il était d'habitude utilisé pour la gravure chimique), il a aussi fallu le passer dans un bac pour la retirer.

J'ai ensuite pu commencer à placer mes composants sur la carte. Il faut souder ceux-ci à l'étain (ou les braser, qui est le terme exact). Pour ce faire, j'ai eu l'occasion d'utiliser un four, ce qui est particulièrement pratique lorsqu'on a de très petits composants. Ainsi, on place de la pâte à braser sur la carte grâce à une seringue. La pâte est grise et dure et fondra lorsqu'on la passera au four pour devenir de l'étain. L'étain est attiré par le cuivre, donc les composants vont se replacer d'eux-mêmes dans le four et on ne trouvera pas de pâte là où il n'y a pas de cuivre (sauf si on a mis trop de pâte). Une astuce pour que la pâte soit plus facile à mettre est de chauffer la seringue dans sa main régulièrement pour rendre la pâte plus liquide.

J'ai ainsi déposé le maximum de composants sur la carte, mais pas ceux que je n'avais pas (comme c'était le cas pour certaines valeurs de résistances) ni le module LORA et le Sensor Tile qui n'auraient pas supporté le passage à de très hautes températures. Après la cuisson, le cuivre a changé de couleur car il s'est oxydé, souder le reste des composants sera impossible sur un tel cuivre. Pour remédier à cela, il suffit de bien gommer la carte puis de mettre du flux pour aider les soudures. On peut aussi étamer les empreintes avant la soudure pour faciliter celle-ci.

La carte étant double-face, elle contient beaucoup de vias, des trous qui permettent de relier les deux côtés. Les trous sont habituellement métallisés mais les cartes ici ne le sont pas, les vias ont donc dû être faits à la main. J'ai donc commencé par couper et dénuder des morceaux de fils pour ne garder que la partie intérieure. On passe ensuite un fil dans chaque via, et pour éviter que la carte ne bouge on les plante dans la mousse (sur laquelle la carte est posée). On les soude tous d'un côté (après ajout de flux au préalable) puis on les coupe à la même hauteur mais tout en laissant une certaine longueur pour pouvoir les replanter de l'autre côté dans la mousse. Enfin, on soude le second côté et on les coupe à ras.

Thierry m'a ensuite montré comment souder les composants de surface plus complexes (car les pins sont nombreux, très proches et très petits), tels que le module LORA et le Sensor Tile. J'ai fini par souder aussi des headers et les autres composants traversants. Les headers servent pour la plupart à faire les connexions entre modules de la carte, je leur ai donc rajouté des jumpers, des petits chapeaux qui englobent deux pins et permettent de les relier ensembles.

Carte Google Map sur Android

Un des objectifs de cette application était aussi de pouvoir afficher une carte de la pollution environnante. Il est possible d'ajouter de telles cartes sur Android, en utilisant l'API proposée par Google.

J'ai commencé par tenter d'afficher une nouvelle activité (qui contiendra la carte Google Maps) lorsque l'on clique sur le taux de pollution relevé. Cela n'a pas posé de problème, mais c'est lorsque l'on souhaite revenir à la page précédente contenant la liste des relevés des capteurs que survient un problème. Il était en effet impossible de se reconnecter au service Bluetooth. Cela était dû au fait que le nom de l'appareil (ici, la carte émettant les données Bluetooth) était perdu, celui-ci étant obtenu lors du scan des appareils. Comme on ne passe plus par l'activité de scan lorsqu'on cherche à revenir à l'activité précédente, on perd ces données. La solution a été de les transmettre lors du scan à une classe héritant de l'Application, ce qui en fait des variables accessibles partout et à tout moment. J'ai également dû déplacer les initialisations contenues dans la fonction onCreate dans une nouvelle fonction (que j'ai appelée init) et appeler celle-ci aussi dans la fonction onResume, car c'est celle-ci qui est appelée lors d'un retour en arrière. Si on ne fait pas cela, rien ne sera affiché sur l'application.

Pour créer une carte Google Map, il a d'abord fallu télécharger les services Google Play puis ajouter l'utilisation des cartes dans le fichier de configuration Gradle. Il a aussi été nécessaire pour moi de procéder à mon enregistrement sur Google pour obtenir une clé d'API, que j'ai ensuite reporté dans l'application. Tout cela est expliqué lorsqu'on créé une nouvelle activité de base Google Maps.

On peut réaliser beaucoup de choses sur une telle carte. J'ai commencé par récupérer la position actuelle du téléphone, ajouter un marqueur à cet endroit puis y centrer la caméra. On peut aussi jouer sur les réglages visuels tels que le zoom (que j'ai mis à 20, 20 correspondant à une vue proche, 5 par exemple est plutôt une vue d'ensemble de la région) ou l'angle de vue (tilt en anglais) ce qui permet de donner un léger effet 3D à la carte. Il existe différents types de cartes, qui montrent différents types d'informations. J'aurais aimé utiliser une carte de type Terrain, où les routes sont moins mises en avant, mais il était alors impossible de visualiser les formes des bâtiments, je suis donc finalement restée sur une carte de type Normal.

J'ai ajouté une carte superposée de type Heatmap. Ce genre de carte permet d'indiquer une forte valeur là où les mesures sont nombreuses et proches, mais il est possible avec l'API Google d'ajouter la prise en compte du poids (par exemple de la valeur de pollution) également. Le seul problème est que malgré la prise en compte des valeurs dans l'affichage, la densité des mesures (nombre et proximité) est toujours prise en compte. Je n'ai malheureusement pas trouvé d'autres alternatives à cela. De plus, lorsqu'on a peu de points, ceux-ci restent séparés et donc peu visibles.

Semaine 6 (du 12/02/2018 au 18/02/2018)

Tests sur la carte électronique

Cette semaine j'ai commencé par tester si la carte fonctionnait correctement. J'ai pour cela utilisé un multimètre pour détecter les possibles courts-circuits, ainsi que vérifier que les masses sont bien reliées et les alimentations aussi. Ensuite, j'ai branché la carte par le port micro-usb en ne connectant aucun des modules (pour isoler cette partie du circuit). Il se trouve que l'empreinte du port usb était inversée, c'est-à-dire que la piste 5V était reliée au pin Ground et inversement et le multimètre mesurait -5V. Pour corriger cela, avec l'aide précieuse de Thierry, il a été nécessaire de couper des pistes (grâce à un cutter) et en relier d'autres par des fils. Cela ne marchant toujours pas, il a fallu dessouder le port pour observer qu'en dessous, il y avait un pont thermique (une connexion entre plusieurs éléments qui étaient, avant de s'apercevoir du souci avec l'empreinte, censés être tous reliés à la masse). Une fois cela corrigé, le composant a été ressoudé.

Un autre souci qui a été corrigé correspond à l'alimentation 5V : en effet, le module Sensor Tile a plusieurs pins d'alimentation, mais il va de soi qu'on ne peut pas tous les alimenter en même temps, sinon il y aura conflit. Le 3.3V est celui qui alimente le Sensor Tile et le reste de la carte, mais on avait aussi besoin du 5V pour éventuellement changer et alimenter dans tous les cas le capteur de pollution. La carte dans son état actuel ne permettait malheureusement pas d'alimenter le capteur de pollution en 5V sans alimenter le Sensor Tile en même temps, et la connexion au Sensor Tile se trouvait entre le 5V de l'alimentation et la connexion au capteur de pollution. J'ai donc dû couper la piste menant au Sensor Tile et connecter les pistes avant et après ensemble.

Programmation de la carte électronique

La programmation se fera par SWD, c'est à dire par cinq fils : VDD, CLK, GND, IO et RST. Ces fils relieront la carte électronique et la carte Nucléo-F401RE utilisée précédemment. En effet, celle-ci possède un linker qui permet de la programmer depuis un câble usb branché à l'ordinateur; mais ce linker peut aussi être utilisé pour programmer d'autres cartes ou microcontrôleurs de la même gamme. Il faut pour cela retirer les jumpers connectés en CN2. C'est aussi une bonne idée de déconnecter la carte qui ne sera pas programmée (le reste du Nucléo-F401RE). Enfin, brancher les 5 fils tels quels ne fonctionne que si l'on alimente en plus la carte à côté, mais on peut ne pas brancher le VDD sur le SWD du linker mais plutôt à un pin sortant 3.3V, ce qui permet d'alimenter directement la carte électronique sans passer par un câble usb supplémentaire.

J'ai tenté de programmer la carte en faisant clignoter la LED de la carte mais n'ai pas réussi. Le problème venait tout d'abord de l'IDE Mbed en ligne, qui ne reconnaît que les cartes entières et pas les microcontrôleurs eux-mêmes. Ma carte était donc reconnue, mais certains pins étaient inaccessibles (notamment tous les pins PGx). J'ai pour cela téléchargé plusieurs IDEs pour tenter de la faire fonctionner : System Workbench qui est un IDE gratuit mais qui refusait de se lancer il y a moins d'un mois; Keil uVison 5 mais celui-ci est payant et la version d'essai ne fonctionnait pas avec la version de GCC; IAR Embedded Workbench, payant lui aussi mais vraiment limité au niveau de la taille de programmes; et enfin de nouveau System Workbench, qui fonctionne sur mon ordinateur avec la dernière mise à jour. L'IDE TrueStudio est aussi gratuit et fonctionne également. Ces deux derniers sont basés sur Eclipse et sont donc faciles à utiliser.

Avec ces IDEs, j'ai téléchargé l'outil STM32CubeMX, qui permet de créer un projet pour n'importe lequel des IDEs cités précédemment avec une configuration de base déjà faite. Il est très simple d'utilisation : on choisit le modèle du microcontrôleur, puis les entrées/sorties que l'on souhaite utiliser. On peut les renommer puis on génère le projet. J'ai réussi avec ces outils à faire clignoter une LED sur la carte Nucléo-F401RE mais pas sur ma carte.

Semaine 7 (du 19/02/2018 au 25/02/2018)

Programmation de la carte électronique

Le problème avec ma carte venait du fait que certains pins (comme PC0) sont alimentés directement depuis VDD, mais d'autres sont en fait alimentés par VDD_USB, lequel n'était pas branché à quoi que ce soit (mais un header permettait d'y accéder). J'ai pour cela soudé un fil entre l'alimentation en 3.3V et le port VDD_USB et ma LED clignotait.

J'ai également réussi à imprimer du texte dans la console; il faut pour cela activer le semi-hosting. Cela permet de lire les printfs dans la console de l'IDE (mais pas dans la console de Tera-Term par exemple). La démarche à suivre est indiquée ici et consiste à rajouter des arguments dans quelques configurations du projet et de l'IDE, ainsi qu'à réaliser une initialisation au moyen de l'appel d'une fonction déjà existante.

Un début de programmation de lecture du capteur de particules a été réalisé, mais n’a pas donné de résultats concluants pour le moment. Je pense que les pins RX et TX ont été inversés; il faut alors connecter la carte d'adaptation du capteur par des câbles en faisant aller RX à TX et inversement. La carte d'adaptation est bien alimentée et on peut sentir que le ventilateur du capteur tourne, mais aucun caractère n'est lu.

Mise à jour du schéma et du pcb Altium

J'ai réalisé une version corrigée du schéma et du pcb sous Altium Designer afin de corriger les erreurs et problèmes détectés soit lors de la réalisation de carte (soudure, tests) ou soit lors de sa programmation. J’ai ainsi corrigé dans cette version : l’empreinte du port micro-USB dont les pistes +5V et GND étaient inversées, les lignes de communication série dont il faut que les RX aillent vers TX et inversement (ce n’était pas le cas). J’ai également retiré la connexion allant du 5V à V_in car on ne souhaite pas alimenter la carte par V_in et V_dd en même temps, sinon il y aurait conflit. Le 5V par contre reste connecté au capteur de pollution. V_ddusb est maintenant alimenté en 3.3V.

Lien entre l'application Android et l'API REST

On souhaite récupérer les positions des relevés de pollution de la base de données. Pour cela, on effectue un appel à l'API REST de type GET. Pour effectuer des appels à l’API REST, il est nécessaire de créer une tâche asynchrone sur Android et de les faire dans celle-ci. En effet, les appels à des adresses http doivent être faits en arrière-plan pour ne pas bloquer des fonctions importantes de l’application comme l’affichage. Dans le cas où l’API n’est déployée qu’en local, c’est-à-dire sur l’ordinateur alors que l’application est lancée sur un téléphone, il est impossible d’y accéder (tant qu’un serveur n’a pas été déployé). J’ai donc mis en place des données factices pour quand même pouvoir tester la carte de chaleur sans le serveur. Le code de récupération des données par appel REST a été réalisé et mis dans la tâche asynchrone. Lorsque l'utilisateur se déplace, la tâche est relancée si elle était terminée.

Bibliographie

Annexes