Balise de suivi de polluant

De Wiki de Projets IMA
Révision datée du 12 juin 2015 à 08:31 par Rex (discussion | contributions)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)


Vidéo HD


Cahier des charges

Présentation générale du projet

Contexte

Le suivi des polluants dans les milieux naturels (notamment eaux de surface) est nécessaire afin d'informer les populations et pour aider à la gestion des eaux.

Objectif du projet

Ce projet propose le développement d'une balise autonome permettant le suivi des polluants dans les milieux naturels, en l’occurrence l'eau de surface.

Description du projet

Le suivi de la qualité des eaux de surface (notamment leur teneur en métaux) se fait actuellement soit par prélèvement et analyse en laboratoire (spectroscopie ICP, méthode sensible mais couteuse), soit par prélèvement et analyse par voltammétrie. Cette dernière technique est moins sensible mais nettement plus abordable et simple à mettre en œuvre. Actuellement, l'électrode utilisée est une électrode à base de mercure, ce qui impose des contraintes fortes.

A l'IRCICA, en collaboration avec le LASIR, nous développons des électrodes à base d'or permettant le suivi in situ des polluants.

Ce projet propose de développer une station mobile à faible coût permettant de mettre en œuvre ces électrodes. La balise de suivi sera constituée d'un galvanostat (carte déjà disponible sur Internet) et d'une carte électronique à développer pour gérer le galvanostat, enregistrer les données et les transmettre. Une interface web sera développée afin d’accéder aux données.

En cas de succès, la balise sera déployée dans le lac du Héron pour le suivi des polluants.

Choix techniques : matériel et logiciel

Matériel choisi :

Module Arduino équipé de

  • Module RTC [Récupếré le 18/05/2015]
  • Shield GSM Arduino [fourni le 28/01/15][Récupếré le 18/05/2015]
  • Shield GPS Arduino [fourni le 11/02/15][Récupếré le 18/05/2015]
  • 2 Arduino UNO [fourni le 28/01/15 et le 11/03/15][Récupếré le 18/05/2015]
  • Arduino MEGA [fourni le 18/03/15][Récupếré le 18/05/2015]
  • Panneau solaire de 3W [fourni le 18/03/15][Récupếré le 18/05/2015]
  • Galvanostat type "Ardustat" crée par nous-mêmes : [fourni le 15/04/15]
  • Réception du MPPT le 01/04/2015[Récupếré le 18/05/2015]
    • Convertisseur Numérique Analogique : MAX5250
    • Potentiomètre : MCP4261
    • Relai : R561D.56 NTE
    • Résistances : Deux de 100\Omega et deux de 10k\Omega
    • une LED
    • 40 pins broches mâle/mâle (Digikey Parts : A26509-40-ND), découpé par la suite en 8-8-6-4
  • Circuit d'alimentation autonome : cellule photovoltaique [2 cellules fournies le 04/02/15].[Récupếré le 18/05/2015]
  • Circuit d'alimentation autonome : batterie [disponible dans le casier au 18/2/2015][Récupếré le 18/05/2015]

Pour le reste le développement de la partie logicielle s'oriente vers :

  • Module de supervision permettant de déclencher les mesures, stocker les données, transmettre les données[Récupếré le 18/05/2015]
    • Il faudrait, dans les requêtes émises, un bit affirmant la bonne réception des données envoyées, auquel cas on peut supprimer les données sur l'Arduino
  • une interface de consultation des données à distance (DB SQL + Web PHP), utilisation de PostgreSQL 9.4
  • Le code devrait principalement être réalisé sous VIM en C.
  • On pourra, une fois arrivé là, étudier la transmission sans fil via balises GSM. La table crée dans la base de données contient déjà un élément à cet effet.

Etapes du projet

Etape 1

☐ Mise en oeuvre des schémas de fonctionnements, indiquant les différents modules, des dessins valent plus que des mots
☑ Récupération et/ou commande des composants utiles à la réalisation du projet
☑ Réflexion sur les différents fichiers de code à écrire
☑ Réflexion sur le système de base de données à implémenter
☑ Création d'une base de données test en local
☑ Création d'un site web de supervision sur weppes

Etape 2

☐ Création d'un compte utilisateur Polytech pour le projet Abandonné, superflu
☑ Création de la base de données sur ce compte et des différentes tables à insérer
☐ Montage électrique de la carte

Etape 3

