Partie technique Data painting
Sommaire
Partie Electronique
Cette partie a pour but d'expliciter la réalisation technique du projet. C'est en d'autre mot la recette à suivre pour construire le projet
Matériel utilisé
- Une carte Arduino Yun
- Un capteur de température et d'humidité HTU21D-F
- Un module GPS avec son shield : EM406
- Un écran LCD-Grove et son shield adaptable à la carte Arduino
- Une batterie d'alimentation 5v 6000mAh Leitz
- Une carte SD SanDisk 32 Go
Voici les différents éléments en image :
Voici les liens vers les différentes datasheet des composants :
présentation Arduino Yun
datasheet GPS
datasheet capteur de température/humidité
datassent écran LCD
Capteur Humidité & Température
Le capteur d'humidité et de température sont monté sur un même circuit : le HT21D-f. Il fonctionnera en liaison I2C avec la carte Arduino Yun. Voici le schéma de branchement :
Une fois le branchement effectué, testez le fonctionnement du capteur seul. Avec le logiciel Arduino, allez sur Croquis >> Inclure une bibliothèque >> Gérez les bibliothèques , tapez Adafruit HTU21D-F Library et installez la bibliothèque. Puis allez dans Fichier >> Exemples >> Adafruit HTU21D-F Library >> HTU21DF_test Téléverser le programme et vérifiez dans le moniteur série l'affichage de la température et de l'humidité. Si tout marche bien, un affichage semblable devrait apparaitre :
Temp : xx°C Hum : xx % Temp : xx°C Hum : xx % Temp : xx°C Hum : xx % Temp : xx°C Hum : xx % ...
Stockage des données sur carte Micro-SD
La carte de développement Arduino Yun dispose d'un lecteur de carte micro-SD. Gràce à quelques lignes de commandes simples, nous pouvons dialoguer avec ce périphériques afin de stocker des données dessus. En l’occurrence ici, les valeurs de nos différents capteurs. Avant de plugger la carte mémoire dans la Yun, connecter la micro-SD à votre PC, vérifiez bien qu'elle est vide et formaté en FAT32, puis, créez à la racine un dossier "arduino". Celui-ci est indispensable afin d'établir la connexion entre la carte SD et l'Arduino Yun.
Vous pouvez à présent placer votre carte mémoire dans le slot, puis lancer le programme ci-dessous. Afin de vérifiez le fonctionnement du programme, rebrancher la carte SD à votre ordinateur, un fichier "datalog.txt" doit avoir apparu avec le mot "test" écrit à l'intérieur.
#include <FileIO.h>
void setup() {
Bridge.begin();
Serial.begin(9600);
FileSystem.begin();
while(!Serial);
Serial.println("Filesystem datalogger\n");
}
void loop() {
File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_APPEND);
if (dataFile) {
dataFile.println("test");
dataFile.close();
}
else {
Serial.println("error opening datalog.txt");
}
delay(15000);
}
Branchements
Pour commencer à brancher le système il est nécessaire de comprendre les différents moyens de communications des capteurs avec la carte.
Pour commencer, parlons du GPS. Le GPS utilise la liaison série pour communiquer (TX/RX). Le shield a deux fonction de communication : UART et DLINE. Cette différence n'est qu'une variation des pins utilisées. Nous avons fonctionné, lors de notre projet, en mode DLINE. Attention ! Il serait donc logique de connecter les pins 2 et 3 sur les 0 et 1 de la carte. Cependant le code créée utilise des interruptions et la carte arduino yun ne supporte pas les interruptions sur la pin 0. Il faut donc l'associer à la pin 10.
Voici donc le code utilisé pour récupérer la latitude et la longitude d'une position. Ces données sont brutes et seront traitées après récupération avec le logiciel processing.
Partie Processing
Une fois la donnée récupérée, elle est stockée sur la carte micro SD dans un fichier csv avec ce formattage :
latitude,longitude,altitude,température,humidité <--- 1ère mesure latitude,longitude,altitude,température,humidité <--- 2ème mesure latitude,longitude,altitude,température,humidité <--- 3ème mesure latitude,longitude,altitude,température,humidité <--- 4ème mesure ...
voici un exemple de dix mesures captées avec le dispositif :
45.451343,4.387325,516.40,16.07,43.03 45.451343,4.387325,516.40,16.04,43.47 45.451347,4.387387,515.40,15.75,44.35 45.451347,4.387387,515.40,15.68,44.58 45.451339,4.387518,515.40,15.48,44.78 45.451351,4.387597,511.60,15.12,45.52 45.451351,4.387597,511.60,14.98,46.01 45.451366,4.387747,513.10,14.96,46.49 45.451366,4.387747,513.10,14.95,46.91 45.451389,4.387815,515.40,14.95,46.83 45.451389,4.387815,515.40,14.98,46.78
Le fichier obtenu (ici "data.csv") est par la suite importé sur processing et interprété en points de différentes taille et couleur avec le code suivant :
Table table;
float[] latitude;
float[] longitude;
int[] altitude;
int[] temperature;
float[] x;
float[] y;
//-------------------------------------------------------------------------------------------------------------
//--- Données à modifier pour adapter le tracé
int maxMapAlti = 30; //diametre des cercles en fonction de l'altitude (en px)
int decalage = 250; //taille des bordures de la zone de rendu (en px)
//-------------------------------------------------------------------------------------------------------------
void setup() {
size(displayWidth, displayHeight);
frameRate(60);
table = loadTable("datas.csv");
int nbreLignes = table.getRowCount();
latitude = new float[nbreLignes];
longitude = new float[nbreLignes];
altitude = new int[nbreLignes];
temperature = new int[nbreLignes];
for (int i=0; i<=table.getRowCount()-1; i++) {
latitude[i] = table.getRow(i).getFloat(0);
longitude[i] = table.getRow(i).getFloat(1);
altitude[i] = table.getRow(i).getInt(2);
temperature[i] = table.getRow(i).getInt(3);
}
//-------------------------------------------------------------------------------------------------------------
//--- Formule de transformation de coordonées polaires en coordonées x, y à l'échelle du monde
//-------------------------------------------------------------------------------------------------------------
float[] xWorld = new float[nbreLignes];
float[] yWorld = new float[nbreLignes];
for (int i=0; i<=table.getRowCount()-1; i++) {
xWorld[i] = (longitude[i]+180)*((width-(2*decalage))/360);
float latRad = latitude[i]*PI/180;
float mercN = log(tan((PI/4)+(latRad/2)));
yWorld[i] = ((height-(2*decalage)/2))-((width-(2*decalage))*mercN/(2*PI));
}
//-------------------------------------------------------------------------------------------------------------
//--- Mise à l'échelle des coordonnées pour qu'elle apparaissent à l'échelle de la fenêtre de visualisation
//-------------------------------------------------------------------------------------------------------------
float xMax = max(xWorld);
float xMin = min(xWorld);
float yMax = max(yWorld);
float yMin = min(yWorld);
float ratioGPS = (xMax - xMin) / (yMax - yMin);
float windowWidth = width-(2*decalage);
float windowHeight = height-(2*decalage);
float ratioWindow = windowWidth/windowHeight;
x = new float[nbreLignes];
y = new float[nbreLignes];
if (ratioGPS < ratioWindow) {
for (int i=0; i<=table.getRowCount()-1; i++) {
y[i] = map(yWorld[i], yMin, yMax, decalage, height-decalage);
x[i] = map(xWorld[i], xMin, xMax, decalage, ratioGPS*(height-decalage));
}
} else {
for (int i=0; i<=table.getRowCount()-1; i++) {
x[i] = map(xWorld[i], xMin, xMax, decalage, width-decalage);
y[i] = map(yWorld[i], yMin, yMax, decalage, (width-decalage)/ratioGPS);
}
}
}
//-------------------------------------------------------------------------------------------------------------
//--- Affichage du tracé
//-------------------------------------------------------------------------------------------------------------
int timer = 1;
void draw() {
//-------------------------------------------------------------------------------------------------------------
//--- Centrage des éléments
//-------------------------------------------------------------------------------------------------------------
translate(width/2-(max(x)-min(x))/2-decalage, height/2-(max(y)-min(y))/2-decalage);
colorMode(RGB, 255);
background(255);
colorMode(HSB, 100);
//-------------------------------------------------------------------------------------------------------------
//--- Lignes entre les points (mettre le timer à 2 pour que cela fonctionne)
//-------------------------------------------------------------------------------------------------------------
stroke(5);
for (int i=0; i<=timer-2; i++) {
stroke(map(temperature[i], 0, 30, 50, 100), 90, 90);
strokeWeight(5);
line(x[i], y[i], x[i+1], y[i+1]);
}
//-------------------------------------------------------------------------------------------------------------
//--- placement des points suivant les coordonées x, y, la température et l'altitude
//-------------------------------------------------------------------------------------------------------------
noStroke();
for (int i=0; i<=timer-1; i++) {
fill(map(temperature[i], 0, 30, 50, 100), 90, 90);
ellipse(x[i], y[i], map(altitude[i], 0, 800, 1, maxMapAlti), map(altitude[i], 0, 800, 1, maxMapAlti));
}
//-------------------------------------------------------------------------------------------------------------
//--- dégradé de couleurs pour la température
//-------------------------------------------------------------------------------------------------------------
/*
for (int i=0; i<=20; i++) {
fill(50+i*2.5, 100, 100);
rect(50+52*i, 50, 50, 25);
text(int(map(50+i*2.5,50,100,0,30)) + "°C",50+52*i, 49);
}
*/
//-------------------------------------------------------------------------------------------------------------
//--- Mise à jour du timer pour faire apparaitre tous les points jusqu'à la fin de l'animation
//-------------------------------------------------------------------------------------------------------------
//save("img"+timer+".png");
if (timer >= table.getRowCount()) {
timer = table.getRowCount();
} else {
timer++;
}
}
Partie Maquettage
Les différents composants électroniques étaient disposés sur une maquette découpé à la découpeuse laser sur du bois d'une épaisseur de 3mm.
Voici les plans en version PDF :
- Fichier:Plan maquette.pdf (bien vérifier que l'épaisseur du matériau corresponde pour que les pièces s’emboîtent)
