IMA4 2017/2018 P18 : Différence entre versions

De Wiki de Projets IMA
(Semaine 13)
 
(19 révisions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 +
<include nopre noesc src="/home/pedago/pimasc/include/video-MandalaElectronique-iframe.html" />
 
__TOC__
 
__TOC__
 
<br style="clear: both;"/>
 
<br style="clear: both;"/>
Ligne 396 : Ligne 397 :
  
 
==Semaine 13==
 
==Semaine 13==
Pour trouver les dispositon des LEDs, nous avons fait un programme de pilote des LEDs qui peut allumer des LEDs une à une dans  l'ordre du première sortie jusqu’au dernière.
+
pour trouver la disposition des porte-LEDs par rapport aux sorties des pilotes de LED, nous avons écrit un programme qui active les sorties une à une dans  l'ordre de la première sortie jusqu’à la dernière.
Voici un extrait du code.
+
Voici un extrait du code.
  
 +
#define NB_DRIVERS 3
 +
#define DLED_CHANNELS 24
 +
#define NB_GROUPES (NB_DRIVERS*DLED_CHANNELS)
  
  TLC5947 LEDs driver
+
  unsigned int groupes[NB_GROUPES];
Include files
+
  int n=0;
#include <avr/io.h>
+
while(1){
#include "tlc5947.h"
+
   printf("Channel #%d on\n",n);
// Global variables
+
   for(int i=0;i<NB_DRIVERS*DLED_CHANNELS;i++) groupes[i]=(i==n)?MAX_VALEUR:0;
// Functions
+
  set_LED_Drivers(groupes,NB_DRIVERS);
  void init_LED_Drivers(int nb){
+
  n++; if(n>=NB_DRIVERS*DLED_CHANNELS) n=0;
  // LED drivers I/O as outputs
+
  _delay_ms(WAIT_DELAY);
  DDR_DLED |= (1<<PIN_DLED_CLOCK) |  (1<<PIN_DLED_DATA) | (1<<PIN_DLED_LATCH);
 
                        // Set LATCH  output low
 
  PORT_DLED &= ~(1<<PIN_DLED_LATCH);
 
}
 
 
 
void set_LED_Drivers(unsigned int pwm[],int nb){
 
   int c,b;
 
                        // Set LATCH  output low
 
  PORT_DLED &= ~(1<<PIN_DLED_LATCH);
 
  // 24 channels per TLC5947
 
   for(c=DLED_CHANNELS*nb-1;c>=0;c--){
 
    // 12 bits per channel, send MSB first
 
    int v=pwm[c];
 
    for(b=0;b<12;b++){
 
                        // Set CLOCK output low
 
      PORT_DLED &= ~(1<<PIN_DLED_CLOCK);
 
 
 
                        // Set DATA as stated by bit #b of c
 
      if(v & 0x0800)
 
        PORT_DLED |= (1<<PIN_DLED_DATA);
 
      else
 
        PORT_DLED &= ~(1<<PIN_DLED_DATA);
 
 
 
                        // Set CLOCK output HIGH
 
      PORT_DLED |= (1<<PIN_DLED_CLOCK);
 
      v <<= 1;
 
    }
 
 
   }
 
   }
                        // Set CLOCK output low
 
  PORT_DLED &= ~(1<<PIN_DLED_CLOCK);
 
 
                        // Set LATCH output high
 
  PORT_DLED |= (1<<PIN_DLED_LATCH);
 
                        // Set LATCH output low
 
  PORT_DLED &= ~(1<<PIN_DLED_LATCH);
 
}
 
  
  
Ligne 451 : Ligne 420 :
  
  
 +
Le ZX gesture est capable de détecter trois mouvements : un geste vers le haut, vers la droite ou vers la gauche. Comme le capteur est utilisé verticalement le geste vers le haut est plutôt un geste d’éloignement. Le capteur est installé sur le bois du mandala. Ses broches CLM et DR sont connectées, respectivement, sur les ports PD3 et PD4 de l’ATMega328p.
 +
Nous utilisons le capteur pour contrôler la vitesse de l'animation du mandala et pour changer d’animation et la vitesse du changement.
 +
Lorsque le geste sur le coté droit est détecté (geste=2 sur la photo), le temps d’attente dans les animations est diminué ce qui accélère la vitesse de l’animation.
 +
Lorsque le geste sur le coté gauche est détecté (geste=1 sur la photo), le temps d’attente dans les animations est augmenté ce qui diminue la vitesse de l’animation.
 +
Chaque fois qu'un geste d’éloginement est détecté (geste=3 sur la photo), l’animation change.
 +
Pour gérer le ZX Gesture nous utilisons une bibliothèque C de gestion du bus I2C, voici la fonction permettant de récupérer un registre du ZX Gesture (par exemple la position se récupère dans un de ces registres) :
  
 +
int zx_getreg(int reg){
 +
int ret;
 +
i2c_start_wait(ZX_ADDR|I2C_WRITE);
 +
i2c_write(reg);
 +
i2c_rep_start(ZX_ADDR|I2C_READ);
 +
ret=i2c_readNak();
 +
i2c_stop();
 +
return ret;
 +
}
  
Un capteur de distance et de mouvement ZX est installé sur le bois du mandala.
+
[[Fichier:gestecode.jpg|thumb|400px|center]]
Nous utilisons des capteurs pour controler les changement de l'animation du mandala et la vitesse du changement.
 
Lorsque le geste sur le coté droit est détecter, g=1 et la valeur du quantum plus 100 ,ce qui signifie que accélérer de la vitesse du luminance des LEDs.
 
Lorsque le geste sur le coté gauche est détecter, g=2 et la valeur du quantum moins 100 ,ce qui signifie que diminuer de la vitesse du luminance des LEDs.
 
Chaque fois qu'un geste up est détecté, g=3 et le mandala va changer un animation.
 
 
 
#include "i2cmaster.h"
 
#include "zxgesture.h"
 
 
 
// Functions
 
 
 
/* Get ZX gesture register value */
 
 
 
int zx_getreg(int reg){
 
int ret;
 
i2c_start_wait(ZX_ADDR|I2C_WRITE);
 
i2c_write(reg);
 
i2c_rep_start(ZX_ADDR|I2C_READ);
 
ret=i2c_readNak();
 
i2c_stop();
 
return ret;
 
}
 
 
 
/* Get ZX gesture model number */
 
 
 
int zx_get_model(void){
 
int model=zx_getreg(ZX_REG_MODEL);
 
return model;
 
}
 
 
 
/* Is a position ready to be read ? */
 
 
 
unsigned char zx_position_ready(void){
 
int status=zx_getreg(ZX_REG_STATUS);
 
return (status&ZX_BIT_POSITION)?1:0;
 
}
 
 
 
/* Is a gesture ready to be read ? */
 
 
 
unsigned char zx_gesture_ready(void){
 
int status=zx_getreg(ZX_REG_STATUS);
 
return (status&ZX_BIT_GESTURE)?1:0;
 
}
 
 
 
/* Get X and Z positions */
 
 
 
void zx_get_positions(int *x,int *z){
 
*x=zx_getreg(ZX_REG_XPOS);
 
*z=zx_getreg(ZX_REG_ZPOS);
 
}
 
 
 
/* Get gesture */
 
int zx_get_gesture(void){
 
int gesture=zx_getreg(ZX_REG_GESTURE);
 
return gesture;
 
}
 
  
 
==Semaine 14==
 
==Semaine 14==
 +
Nous avons terminé le travail de programmation : trois animations sont programmées et le ZX  Gesture est utilisé.
 +
Nous avons conçu trois animations.
  
Pour la programmation, l'IDE Arduino utilise du c++ qui n'est pas assez efficace pour un micro-controôeur qui ne dispose que de 16Ko pour le programme et 2Ko de RAM.
+
Pour la première, les lumières sont allumées de l'intérieur vers l'extérieur.
 
+
[[Media:type1.mp4]]
Nous avons terminé le travail de programmation et réalisé le changement de l'ensemble du modèle Mandala contrôlé par des capteurs détectant différents gestes.
 
 
 
Nous avons conçu trois méthodes de transformation.
 
 
 
Dans le premier type, les lumières sont allumées de l'intérieur vers l'extérieur;
 
 
 
Le deuxième type, les lumières s'allument une à une dans le sens antihoraire et l'ordre du cercle intérieur à extérieur;
 
  
Le troisième type, toutes les lumières sont allumées en même temps.
+
Pour la seconde, les portes-LEDs s'allument un à un dans le sens antihoraire et l'ordre du cercle intérieur vers le cercle extérieur;
 +
[[Media:type2.mp4]]
  
Voila un extrait du code pour réaliser ces 3 animation.
+
Pour la troisième, toutes les lumières sont allumées en même temps, leur luminosité varie.
 +
[[Media:type3.mp4]]
  
#include <stdio.h>
+
Nous allons montrer comment sont définies ces animations dans le code.
 +
La première animation est constituée de 6 sous-animations. Chacune fait varier la luminosité d’un groupe circulaire de portes-LEDs. L’augmentation de la luminosité se fait en 500ms, la diminution en 500ms et la sous-animation se met en pause pendant 2s. En lançant les sous-animations tous les 500ms, on obtient un effet de propagation du centre vers l’extérieur.
 +
Les structures définissant cette animations sont données juste aprés. Le tableau a1 comporte les 6 sous-animations commandées par les paramètres v1 à v6.
  
#include "time.h"
+
/* Animations1 */
#include "tlc5947.h"
+
variation_params v1={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
#include "zxgesture.h"
+
variation_params v2={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
#include "animations.h"
+
variation_params v3={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=256};
 
+
variation_params v4={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
// Global variables
+
variation_params v5={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
+
variation_params v6={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
/* Values for each LED sets */
+
  animation a1[]={
unsigned int groupes[NB_GROUPES];
 
 
 
/* Definition of LED sets */
 
int groupe1[]={
 
  23,10,7,40,61,70,55,13,-1
 
  };
 
int groupe2[]={
 
  5,9,39,43,63,48,57,20,-1
 
  };
 
int groupe3[]={
 
  22,24,8,29,30,33,38,42,60,64,67,49,52,58,14,18,-1
 
  };
 
int groupe4[]={
 
  0,4,6,26,31,34,37,44,47,65,68,50,53,59,15,19,-1
 
 
 
  };
 
int groupe5[]={
 
  2,11,25,27,32,35,41,45,62,66,71,51,56,12,17,21,-1
 
};
 
int groupe6[]={
 
  1,3,28,36,46,69,54,16,-1
 
};
 
 
 
int tous[]={
 
  23,10,7,40,61,70,55,13,
 
  5,9,39,43,63,48,57,20,
 
  22,24,8,29,30,33,38,42,60,64,67,49,52,58,14,18,
 
  0,4,6,26,31,34,37,44,47,65,68,50,53,59,15,19,
 
  2,11,25,27,32,35,41,45,62,66,71,51,56,12,17,21,
 
  1,3,28,36,46,69,54,16,
 
  -1
 
  };
 
 
 
/* Animations1 */
 
variation_params v1={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
variation_params v2={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
variation_params v3={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=256};
 
variation_params v4={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
variation_params v5={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
variation_params v6={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 
animation a1[]={
 
 
   {0,60000,groupe1,&v1,variation_groupes},
 
   {0,60000,groupe1,&v1,variation_groupes},
 
   {500,60000,groupe2,&v2,variation_groupes},
 
   {500,60000,groupe2,&v2,variation_groupes},
Ligne 586 : Ligne 473 :
 
   };
 
   };
  
/* Animation2 */
+
Pour la troisième animation, nous voulions que toutes les LEDs soient allumées en même temps. Nous avons mis le temps de croissance à 500, le temps de décroissance à 500 sans pause. Comme les LEDs bleues sont toujours plus lumineuses que les autres LEDs, on les limite à une luminosité de 256. Le maximum de luminosité pour les autres LEDs est de 1024 (pour un maximum de 4096).
variation_params v_tous={.deltac=100,.deltad=100,.deltap=0,.min=0,.max=255};
+
Voici les paramètres des sous-animations de cette troisième animation.
animation a2[]={
+
 
  {0,40000,tous,&v_tous,variation_groupe},
+
variation_params v21={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
  {-1,-1,NULL,NULL,NULL}
+
variation_params v22={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
  };
+
variation_params v23={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=256};
 +
variation_params v24={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 +
variation_params v25={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 +
variation_params v26={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 +
 
 +
Nous avons mis 0 ms pour le temps de départ de l’animation et 60000 ms pour le temps d’arrêt de l’animation.
  
/* Animation3 */
+
animation a3[]={
variation_params v21={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
+
   {0,60000,groupe1,&v21,variation_groupes},  
variation_params v22={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 
variation_params v23={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=256};
 
variation_params v24={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 
variation_params v25={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 
variation_params v26={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
 
animation a3[]={
 
   {0,60000,groupe1,&v21,variation_groupes},
 
 
   {0,60000,groupe2,&v22,variation_groupes},
 
   {0,60000,groupe2,&v22,variation_groupes},
 
   {0,60000,groupe3,&v23,variation_groupes},
 
   {0,60000,groupe3,&v23,variation_groupes},
Ligne 609 : Ligne 494 :
 
   {-1,-1,NULL,NULL,NULL}
 
   {-1,-1,NULL,NULL,NULL}
 
   };
 
   };
 
animation *anims[]={a1,a2,a3,NULL};
 
 
/* Variables for animation settings */
 
int quantum=1000;
 
int stop;
 
 
// Functions
 
//
 
/* Handle the user input */
 
 
void user_input(void){
 
if(zx_gesture_ready()){
 
  int g=zx_get_gesture();
 
  printf("geste=%d quantum=%d\n",g,quantum);
 
  switch(g){
 
    case ZX_GEST_RIGHT:
 
      if(quantum>QUANTUM_MIN) quantum -= QUANTUM_PAS;
 
      break;
 
    case ZX_GEST_LEFT:
 
      if(quantum<QUANTUM_MAX) quantum += QUANTUM_PAS;
 
      break;
 
    case ZX_GEST_UP:
 
      stop=1;
 
      break;
 
    }
 
  }
 
}
 
 
/* Wait some time */
 
 
void wait_us(unsigned long delay){
 
static unsigned long start;
 
if(delay==0) start=micros();
 
else
 
  while(1){
 
    unsigned long now=micros();
 
    unsigned long delta=now-start;
 
    user_input();
 
    if(delta>=delay) break;
 
    }
 
}
 
 
/* Get a set of LEDs size */
 
 
int taille_groupes(int leds[]){
 
int i=0;
 
while(leds[i]>=0) i++;
 
return i;
 
}
 
 
/* Set luminosity value to a set of LEDs */
 
 
void valeur_groupes(int leds[],unsigned int valeur){
 
int i=0;
 
while(1){ if(leds[i]<0) break; groupes[leds[i++]]=valeur; }
 
}
 
 
/* Compute variation of luminosity for a set of LEDs */
 
 
void variation_groupes(int leds[],void *arg,long temps){
 
variation_params *p=arg;
 
long periode=p->deltac+p->deltad+p->deltap; // Dans quelle phase de la variation se trouve-t-on ?
 
long instant=temps%periode;
 
if(instant<=p->deltac){ // Cas de la phase de croissance de p->min à p->max
 
  long calc=(long)p->max-(long)p->min;
 
  calc=calc*instant/p->deltac+p->min;
 
  valeur_groupes(leds,calc);
 
  }
 
else if(instant<=p->deltac+p->deltad){ // Cas de la phase de décroissance
 
  long calc=(long)p->min-(long)p->max;
 
  calc=calc*(instant-p->deltac)/p->deltad+p->max;
 
  valeur_groupes(leds,calc);
 
  }
 
else // Cas de la pause
 
  valeur_groupes(leds,p->min);
 
}
 
 
/* Variation set by set */
 
 
void variation_groupe(int leds[],void *arg,long temps){
 
variation_params *p=arg;
 
long periode=p->deltac+p->deltad+p->deltap;
 
long nb=temps/periode; // Quel groupe de LED est concerné ?
 
nb=nb%taille_groupes(leds);
 
int instant=temps%periode; // Quelle est la phase courante de la variation ?
 
if(instant<=p->deltac){ // Cas de la phase de croissance de p->min à p->max
 
  long calc=(long)p->max-(long)p->min; calc=calc*instant/p->deltac+p->min;
 
  groupes[leds[nb]]=calc;
 
  }
 
else if(instant<=p->deltac+p->deltad){ // Cas de la phase de décroissance
 
  long calc=(long)p->min-(long)p->max; calc=calc*(instant-p->deltac)/p->deltad+p->max;
 
  groupes[leds[nb]]=calc;
 
  }
 
else // Cas de la pause
 
  groupes[leds[nb]]=p->min;
 
}
 
 
/* Play an animation */
 
 
void animation_play(animation *a){
 
static unsigned char init;
 
if(init==0){ init_LED_Drivers(NB_DRIVERS); init_time(); init=1; }
 
animation *p;
 
unsigned long temps=0;
 
int i;
 
for(i=0;i<NB_GROUPES;i++) groupes[i]=0;
 
while(stop==0){
 
  unsigned char actif=0;
 
  wait_us(0);
 
  for(p=a;p->depart>=0;p++){
 
    user_input();
 
    if(temps>p->arret) continue;
 
    actif=1;
 
    if(temps<p->depart) continue;
 
    p->fun_anim(p->groupes,p->params,temps-p->depart);
 
    }
 
  if(!actif) break;
 
  set_LED_Drivers(groupes,NB_DRIVERS);
 
  wait_us(quantum);
 
  temps++;
 
  }
 
stop=0;
 
}
 
 
/* Play all animations */
 
  
void animation_all(void){
+
Ces structures sont données en paramètre d’une fonction qui implante l’animation.
printf("Play all\n");
 
animation **a=anims;
 
while(*a!=NULL) animation_play(*a++);
 
}
 
  
 
=Documents Rendus=
 
=Documents Rendus=
[[Fichier:Rapport_P18.odt]]
+
[[Media:Rapportp18.odt]]
  
 
[[Media:led_code.zip]]
 
[[Media:led_code.zip]]

Version actuelle datée du 15 juin 2018 à 21:43


Vidéo HD


Présentation générale

Description

Le mot mandala vient d‘une très ancienne langue indienne.Il signifiant:

  1. disque, cercle, sphère ;
  2. toute figure géométrique apparentée au cercle ;
  3. structure, forme d'organisation ;
  4. dessin que l'on trace sur le sol ou sur un autre support à l'occasion de divers rites.

Il s'exprime dans un dessin circulaire, convergeant vers un centre porteur d'infini. Dans la tradition orientale, le cercle représente le Divin, sa manifestation, sa création. Ce symbole du cercle se retrouve dans toutes les cultures et toutes les traditions, tant occidentales qu'orientales.

Le cercle est le symbole de la vie: la naissance, la maturité, la mort et la résurrection ou la renaissance. Dans le bouddhisme, il est utilisé surtout pour la méditation. Le diagramme est dans tous les cas rempli de symboles; il peut être associé à une divinité.

Objectifs

L'objectif est de réaliser un mandala électronique.

Analyse du projet

Analyse du premier concurrent

2018 P18 kit noel.png

Un premier concurrent pourrait être ce kit électronique de sapin de noël avec 16 LEDs clignotantes. Par rapport à notre mandala ce kit comporte peu de LEDs et ne réalise qu'une seule animation sans interaction avec les visiteurs.


Analyse du second concurrent

2018 P18 Xiaojingling1.png

Un second concurrent plus en rapport avec l'apparence de notre mandala est un tableau lumineux pour décoration de chambre d'enfant. Il s'agit d'une peinture avec un éclairage par LEDs. Là encore moins de LEDs et d'interaction qu'avec notre mandala.


Originalité de notre mandala

L'originalité de notre mandala, par rapport aux objets décoratifs déjà existants, est qu'il comportant un grand nombre de LEDs (environ 200), qu'il intègre un micro-contrôleur permettant des animations variées (contrôle de la luminosité des LEDs) et qu'enfin le mandala est interactif grâce à un détecteur de gestes.

Scénario d'usage du produit ou du concept envisagé

Notre mandala est un élément de décoration et, avec des animations adaptées, peut être un objet de relaxation.

Le visiteur est tout d'abord attiré par l'objet artistique, en effet quand il entre dans la pièce, le mandala apparaît comme une peinture sur bois. Au second regard le circuit central pique la curiosité du visiteur. En s'approchant le visiteur déclenche une animation lumineuse. Surpris, il fait un mouvement involontaire qui déclenche un autre type d'animation. Le visiteur teste alors d'autres gestes pour rentrer en interaction avec le mandala.

Le mandala réagissant aux gestes du visiteur, des gestes lents conduisent à des animations relaxantes.

Réponse à la question difficile

Durant la présentation de notre projet les deux questions suivantes nous ont été posées.

Première question

Combien de LEDs le mandala va-t-il comporter, combien de groupes de LEDs indépendants pour les animations ?

Nous avons fait une première esquisse de notre mandala :

2018 P18 mandala brouillon.jpg

Au vu de ce premier dessin, nous avons décidé de rajouter encore des LEDs. Nous partons sur 6 groupes de LEDs pour un total de 256 LEDs :

  • un premier cercle de 32 LEDs oranges ;
  • un deuxième cercle de 32 LEDs jaunes ;
  • un troisième cercle de 32 LEDs bleues ;
  • un quatrième cercle de 64 LEDs jaunes ;
  • un cinqième cercle de 64 LEDs oranges ;
  • enfin un dernier cercle de 32 LEDs oranges.

Seconde question

Le mandala sera alimenté de quelle façon pour quelle autonomie ?

Un rapide calcul de la consommation des LEDs toutes allumées donne un total de 20mA par 256 LEDs soit près de 4A. Même pour une autonomie de 24h, il faudrait une batterie trop importante. Les LEDs ne doivent donc être allumées que lorsqu'un visiteur est présent et les animations doivent éviter les tableaux avec toutes les LEDs allumées à pleine puissance. En partant sur l'équivalent de deux LEDs allumées à pleine puissance tout le temps et sur une consommation du circuit d'environ 40mA nous obtenons une consommation moyenne d'environ 100mA. Avec une alimentation par 8 piles rechargeables AA de 2600MAh nous avons une autonomie d'environ un jour. Il faut donc prévoir que la carte électronique puisse entrer dans un mode d'économie d'énergie ou plus simplement un interrupteur pour éviter de décharger les piles.

Extension de fonction

Utiliser avec ZX Distance et Gesture Sensor

Préparation du projet

Cahier des charges

L'objet final sera constitué des composants ci-dessous.

  1. une peinture de type mandala sur une planche de contre-plaqué réalisée à la gouache ;
  2. une carte électronique centrale à base de micro-contrôleur utilisant des pilotes de LEDs ;
  3. des petites cartes dissiminés sur l'ensemble de la peinture pour porter les LEDs, les connexions avec la carte centrale se fait par des fils passant à l'arrière de la planche ;
  4. les boitiers de piles sont aussi à fixer à l'arrière du mandala ;
  5. pour la détection des gestes nous utiliserons une carte "ZX Distance et Gesture Sensor" de SparkFun.

Choix techniques : matériel et logiciel

Inkscape: pour dessiner un dessin mandala

Frizing: dessiner tous les circuits imprimés et PCBs

Ardunio: programmation informatique pour contrôler les LEDs

Liste des tâches à effectuer

Les tâches à effectuer pour ce projet sont :

  1. faire un dessin précis du mandala avec la position des cartes électronique et celles des trous pour faire passer les câbles permettant de relier les cartes, il faut aussi ajouter les ouvertures permettant d'intégrer le détecteur de gestes ;
  2. choisir un dispositif pour contrôleur les LEDs (registre à décalage ou pilote de LEDs) ;
  3. concevoir le circuit à base de micro-contrôleur pour contrôler les très nombreuses LEDs ;
  4. réaliser (souder) la carte électronique et la tester ;
  5. concevoir les cartes électroniques porte LEDs et les réaliser ;
  6. Programmer des animations pouvant être déclenchées par le capteur de gestes.

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 Heures S13 Heures S14 Total
Dessin du mandala 0 4 4
Contrôle des LEDs 0 4 4
Réalisation du circuit principal 0 4 4 4 12
Réalisation des circuits porte-LEDs 0 4 4 4 12
Réalisation du mandala 0 4 4 4 4 6 4 4 30
Programmation des animations 0 8 8

Semaine 1

Nous avons établi une première liste de matériel nécessaire pour le mandala.

Nous avons aussi utilisé le logiciel inkscape pour dessiner les éléments artistiques du mandala. Le fichier vectoriel est disponible : Media:2018_P18_Mandala Drawing.svg, l'image ci-dessous en donne un aperçu.

2018 P18 Mandala Drawing.png

Semaine 2

L'encadrant en électronique a conseillé d'utiliser des circuits pilotes de LEDs pour gérer les LEDs. Nous avons préféré utiliser des contrôleurs TLC59711 et TLC5947 car ces circuits sont bien documents sur ce document [1].

Pour savoir quel circuit et à combien d'exemplaires il faut utiliser, nous devons décider du voltage d'alimentation et en déduire le nombre de sorties dont nous avons besoin.

Nous allons utiliser 8 accumulateurs à 1,2v nous disposons donc d'une tension d'alimentation de 9,6v.

Chaque sortie des pilotes va donc pouvoir contrôler 4 LEDs à 2v et 2 LEDs à 3,3v.

Pour nos cinq cercles de LEDs cela donne donc les nombres suivant de sorties nécessaires :

  • un premier cercle de 32 LEDs rouges (2v), soit 8 sorties nécessaires ;
  • un deuxième cercle de 32 LEDs oranges (2v), soit 8 sorties nécessaires ;
  • un troisième cercle de 48 LEDs bleues (3v), soit 16 sorties nécessaires  ;
  • un quatrième cercle de 64 LEDs jaunes (2v), soit 16 sorties nécessaires ;
  • un cinqième cercle de 64 LEDs rouges (2v), soit 16 sorties nécessaires ;
  • enfin un dernier cercle de 32 LEDs jaunes (2v), soit 8 sorties nécessaires.

En définitive 72 sorties sont nécessaires. En choisissant des circuits TLC5947 à 24 sorties nous couvront les besoins avec 3 circuits et en laissant une marge pour ajouter des LEDs si nécessaire.

2018-P18-Montage-TLC59771.png

Pour tester un circuit pilote de LEDs nous avons réalisé un montage avec une plaque d'essai, une pile de 9v et un circuit d'Adafruit à base de TLC59711 (un circuit très proche du TLC5947 mais avec seulement 12 sorties).

Nous avons connecté notre montage à un Arduino et nous avons programmé l'Arduino pour allumer les LEDs sur les différentes sorties alternativement. Le code est disponible : Media:2018-P18-TestLeds.ino.zip

Voici le montage sur plaque d'essai pour allumer 8 LEDs alternativement en utilisant 4 sorties (2 LEDs par sortie). Et ça marche.


Semaine 3

Pour réaliser la carte électronique principale nous utilisons le logiciel Fritzing.

Ce logiciel ne possède pas d'empreinte pour le TLC5947. Nous devons la créer nous même.

Nous avons étudié la façon pour créer de nouvelles empreintes.

D'abord, nous avons trouvé un composant avec une empreinte de type HTSSOP 28 broches que nous pouvons transformer en 32 broches. Nous avons utilisé inkscape pour dessiner les différentes vues et puis nous importons les dessins dans Fritzing.

Pour cette séance nous nous sommes occupés de la vue "plaque d'essai" et de la vue "schématique".


  • schéma de la vue "breadboard" :
    2018 P18 TLC5947 breadboard.png
  • schéma de la vue "schematic" :
    2018 P18 TLC5947 schematic.png

Semaine 4

Nous avons continué à réaliser l'empreinte pour un TLC5947. Voici le dessin pour la vue PCB :
2018 P18 TLC5947 PCB.png

Le fichier du nouveau composant est disponible : Media:2018_P18_TLC5947_v3.zip.

Pour l'utiliser il faut renommer le fichier en .fzpz et l'importer dans la fenêtre "composants" de Fritzing.

Nous avons commencé à concevoir la carte principale avec cette nouvelle empreinte.

Voila la vue "plaque d'essai" de notre circuit principal :

2018 P18 CP breadboard.png

Le circuit avec les composants placés mais non routé :

2018 P18 PCB CP nonroute.png

Semaine 5

Le schématique du circuit principal :

2018 P18 CP schematic.png

Et le circuit finalement routé :

2018 P18 CP PCB.png

Le fichier Fritzing du circuit principal est disponible : Media:2018 P18 CP.zip.

Après la conception et la validation des règles (écart entre les pistes, etc) nous avons demandé la fabrication de la carte. La carte a été réalisée par une entreprise extérieure pour obtenir un rendu propre avec un vernis. La couleur du vernis des différentes cartes a été choisie pour obtenir un résultat esthétique.

Une fois la carte réceptionnée, nous avons soudé les composants sur la carte. Plusieurs séances ont été nécessaires car nous avons soudé les composants des grandes parties de la carte en testant ces parties avant de continuer : partie micro-contrôleur (Atmega328p), partie alimentation, partie interface USB (FTDI), pilotes de LEDS (TLC5947). Il n’est pas facile de souder les composants comme l’Atmega328p et les TLC5947 qui on un grand nombre de pattes très fines.

Semaine 6

Les dessins pour la découpeuse laser (Media:2018_P18_Mandala_Decoupe.svg, Media:2018_P18_Mandala_Decoupe_Anneau.svg) sont représentés ci-dessous.

2018 P18 Mandala Decoupe.png
2018 P18 Mandala Decoupe Anneau.png


Circuit porte 2 LEDs : 2018 P18 Porte2LEDs PCB.png

Circuit porte 4 LEDs : 2018 P18 Porte4LEDs PCB.png

Circuit lune porte 4 LEDs : 2018 P18 Lune.png


Les fichiers Fritzing sont disponibles : Media:2018_P18_Porte2LEDs.zip Media:2018 P18 Porte4LEDs.zip Media:2018_P18_Lune.zip

Semaine 7

Cette semaine, nous avons terminé tous les dessins sur l'ordinateur, cette semaine nous avons imprimé notre dessins sur la blaque de bois.

Bois.jpg

Et nous avons soudé des LEDs CMS aux PCBs.

LesPCB.jpg

Semaine 8

Nous avons continué le travail de soudage et vérifié le bon soudage avec un multimètre.

Bois1.jpg

Démonstration du bon fonctionnement du circuit principal.

Media:2018_P18_demo_TLC5947.mp4


Semaine 9

Nous avons essayé de tester le capteur ZX DISTANCE AND GESTURE SENSOR. Dans des circonstances normales, la poignée est placée 10 à 25 cm au-dessus du capteur, et nous pouvons observer les informations de position renvoyées. Z (hauteur au-dessus du capteur) et X (position d'un côté à l'autre).


ZX tset.jpg


Pour la décoration du mandala, nous voulions peindre le mandala dans un style bouddhiste. Au début, nous avons utilisé de la gouache. Mais la peinture avait tendance à baver sur le contre-plaqué. Pour améliorer notre mandala, nous avons acheté des paillettes or pour couvrir la gouache jaune. Nous avons aussi acheté des perles pour décorer les bords. Nous avons utilisé de la colle liquide pour coller les perles sur le bois. Vous pouvez voir le résultat sur la photo ci-dessous. Nous avons passé 2 semaines pour réaliser ce travail.

Mandala decoration.jpg

Semaine 10

Pour connecter les cartes portes LEDs, le contrôleur de gestes “ZX gesture” avec la carte principale, nous avons passé des câbles au verso du mandala avec les trous que nous avions déjà percés et nous les avons soudé.

Connection cables.jpg

Semaine 11 et 12

Il reste une petite partie du travail au cours des deux semaines précédentes, et nous allons le terminer.

Et support du mandala est réalisé par une imprimante 3D en utilisant le logiciel Freecad pour la conception. Le support permet de fixer les piles et de supporter le mandala. La première version a été modifiée pour ajouter les fentes pour le circuit de détection de gestes “ZX gesture” et ses câbles.

Support mandala2.jpg
Support-mandala3.jpg


Le support du Mandala est disponible: Media:Support_mandala.zip

Semaine 13

pour trouver la disposition des porte-LEDs par rapport aux sorties des pilotes de LED, nous avons écrit un programme qui active les sorties une à une dans l'ordre de la première sortie jusqu’à la dernière. Voici un extrait du code.

#define	NB_DRIVERS		3
#define	DLED_CHANNELS	24
#define	NB_GROUPES		(NB_DRIVERS*DLED_CHANNELS)
unsigned int groupes[NB_GROUPES];
int n=0;
while(1){
 printf("Channel #%d on\n",n);
 for(int i=0;i<NB_DRIVERS*DLED_CHANNELS;i++) groupes[i]=(i==n)?MAX_VALEUR:0;
 set_LED_Drivers(groupes,NB_DRIVERS);
 n++; if(n>=NB_DRIVERS*DLED_CHANNELS) n=0;
 _delay_ms(WAIT_DELAY);
 }


Et nous avons trouvé le position des LEDs.

LEDs Position.jpg


Le ZX gesture est capable de détecter trois mouvements : un geste vers le haut, vers la droite ou vers la gauche. Comme le capteur est utilisé verticalement le geste vers le haut est plutôt un geste d’éloignement. Le capteur est installé sur le bois du mandala. Ses broches CLM et DR sont connectées, respectivement, sur les ports PD3 et PD4 de l’ATMega328p. Nous utilisons le capteur pour contrôler la vitesse de l'animation du mandala et pour changer d’animation et la vitesse du changement. Lorsque le geste sur le coté droit est détecté (geste=2 sur la photo), le temps d’attente dans les animations est diminué ce qui accélère la vitesse de l’animation. Lorsque le geste sur le coté gauche est détecté (geste=1 sur la photo), le temps d’attente dans les animations est augmenté ce qui diminue la vitesse de l’animation. Chaque fois qu'un geste d’éloginement est détecté (geste=3 sur la photo), l’animation change. Pour gérer le ZX Gesture nous utilisons une bibliothèque C de gestion du bus I2C, voici la fonction permettant de récupérer un registre du ZX Gesture (par exemple la position se récupère dans un de ces registres) :

int zx_getreg(int reg){
int ret;
i2c_start_wait(ZX_ADDR|I2C_WRITE);
i2c_write(reg);
i2c_rep_start(ZX_ADDR|I2C_READ);
ret=i2c_readNak();
i2c_stop();
return ret;
}
Gestecode.jpg

Semaine 14

Nous avons terminé le travail de programmation : trois animations sont programmées et le ZX Gesture est utilisé. Nous avons conçu trois animations.

Pour la première, les lumières sont allumées de l'intérieur vers l'extérieur. Media:type1.mp4

Pour la seconde, les portes-LEDs s'allument un à un dans le sens antihoraire et l'ordre du cercle intérieur vers le cercle extérieur; Media:type2.mp4

Pour la troisième, toutes les lumières sont allumées en même temps, leur luminosité varie. Media:type3.mp4

Nous allons montrer comment sont définies ces animations dans le code. La première animation est constituée de 6 sous-animations. Chacune fait varier la luminosité d’un groupe circulaire de portes-LEDs. L’augmentation de la luminosité se fait en 500ms, la diminution en 500ms et la sous-animation se met en pause pendant 2s. En lançant les sous-animations tous les 500ms, on obtient un effet de propagation du centre vers l’extérieur. Les structures définissant cette animations sont données juste aprés. Le tableau a1 comporte les 6 sous-animations commandées par les paramètres v1 à v6.

/* Animations1 */
variation_params v1={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
variation_params v2={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
variation_params v3={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=256};
variation_params v4={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
variation_params v5={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
variation_params v6={.deltac=500,.deltad=500,.deltap=2000,.min=0,.max=1024};
 animation a1[]={
 {0,60000,groupe1,&v1,variation_groupes},
 {500,60000,groupe2,&v2,variation_groupes},
 {1000,60000,groupe3,&v3,variation_groupes},
 {1500,60000,groupe4,&v4,variation_groupes},
 {2000,60000,groupe5,&v5,variation_groupes},
 {2500,60000,groupe6,&v6,variation_groupes},
 {-1,-1,NULL,NULL,NULL}
 };

Pour la troisième animation, nous voulions que toutes les LEDs soient allumées en même temps. Nous avons mis le temps de croissance à 500, le temps de décroissance à 500 sans pause. Comme les LEDs bleues sont toujours plus lumineuses que les autres LEDs, on les limite à une luminosité de 256. Le maximum de luminosité pour les autres LEDs est de 1024 (pour un maximum de 4096). Voici les paramètres des sous-animations de cette troisième animation.

variation_params v21={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
variation_params v22={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
variation_params v23={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=256};
variation_params v24={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
variation_params v25={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};
variation_params v26={.deltac=500,.deltad=500,.deltap=0,.min=0,.max=1024};

Nous avons mis 0 ms pour le temps de départ de l’animation et 60000 ms pour le temps d’arrêt de l’animation.

animation a3[]={
 {0,60000,groupe1,&v21,variation_groupes}, 
 {0,60000,groupe2,&v22,variation_groupes},
 {0,60000,groupe3,&v23,variation_groupes},
 {0,60000,groupe4,&v24,variation_groupes},
 {0,60000,groupe5,&v25,variation_groupes},
 {0,60000,groupe6,&v26,variation_groupes},
 {-1,-1,NULL,NULL,NULL}
 };

Ces structures sont données en paramètre d’une fonction qui implante l’animation.

Documents Rendus

Media:Rapportp18.odt

Media:led_code.zip