☐ Récupération des données du galvanostat sur l'Arduino En attente du galvanostat
☑ Insertion des données dans la DB
☑ Création des pages web permettant la consultation des données
☐ (Optionnel) Création d'une interface terminal pour dump les données de l'Arduino sur un système Unix

Etape 4

☑ Etude de la méthode de transfert GSM des données enregistrées par l'Arduino
☑ Implémentation de ce transfert et tests d'insertion dans la DB sans fil
☐ Mise en forme du code et affichage sur le port série des informations front-end

Balise de suivi de polluants : développement détaillé

Le développement de la balise de suivi de polluants s'est très vite orienté vers l'utilisation d'une plateforme Arduino, sur laquelle nous nous sentions relativement à l'aise avec les TP et tutorats que nous avions déjà eu avec, par son côté open, et par sa grande modularité.

Le cahier des charges très vite détaillé, nous avons pu établir le schéma de conception suivant qui permet d'y voir un peu plus clair concernant l'implémentation à réaliser :

Schéma de conception initialle du projet



La base de données, dont le nom est tteneur, est stockée sur le serveur Cambraisis (cambraisis.escaut.net). Elle contient une table nommé data qui va nous servir à stocker les données de la balise, à savoir la date de la mesure, la position GPS, et bien entendu, la mesure. Au niveau des types, nous avons choisi DATETIME pour la date. En effet, cela permet d'avoir l'heure et le jour de la mesure à la seconde près. Pour la position GPS, deux colonnes DECIMAL(7,3) nous permettent de stocker la longitude et la latitude de la balise à l'instant de la mesure, avec une précision de 4 à 5 chiffres après la virgule. La mesure est quant à elle stockée en type DOUBLE ce qui nous autorise une très grande précision.

Représentation de la table de données



Nous avons ensuite récupéré et adapté un code C open source pour Arduino, nous permettant via notre Shield GSM d'effectuer une requête GET par protocole HTTP. Cette requête à l'allure suivante :

GET /savedb.php?meastime=meastime&lat=lat&lon=lon&measure=measure HTTP/1.0
Host:teneur.polytech-lille.net

Concrètement, ce code est implanté de la manière suivante en C :

// La requête sur "teneur.polytech-lille.net/savedb.php"
char server[] = "teneur.polytech-lille.net"; // URL de base
String meastime = "2015-02-25%2016:30:00"; //date de la mesure
String lat = "56.541"; //latitude
String lon = "7.5412"; //longitude
String measure = "12"; //mesure
String path = "http://teneur.polytech-lille.net/savedb.php?meastime=" + meastime +"&lat=" + lat + "&lon=" + lon + "&measure=" + measure; //chemin complet de la requête
int port = 80; // port, 80 pour HTTP

// Si on a reussi la connexion au serveur, on execute la requête : if (client.connect(server, port)) { Serial.println("connected"); // Make a HTTP request: client.print("GET "); client.print(path); client.println(" HTTP/1.0"); client.println(); } else { // Sinon échec de la connexion au serveur on affiche Serial.println("connection failed"); }

Ceci nous permet donc d'effectuer notre requête sur la page savedb.php... mais que fait celle-ci ? Voici son code :

<?php
 error_reporting(E_ALL);
 require_once('connexion.php'); //récupération des identifiants de connexion pour accéder à la DB
 $meastime=$_GET["meastime"];   //récupération de la date et heure via l'URL
 $lat=$_GET["lat"];             //récupération de la latitude via l'URL
 $long=$_GET["lon"];            //récupération de la longitude via l'URL
 $measure=$_GET["measure"];     //récupération de la mesure via l'URL
 $query="INSERT INTO `tteneur`.`data` ( //requête INSERT INTO pour insérer les valeurs dans la DB 
 `meastime` ,
 `lat` ,
 `long` ,
 `measure`
 )
 VALUES (
 '$meastime', '$lat', '$long', '$measure'
 );";
 echo 'Date de la mesure : ' . $meastime . "<br>"; //debug visuel de la page
 echo 'Latitude : '.$lat . "\n";
 echo 'Longitude : '.$long . "<br>";
 echo 'Mesure (A) : '.$measure . "<br>";
 echo "<br><br>" . 'Insertion dans la base données...' . "<br><br>";
 echo 'Requete : ' . $query . "<br><br>";
 $result = mysql_query($query) or die("Erreur SQL ! $query".mysql_error());
if (!$result) { die('Impossible d\'exécuter la requête :' . mysql_error()); } else{ echo 'Requete effectuée avec succès !'; }
?>


