Partie technique Data painting : Différence entre versions

De Learning Lab Environnements Connectés
Sauter à la navigation Sauter à la recherche
Ligne 188 : Ligne 188 :
 
== Partie Maquettage ==
 
== Partie Maquettage ==
  
[[Fichier:plan_maquette.jpg|thumb|left|Module GPS avec son shield]]
+
[[Fichier:plan_maquette.jpg|thumb|left|Plan des différents étages de la maquette]]
[[File:Plan_maquette.pdf]]
+
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.<br/>
 +
Voici les plans en version PDF :<br/>
 +
*[[File:Plan_maquette.pdf]] (bien vérifier que l'épaisseur du matériau corresponde pour que les pièces s’emboîtent)

Version du 11 décembre 2015 à 23:15

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

Voici les différents éléments en image :

carte arduino utilisée
capteur de température
Module GPS avec son shield
Shield grove pour arduino
Ecran LCD
Batterie d'alimentation




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

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.

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++;
  }
}
Exemple du tracé obtenu à partir des mesures et du code processing

Partie Maquettage

Plan des différents étages de la maquette

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 :