IMA4 2017/2018 P18 : Différence entre versions
(→Semaine 13) |
(→Semaine 13) |
||
Ligne 401 : | Ligne 401 : | ||
TLC5947 LEDs driver | TLC5947 LEDs driver | ||
− | |||
Include files | Include files | ||
− | + | #include <avr/io.h> | |
− | #include <avr/io.h> | + | #include "tlc5947.h" |
− | + | // Global variables | |
− | #include "tlc5947.h" | + | // Functions |
− | + | void init_LED_Drivers(int nb){ | |
− | // Global variables | + | // LED drivers I/O as outputs |
− | + | DDR_DLED |= (1<<PIN_DLED_CLOCK) | (1<<PIN_DLED_DATA) | (1<<PIN_DLED_LATCH); | |
− | // Functions | + | // Set LATCH output low |
− | |||
− | void init_LED_Drivers(int nb){ | ||
− | |||
− | DDR_DLED |= (1<<PIN_DLED_CLOCK) | (1<<PIN_DLED_DATA) | (1<<PIN_DLED_LATCH); | ||
− | // Set LATCH output low | ||
PORT_DLED &= ~(1<<PIN_DLED_LATCH); | PORT_DLED &= ~(1<<PIN_DLED_LATCH); | ||
} | } | ||
Ligne 421 : | Ligne 415 : | ||
void set_LED_Drivers(unsigned int pwm[],int nb){ | void set_LED_Drivers(unsigned int pwm[],int nb){ | ||
int c,b; | int c,b; | ||
− | // Set LATCH output low | + | // Set LATCH output low |
PORT_DLED &= ~(1<<PIN_DLED_LATCH); | PORT_DLED &= ~(1<<PIN_DLED_LATCH); | ||
// 24 channels per TLC5947 | // 24 channels per TLC5947 |
Version du 16 mai 2018 à 06:25
Sommaire
Présentation générale
Description
Le mot mandala vient d‘une très ancienne langue indienne.Il signifiant:
- disque, cercle, sphère ;
- toute figure géométrique apparentée au cercle ;
- structure, forme d'organisation ;
- 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
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
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 :
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.
- une peinture de type mandala sur une planche de contre-plaqué réalisée à la gouache ;
- une carte électronique centrale à base de micro-contrôleur utilisant des pilotes de LEDs ;
- 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 ;
- les boitiers de piles sont aussi à fixer à l'arrière du mandala ;
- 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 :
- 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 ;
- choisir un dispositif pour contrôleur les LEDs (registre à décalage ou pilote de LEDs) ;
- concevoir le circuit à base de micro-contrôleur pour contrôler les très nombreuses LEDs ;
- réaliser (souder) la carte électronique et la tester ;
- concevoir les cartes électroniques porte LEDs et les réaliser ;
- 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.
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.
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" :
- schéma de la vue "schematic" :
Semaine 4
Nous avons continué à réaliser l'empreinte pour un TLC5947. Voici le dessin pour la vue PCB :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 :
Le circuit avec les composants placés mais non routé :
Semaine 5
Le schématique du circuit principal :
Et le circuit finalement routé :
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.
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.
Et nous avons soudé des LEDs CMS aux PCBs.
Semaine 8
Nous avons continué le travail de soudage et vérifié le bon soudage avec un multimètre.
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).
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.
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é.
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.
Le support du Mandala est disponible: Media:Support_mandala.zip
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. Voici un extrait du code.
TLC5947 LEDs driver Include files #include <avr/io.h> #include "tlc5947.h" // Global variables // Functions void init_LED_Drivers(int nb){ // LED drivers I/O as outputs 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);
}
Et nous avons trouvé le position des LEDs.
Un capteur de distance et de mouvement ZX est installé sur le bois du mandala.
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
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.
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.
Voila un extrait du code pour réaliser ces 3 animation.
- include <stdio.h>
- include "time.h"
- include "tlc5947.h"
- include "zxgesture.h"
- include "animations.h"
// Global variables
/* Values for each LED sets */ 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}, {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} };
/* Animation2 */ variation_params v_tous={.deltac=100,.deltad=100,.deltap=0,.min=0,.max=255}; animation a2[]={
{0,40000,tous,&v_tous,variation_groupe}, {-1,-1,NULL,NULL,NULL} };
/* Animation3 */ 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}; 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} };
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){ printf("Play all\n"); animation **a=anims; while(*a!=NULL) animation_play(*a++); }