A mi-projet, nous sommes capables désormais de transmettre donc des variables vers notre interface web. Le shield GSM monté sur l'arduino a l'allure ci-contre.

L'Arduino et son shield GSM.

La communication se déroule en plusieurs étapes avant de pouvoir envoyer notre requête SQL : Il faut tout d'abord déverrouiller la carte SIM en entrant son code PIN via la méthode gsmAccess.begin. Une fois ceci fait, il faut accéder au réseau GPRS. On entre donc les identifiants opérateur (chez Orange, UID: orange MDP: orange APN: orange) dont une liste peut-être trouvée ici. En vérifiant la valeur de retour de la méthode gprs.attachGPRS, on confirme le plein accès au réseau. On peut alors se connecter au serveur : si client.connect(server, port) renvoie true, alors on peut faire la requête HTTP/GET.

En initialisant GSM gsmAccess à true, on affiche la totalité des commandes AT envoyées à la carte SIM ce qui nous permet de voir la progression (assez lente) du démarrage du client web. Un guide des commandes AT du shield GSM est disponible ici. Il faut en moyenne 2 minutes du démarrage de l'arduino jusqu'à ce que la requête soit effectuée.

L'Arduino avec cette fois un shield GPS.

Du côté du shield GPS, nous arrivons à récupérer les données de longitude, latitude, relativement précises puisque nous sommes localisés au centre du bâtiment B de l'école en étant en salle E306. Le GPS nous permet aussi de récupérer la date actuelle, ce qui, après mise en forme convenable, ne devrait pas poser de problème à insérer dans la base de données.

Les bases de données furent ensuite retravaillées pour permettre de gérer plusieurs arduino. Une table entière Arduino fut donc crée à cet effet avec les colonnes ID, BATT_STATE, GPS_STATE, TIME_CONF afin de configurer les différents éléments d'un arduino donné : l'intervalle de temps entre deux mesures, l'activation ou pas du GPS, ce qui nous permet de répondre à la problématique énergétique de notre projet.

Représentation de la table des Arduinos.

Suivi de l'avancement du Projet

Semaine 1 (26/01/2015)

Nous avons tout d'abord consulté les enseignants afin de récupérer les éléments physiques nécessaires à la réalisation de la balise, à savoir à ce jour l'Arduino UNO monté d'un shield GSM. En outre, la liste des composants utiles à la réalisation de la carte d'acquisition de mesures (galvanostat) a été dressée et nous sommes désormais en attente de leur réception pour pouvoir développer la partie mesure.

Côté logiciel, la base de donnée a été crée sous le nom db_balise sur le serveur weppes.studserv.deule.net.

Le site web a démarré son développement. Il est pour l'instant accessible via weppes.studserv.deule.net/~tteneur/. Les pages index.html, connexion.php, data.php, control.php, et database_params.php y ont été créees.

Pour l'instant, seule la page index.html est remplie.

Semaine 2 (02/02/2015)

Nous avons récupéré le code du Shield GSM qui est Open Source et nous avons commencé à le convertir en language C.
Absence de Timothée Teneur lors de la séance de projet du mercredi (enterrement d'un membre de la famille).

Semaine 3 (09/02/2015)

  • Migration vers MySQL depuis PostgreSQL.
  • Migration de la base de données (désormais sur Cambraisis) : La base de données tteneur contient une table data.
  • Changement d'adresse du site (URL en bas de cette page).
  • Finalisation de la partie affichage des mesures par web.
  • Changement du type de données pour les coordonnées GPS : On passe du type point à deux colonnes DECIMAL(7,3) contenant respectivement la latitude et la longitude.
  • Création d'une page php savedb.php qui récupère les variables passées en paramètre dans l'URL et les insère dans la base de données.
  • Rédaction du code C permettant d'envoyer via un AP GPRS une requête GET via protocole HTTP. Conjointement à la page php ci-dessus, cela permet d'insérer les données dans la base de données directement depuis l'Arduino.

Semaine 4 (16/02/2015)

  • La réalisation se fera entièrement avec l'IDE de l'Arduino et sera converti en C si il nous reste du temps.
  • Étude des caractéristiques du panneau solaire.
  • Réflexion sur les composants permettant de transmettre le courant du panneau solaire à la batterie.

Semaine 5 (23/02/2015)

  • Le code concernant le shield GSM est réalisé et fonctionne.
  • Le schéma électrique pour relier la batterie, le panneau photovoltaïque et l'arduino est le suivant :

Diapo2.png

Semaine 6 (09/03/2015)

L'ensemble de la communication est fonctionnel : la plateforme Ardunio + GSM fonctionne correctement et permet d'insérer dans la base de données les requêtes nécessaires. Il manque donc simplement à changer les valeurs des variables avec les données recueillies :

  • La valeur de concentration des polluants avec la sonde
  • La latitude avec le shield GPS
  • La longitude avec le shield GPS
  • la date et l'heure avec le shield GPS qui peut récupérer ces données au fuseau horaire GMT.

Le shield GPS a été testé et fonctionne : on arrive à récupérer les données géographiques et la date et heure. Il faut désormais mettre en forme tous ces modules ensemble. Le problème lorsque l'on met les deux shields sur un seul arduino est qu'un des deux ne fonctionne plus. Probablement parce qu'ils utilisent les mêmes PINs. Nous allons continuer à enquêter sur ce sujet. A priori dans le pire des cas, en rajoutant un Arduino, il ne resterait plus qu'à les faire communiquer entre-eux pour s'échanger les données. La batterie USB assure l'alimentation des deux appareils grâce à ses deux ports USB, mais dans ce cas il est possible que l'énergie fournie par les panneaux solaires soit insuffisante pour alimenter les deux arduinos, et même peut être un.

Maintenant que nous récupérons les données et que nous savons les envoyer, nous allons étudier la périodisation de la tâche d'envoi et la mise en veille de l'arduino.

Pour la partie énergétique, un panneau solaire a été commandé car le précédant ne correspondait pas et un PCB va être réalisé.

Semaine 7 (16/03/2015)

Beaucoup de travail a été effectué sur les shields. Chaque module indépendant fonctionnait parfaitement sur un Arduino mais pas sur deux : en fait, le shield GSM et le shield GPS utilisait tous les deux le même port série sur l'arduino pour communiquer. Problème : il n'y a qu'un port série sur un Arduino Uno. Solution : Prendre un Arduino Mega 2560. Ce dernier dispose de 4 ports série. Mais le shield GSM qui fonctionnait out-of-the-box avec un Uno ne fonctionne plus sur Mega. En fait le port RX n'est plus sur la PIN2 de l'arduino mais sur la 10. Il faut donc bridger la pin 2 sur le 10 et l'empêcher de se connecter à l'Arduino. En connectant les alims comme il faut, tout fonctionne ! On peut donc brancher le shield GPS. Ajouter la libraire AltSoftSerial.h permet d'obtenir un second port série pour communiquer sur l'Arduino : on la configure pour utiliser les pins 14 et 15 (RX3 & TX3) du Mega. Le shield GPS passé en DLINE permet de sortir RX et TX sur les pins 2 et 3 du shield. On obtient donc notre deuxième liaison série. Celle-ci communique parfaitement. On arrive bien à récupérer la date et l'heure dans l'arduino via le GPS, et la position. Reste à mettre en forme les String ainsi obtenues pour pouvoir les envoyer dans la requête HTTP, globalement surtout mettre la date en forme souhaitée. Le tout devrait être fonctionnel en fin de semaine 8. Manque donc à l'heure actuelle les composants permettant de réaliser la sonde, soit au niveau du code une seule variable sur 4 pour avoir un projet totalement fonctionnel.

Semaine 8 (23/03/2015)

Nous avons récupéré avec succès les données que nous souhaitions utiliser du shield GPS. Une fois les librairies importées, la plus grosse partie a été de traiter les données. En effet, notre requête HTTP doit contenir les variables du GPS relevées sous forme de String, mais le GPS renvoie du float, double, int... En ce qui concerne la date et l'heure, un cast en (String)variable était suffisant pour la conversion, en concaténant les chaines avec l'opérateur + (opération permise par le constructeur String), il ne restait plus qu'à mettre en forme la variable meastime au bon format pour la requête SQL. Le gros problème est apparu avec la latitude et la longitude. La librairie TinyGPS++.h offre une grande précision au niveau de la position, ceci étant permis par le type double renvoyé par gps.position.lat() et gps.position.lng(). Impossible en castant avec (String) de faire rentrer tout ça dans le type String. Nous avons donc utilisé la fonction dtostr() qui permet de convertir un double en chaine de caractère, permettant au passage de choisir la précision par le nombre de chiffre que l'on souhaite avant et après la virgule (dans la limite où String ne peut pas être plus long que char[10]. On peut donc avoir, pour une latitude (-90 à +90°) jusqu'à 7 chiffres après la virgule, et 6 pour une longitude (-180 à 180°), sachant qu'un caractère de String est réservé pour indiquer la fin de la chaine, donc un maximum de 9 utilisables pour nos mesures de latitude et longitude. On peut éventuellement définir les constantes et demander au laboratoire quel précision il souhaite. Des tests ont été effectués, d'abord avec le format de la date, puis en extérieur avec les valeurs de latitude et longitude. Bilan : Près d'une fenêtre, le GPS se fixe en 2-3min, et en moins de temps qu'il ne faut pour lancer minicom, à l'extérieur. Toutes les variables sont récupérées et insérées dans la base de données avec succès. L'implémentation des deux parties de codes, distinctes jusqu'ici, GPS et GSM, est donc un succès. Nous allons désormais mettre en forme le code source de manière lisible, et expérimenter un système de mise en veille de l'Arduino avec réveil périodique par interruption, sur une période définie par le laboratoire, ce qui permettrait d'économiser l'énergie de la batterie, le but étant toujours de rendre l'ensemble du système totalement autonome. Pour la partie électronique, nous sommes toujours en attente de la sonde (l'unique variable - et peut-être la plus importante) qu'il manque pour utiliser à bon escient la balise, et des composants commandés, afin de pouvoir alimenter notre batterie avec des panneaux photovoltaïques. Enfin, nous avons mis à jour le site d'affichage des mesures. Une petite couche de CSS pour rendre le site beaucoup plus digeste.

Semaine 9 (30/03/2015)

Une première version du PCB du circuit électrique pour la gestion de l'énergie a été réalisé. De plus, M. Boé nous a suggéré d'offrir plus de mode de fonctionnement pour l'Arduino (Couper le GPS toutes les X minutes, stocker les données sur une carte SD quand le GSM est coupé...). On s'oriente donc sur deux modes différents pour la balise : un mode connecté, qui reste connecté au serveur en permanence et envoie périodiquement les données selon un intervalle de temps t, et un mode déconnecté qui se connectera toutes les t minutes puis se déconnectera une fois l'envoi de données effectué, ceci afin d'économiser la batterie. Pour économiser la batterie, il a aussi été décidé de pouvoir couper le shield GPS, et de gérer son fonctionnement depuis l'interface web.

Semaine 10 (06/04/2015)

L'interface web a été totalement refaite pour implémenter les différentes nouveautés : au programme, affichage des mesures d'une balise choisie en particulier, activation ou désactivation de son shield GPS via l'interface web, changement de l'intervalle d'envoi des mesures... Nous avons aussi réussi à palier à l'utilisation d'une horloge. En effet, la date et l'heure étant récupérées par le GPS, sa désactivation nous empêchait d'avoir ces données. Comme on travaille avec une base de données, la fonction UTC_CURRENT_TIMESTAMP() récupère l'heure et la date sur le serveur directement si l'Arduino n'a pas le GPS actif. Notons qu'avec cette méthode, on aura l'heure du serveur et non pas de l'emplacement de la balise. Admettons que le serveur soit décalé en méridiens par rapport à l'emplacement géographique de la balise et l'heure devrait être incorrecte, mais cela évite d'utiliser un équipement électronique en plus, aussi faible sa consommation puisse être... Cette méthode semble donc le meilleur compromis entre données et économies d'énergie.

Semaine 11 (13/04/2015)

Après plusieurs modifications du PCB afin de réduire la taille de la carte et d'un problème sur la génération du plan de masse, la carte électronique a pu être tirée. Beaucoup de travail sur la partie web pour implémenter efficacement les deux modes connecté et deconnecté sur lesquels nous nous sommes orientés. Modifications des tables SQL correspondantes, notamment des types de données de certaines colonnes ainsi que l'ajout d'une table pour la gestion d'un parc entier de balises repérées par leur ID.

Semaine 12 (20/04/2015)

Les composants ont été soudés sur la carte. Un test aura lieu pendant les vacances afin de vérifier son bon fonctionnement. -> Après tests, la carte fonctionne et permet de recharger la batterie

Fichiers Rendus

Site web : URL | Download (.tar) | Download (.zip)

Code Arduino : View | Download (.zip) | Download (.tar)

Rapport de Projet : View