Dé électronique communiquant

De Wiki d'activités IMA


Vidéo HD


Cahier des charges

Présentation du projet

Contexte

Dans une époque où la technologie concerne le mode de vie de presque tout le monde, la plupart des gens ont tendance à se tourner vers les nouvelles technologies (smartphone, ordinateur) pour se divertir, et ainsi délaisser les anciens jeux de société. Afin de faire revivre ce genre de jeu, nous avons décidé de revisiter un pilier du jeu de société : le dé à jouer.

Objectif du Projet

L'objectif de ce projet est de réaliser un dé à jouer programmable du même type que les futurocubes.

Idées de fonctionnalités

Voici quelques idées d'applications qu'on pourrait mettre en place :

  • Dé à jouer classique : chiffre aléatoire de 1 à 6
  • Jeu du morpion (Tic Tac Toe)
  • SNAKE fonctionnant avec l'accéléromètre
  • Eclairage "d'ambiance" avec variation aléatoire des couleurs
  • Modélisation d'un Rubik's Cube 3x3
  • Jeu de mémoire couleur/son (comme le jeu Simon)

Choix techniques : matériel - utilité

Nous allons nous baser sur :

  • un microcontrôleur de type MBED (ARM Cortex M3) [fourni le 2/2/2015] : Cerveau du dé - Sons/bruitages

La documentation est disponible ici. Les programmes implémentés seront codés en C/C++.

Ensuite, les composants suivants doivent être intégrés :

  • LED RGB (54 LEDs) : Elles seront multiplexés à l'aide de transistors. [9 LED Rouges/Jaunes fournies le 4/2/2015] 54 x LED [100 LEDs RGB commandées chez Farnell le 18/2/2015]
  • 18 transistors NPN [3 fournis le 4/2/2015]
  • 18 x Transistor [20 BC548BRL1G commandées chez Farnell fournies le 11/3/2015]
  • 18 x Transistor CMS [100 BC848B-7-F commandées chez Farnell le 18/2/2015]
  • Résistances : à voir avec les encadrants et en fonction des tests (Savoir si on doit en placer une à l'anode ou une à chaque cathode)
  • Accéléromètre : Orientation dans l'espace et réveil de l'appareil après la détection d'un mouvement. [ fourni le 11/2/2015]
  • Alimentation : Rechargeable via usb.
  • 6 faces "tactiles" via le centre de chaque face : Possible par résistances capacitives, touches tactiles (SparkFun Touch Shield), boutons poussoirs (Tests à réaliser pour déterminer la meilleure méthode).

Étapes du projet

Étape 1

  • Choix des jeux et fonctionnalités à intégrer au dé en tenant compte des contraintes matérielles
  • Aperçu du matériel disponible et nécessaire, puis choix des composants
  • Élaboration du schéma électronique à adopter
  • Découverte de la plateforme MBED

Étape 2

Cette étape occupera la plus grande partie de la durée du projet.

  • Réalisation du code des fonctionnalités à intégrer sur la plateforme MBED
  • Réalisation des circuits électroniques nécessaires via Altium Designer
  • Début du montage du cube

Étape 3

  • Montage final du cube
  • Réalisation de programmes optionnels s'il reste du temps (fonctionnalités compliquées à implémenter ou pensées plus tard dans le projet)
  • Tests des fonctionnalités sur le matériel

Avancée du projet

Semaine 1 (du 26/01/2015 au 01/02/2015)

Schéma multiplexage LED

Nous avons surtout porté nos recherches sur du matériel électronique spécifique, notamment pour l'aspect "tactile" de notre cube. En effet, il est possible d'utiliser les techniques suivantes :

  • Résistance et capacité : On utilise une simple résistance et un métal conducteur. En touchant celui-ci avec notre doigt, on le transforme en capacité. On peut voir le principe ici.
  • Résistance capteur de pression : Prête à être utilisée mais assez chère. Il y a bien d'autres alternatives.
  • Touch Shield : A voir avec l'intégration des LED.
  • Boutons réalisés sur le principe du Button Pad à raison d'un par face : Dans le pire des cas ...

Puis nous nous sommes intéressés à la connexion des LEDs. Elles seront au nombre de 54, soit 9 par face, et en plus, ce sera des LED RGB. Nous avons trouvé pour cela une solution de multiplexage à l'aide de transistors NPN. Voici un petit schéma du branchement possible sur une face avec 9 LEDs RGB : Il sera possible de le porter à plus grande échelle par la suite.


Voici le principe de fonctionnement : On alimente une colonne de LED par l'anode commune. On détermine ensuite laquelle sera reliée à la masse et s'allumera donc. Pour cela on combine les bases et les collecteurs. Il faut activer la base (mettre à 1) correspondant à la colonne de la LED à allumer, et mettre à la masse (mettre à 0) la ligne du collecteur correspondant. Ainsi, une seule LED sera reliée à la masse.


L'objectif pour la semaine prochaine sera de tester les solutions du "tactile" et le branchement des LEDs.

Nous avons également discuté avec nos encadrants sur le matériel et ses limites, c'est-à-dire le tactile, la connexion des LEDs, l’accéléromètre (disponible à Polytech), le MBED, les sons (réalisables avec le MBED) et le côté alimentation.

Semaine 2 (du 02/02/2015 au 08/02/2015)

Lors de cette semaine, nous avons surtout porté nos recherches sur la méthode de multiplexage des LEDs. Faute d'avoir des LEDs RGB, nous avons testé le multiplexage selon le schéma précédent avec 3 LEDs simples, soit une LED RGB. Nous avons réalisé le test d'allumer 1 seule des LEDs (pour avoir une couleur) puis 2 (mélange de couleurs).

Test 1 multiplexage d'une LED RGB (avec 3 LEDs)
Test 2 multiplexage d'une LED RGB (avec 3 LEDs)


Nous avons ensuite réalisé le branchement afin d'obtenir une ligne de LEDs RGB selon le schéma précédant, soient 3 fois 3 LEDs simples. On peut voir ci-dessous le branchement et le résultat du test :

Branchement d'une ligne de 3 LEDs RGB (9 LEDs basiques)
Résultat du multiplexage d'une ligne de LEDs



L'objectif pour la semaine prochaine sera de tester le multiplexage des LEDs sur une face, et d'aborder le côté "tactile" du projet.


Semaine 3 (du 09/02/2015 au 15/02/2015)

Suite aux résultats du multiplexage des LEDs, nous avons commencé la réalisation du codage de l'allumage de celles-ci selon le schéma complet suivant :

Parallèlement, nous avons porté nos recherches sur l'accéléromètre ADXL335. Nous avons effectué quelques tests pour déterminer le fonctionnement exact. Nous avons récupéré les valeurs de celui-ci sur les broches analogiques du MBED et à l'aide de la fonction read() qui renvoie logiquement une valeur entre 0.0 et 1.0. Nous avons codé le petit programme de test suivant pour tester selon l'axe Y:

Schéma complet du multiplexage

   DigitalOut myled1(LED1);
   DigitalOut myled2(LED2);
   DigitalOut myled3(LED3);
   DigitalOut myled4(LED4);
   DigitalOut verif (p5);
   DigitalOut verif2 (p30);
   AnalogIn x(p15);   // 0.4<X<0.6
   AnalogIn y(p16);   // 0.4<Y<0.6
   AnalogIn z(p17);   // 0.4<Z<0.6
   int main() {
       while(1) {
           wait(0.2);
           float m1 = x.read();
           float m2 = y.read();
           float m3 = z.read();
       
           if (m2>0.5) myled1=1; else myled1=0;
           if (m2>0.52) myled2=1; else myled2=0;
           if (m2>0.54) myled3=1; else myled3=0;
           if (m2>0.56) myled4=1; else myled4=0;
           if (m2>0.58) verif=1; else verif=0;
           if (m2>0.6) verif2=1; else verif2=0;}}


On peut voir le résultat ici :

Fichier:Testaccel.avi

Semaine 4 (du 16/02/2015 au 22/02/2015)

Durant cette semaine, nous avons observé le comportement de l'accéléromètre via l'utilitaire Minicom et la liaison série entre le microcontrôleur et le PC. Nous avons ainsi vérifié le fonctionnement de l'accéléromètre selon chaque axe, et ainsi confirmer les pistes observées la semaine dernière. Nous avons ainsi pu réfléchir à une solution tactile pour notre dé.

Après nos recherches sur internet, nous avons pu voir que peu de solutions sont disponibles pour notre MBED.

L'objectif pour la semaine prochaine sera ainsi d'approfondir nos recherches sur cette solution tactile.

Semaine 5 (du 23/02/2015 au 01/03/2015)

Pendant cette semaine, nous avons poursuivi nos recherches sur la partie tactile de notre cube. Nous avons notamment réfléchi à 2 solutions :

  • L'utilisation du SparkFun Touch Shield, que nous avons pu nous procurer. Néanmoins, ce pad est spécialement conçu pour être connecté sur Arduino Uno. Il n'est donc pas évident de l'adapter à notre MBED.
  • La fabrication de touches tactiles "Do It Yourself" sur ce modèle. Néanmoins, le code de cette solution est fait pour fonctionner sous Arduino, il faudrait donc réfléchir à l'adapter à notre MBED.

C'est pourquoi nous avons décidé d'emprunter une carte Arduino Uno, afin de tester ces deux solutions, et envisager de les porter sur notre MBED.

Le code des touches tactiles "Do it Yourself" a parfaitement marché sur l'arduino. Nous avons étudié la structure de plus près. A l'aide des fonctions disponibles sur MBED, nous avons plus ou moins suivi l'idée de ce code mais en le transcrivant pour le MBED. Après plusieurs versions testées, rien ne fonctionnait vraiment sauf la suivante :


  include "mbed.h"
  DigitalOut led(LED1);
  DigitalOut boom (p6);
  DigitalInOut button (p21);
  Serial pc(USBTX, USBRX);
  //Seuil de détection 
  const uint16_t THRESHOLD = 50;
  uint8_t cycles;
  void touch_measure(){
    // Décharge la capacité en contact avec la broche 
    button.write(0);         // Place la broche à LOW
    button.output();         // Place la broche en sortie
    wait(1); // Attend pour être sur que la capacité est déchargé
    // Place la broche en entrée, sans résistance de pull-up ! 
    // (La résistance de >1M ohms externe servira de résistance de pull-up) 
    button.mode(PullNone);
    // Mesure le nombre de cycles CPU requis avant que la broche ne commute 
    for(cycles = 0; cycles < 256; ++cycles)
    {
      if (button.read()) break; // Si la broche a commuter on quitte la boucle
    }
    // Re-décharge la capacité en contact avec la broche
    // afin d'éviter tout parasitages d'une autre mesure sur une autre broche.
    // Dans le cas contraire il serait impossible de manipuler plus d'une touche "tactile" 
    button.write(0);
    button.output();
    // Retourne le résultat 
    //return cycles;}
  int main() {
      // Test si la "touche" a été appuyé ou non 
      while (1) {
          if(cycles > THRESHOLD)
          led = 1;
      else
          led = 0;
      wait(0.5);
     //pc.printf("%d  ",cycles);
      touch_measure(); }  }
  

En branchant directement le fil "à toucher" sur la masse, la led s'allumait (ce qui devait se passer quand on touche le fil). Cependant, cela ne marchait pas à tous les coups. Voici une vidéo qui montre ce qui se passe : Fichier:Test tactile.avi

Nous avons donc demandé à M. Vantroys par rapport au code à utiliser et pourquoi cela ne marchait pas en transcrivant simplement le code sur MBED. En fait, les fonctions utilisées dans le code du tutoriel étaient du langage très bas niveau pour l'Arduino. En effet, cela permet de toucher directement les ports du microprocesseur et donc d'avoir un temps d’exécution très court. Or, en utilisant les fonctions "de base" du MBED et ne sachant pas le code de celle-ci, on peut déduire que le temps d’exécution n'était pas aussi rapide et empêchait donc le bon fonctionnement de comptage des cycles et évaluation du temps de charge/décharge de la capacité.


L'objectif pour la prochaine séance sera de se décider sur la solution tactile de notre cube, ou sur une alternative à adopter en cherchant le code bas niveau du MBED.

Semaine 6 (du 09/03/2015 au 15/03/2015)

Lors de cette sixième semaine, nous avons continué à travailler sur la solution tactile à adopter, et nous avons spécialement étudié la manipulation des ports du microprocesseur du MBED, afin de pouvoir étudier l'utilisation de touches tactiles "Do It Yourself". Après de nombreuses recherches et quelques essais infructueux, nous nous sommes rendus compte que cette solution aurait été trop compliqué et encombrante à coder. Nous étions prêts à nous orienter vers une solution alternative. Nous avons aussi rendu la carte Arduino Uno qui nous avait été fournie.

Aussi, notre commande de transistors BC548 est arrivée cette semaine, nous avons pu nous les procurer, en vue de l'élaboration de nos PCB.

L'objectif pour la semaine prochaine sera de trouver la solution alternative à adopter pour l'interaction entre l'utilisateur et le dé.

Semaine 7 (du 16/03/2015 au 22/03/2015)

Pendant cette semaine, une solution concernant l'interaction Utilisateur-Dé nous est arrivée : nous avons pu nous procurer un Adafruit MPR121 Breakout Board à 12 touches, et un autre à 8 touches. Pour sa simplicité de branchement, nous avons décidé d'utiliser celui à 12 touches. Il nous permettra de créer 6 touches tactiles, une pour chaque face. Nous connecterons cette board via les ports I²C du microcontrôleur.

De plus, M. Boé nous a suggéré d'utiliser un accéléromètre permettant d'influer sur la consommation énergétique du microprocesseur. Il nous a ainsi fourni l'accéléromètre ADXL345, pouvant communiquer avec le microprocesseur via deux protocoles : SPI ou I²C. Nous avons tout d'abord décidé d'utiliser le protocole I²C, mais le programme-test ne fonctionnait pas comme on le voulait. L'impression des valeurs de l'accéléromètre devait se faire via une liaison série vers le PC, mais rien ne se passait à l'écran.

L'objectif pour la semaine prochaine sera de terminer la configuration de l'accéléromètre, et de configurer la board tactile.

Semaine 8 (du 23/03/2015 au 29/03/2015)

Nous avons continué la configuration de l'accéléromètre, en utilisant des bibliothèques obtenues sur le site de développement MBED. N'ayant pas réussi à résoudre le problème de la communication I²C, nous avons décidé d'utiliser les ports SPI pour obtenir les valeurs, avec une bibliothèque paramétrant l'utilisation des ports SPI pour l'accéléromètre. Le code suivant nous a permis d'afficher les valeurs reçues sur les ports SPI via la liaison série :

   #include "ADXL345.h"
   ADXL345 accelerometer(p5, p6, p7, p8);
   Serial pc(USBTX, USBRX);
   int main() {
       int readings[3] = {0, 0, 0};
       pc.printf("Starting ADXL345 test...\n");
       pc.printf("Device ID is: 0x%02x\n", accelerometer.getDevId());
       //Go into standby mode to configure the device.
       accelerometer.setPowerControl(0x00);
       //Full resolution, +/-16g, 4mg/LSB.
       accelerometer.setDataFormatControl(0x0B);
       //3.2kHz data rate.
       accelerometer.setDataRate(ADXL345_3200HZ);
       //Measurement mode.
       accelerometer.setPowerControl(0x08);
       while (1) {
           wait(0.1);
           accelerometer.getOutput(readings);
           //13-bit, sign extended values.
           pc.printf("%i, %i, %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
       }
   }

Nous avons aussi configuré la board tactile. Elle communique avec le microcontrôleur par les ports I²C. Avec une bibliothèque obtenue sur le site de développement MBED, nous avons réalisé un programme-test qui permet d'allumer les LEDs du microcontrôleur en fonction des touches actives ou non. Voici l'algorithme général de ce programme, exécuté en boucle :

//led1, led2, led3 et led4 initialement à 0
Si (touche1 == 1) alors led4=1;
Si (touche2 == 1) alors led3=1;
Si (touche3 == 1) alors {led3=1; led4=1;}
Si (touche4 == 1) alors led2=1;
Si (touche5 == 1) alors {led2=1; led4=1;}
Si (touche6 == 1) alors {led2=1; led3=1;}
Si (touche7 == 1) alors {led2=1; led3=1; led4=1;}
Si (touche8 == 1) alors led1=1;
Si (touche9 == 1) alors {led1=1; led4=1;}
Si (touche10 == 1) alors {led1=1; led3=1;}
Si (touche11 == 1) alors {led1=1; led3=1; led4=1;}
Si (touche12 == 1) alors {led1=1; led2=1;}

L'objectif pour la semaine prochaine sera de commencer l'élaboration des cartes PCB, et de paramétrer l'utilisation d'un élément piézoélectrique pour l'émission de sons.

Semaine 9 (du 30/03/2015 au 05/04/2015)

Lors de cette semaine, nous avons commencé à créer une carte PCB avec le logiciel Altium Designer. Nous avons tout d'abord créé la carte permettant le multiplexage des LEDs. Nous avons placé sur cette carte 18 transistors BC548, 18 résistances, ainsi qu'un décodeur 3 vers 8 74LS138, permettant d'avoir une sortie à l'état bas et les 7 autres à l'état haut, selon cette datasheet. Les pistes se feront des 2 côtés de la carte. A l'issue de cette semaine, nous avons pu envoyer notre modèle au service électronique pour élaboration.

Schématic multiplexage LED
multiplexage LED Face 1
multiplexage LED Face 2


Parallèlement, nous avons travaillé sur l'émission d'une gamme de sons par une pièce piézoélectrique. Sur le site de développement MBED, nous avons pu trouver une bibliothèque permettant l'élaboration d'une note et de sa durée, et par extension l'élaboration d'une mélodie.

   #include "mbed.h"
   #include <Sound.h>
   Sound sound(p21, p10);
   const Sound::sound_t WESTMINSTER[] =     {
       //   hanon siji 0:b(flat)   1:tujo  2:#(sharp)
       //   |  C1 - B9 kan deno onkai(Gx ha 9x ni okikae te siji)  0xFF=end data
       //   |  |   time (1/1[ms]/count)   
       //   |  |   |    envelope(yoin) (1/1 [ms]/count)
       //   |  |   |    |
           {1,0xC5,300,500},
           {1,0xD5,300,500},
           {1,0xE5,300,500},
           {1,0xF5,300,500},
           {1,0x85,300,500},
           {1,0x95,300,500},
           {1,0xA5,300,500},
           {1,0xB5,300,500},
           {1,0x75,300,500},
           {1,0x65,300,500},
           {1,0x55,300,500},
           {1,0xFF,1000,0},    // end
   };
   int main() {
        //---------------------
        // enso data no settei
        //---------------------
        // sound.sound_enso("/local/enso.txt");     // mbed local file data "enso.txt" load (sita ni data no rei wo oite oku)
       sound.sound_enso((Sound::sound_t*)WESTMINSTER);  
       //---------------------------------------------------
       // output tone
       //---------------------------------------------------
       // tone1 
       Sound::sound_t oto = {1,0x95,200,100};
       sound.sound_sound(oto);
       while(sound.sound_sound() == true){}       
       // tone2
       oto.hanon = 1; oto.onkai = 0xA5; oto.time = 2000; oto.envelope = 1000;
       sound.sound_sound(oto);
       while(sound.sound_sound() == true){}
       //---------------
       // output melody
       //--------------
       sound.sound_enso(true);
       while(1) {
       }
   }

Nous travaillerons ultérieurement sur la sélection de notes à adopter.

L'objectif pour la semaine prochaine sera de continuer l'élaboration des cartes électroniques, ainsi de commencer le développement des programmes finaux.

Semaine 10 (du 06/04/2015 au 12/04/2015)

Lors de cette semaine, nous avons continué l'élaboration des circuits électroniques. Nous avons commencé à concevoir les faces, soit les cartes contenant 9 LEDs RGB. Nous avons eu des LEDs CMS, nous avons donc dû créer ces composants sur Altium Designer.

Parallèlement nous avons commencé à travailler sur les programmes finaux. Nous avons développé un programme permettant d'allumer une LED une par une, selon la couleur voulue, et selon le schéma suivant :


   #include "mbed.h"
   #include "Random.h"
   BusOut myled(LED4,LED3,LED2,LED1);
   DigitalOut anode[9]={p12,p13,p14,p15,p16,p17,p18,p19,p20};
   BusOut base_couleur(p30,p29,p28);
   BusOut collecteur(p24,p23,p22);
   void allume_LED(int led, int face, char couleur){
       for (int i=0;i<9;i++) anode[i]=0;
       // sélection anode ("face")
       if ((led == 1)||(led == 4)||(led == 7)){
           if ((face == 1) || (face == 2)) anode[0]=1;
           else if ((face == 3) || (face == 4)) anode[3] = 1;
           else if ((face == 5) || (face == 6)) anode[6] = 1;
       }
       else if ((led == 2)||(led == 5)||(led == 8)){
           if ((face == 1) || (face == 2)) anode[1] = 1;
           else if ((face == 3) || (face == 4)) anode[4] = 1;
           else if ((face == 5) || (face == 6)) anode[7] = 1;
       }
       else if ((led == 3)||(led == 6)||(led == 9)){
           if ((face == 1) || (face == 2)) anode[2] = 1;
           else if ((face == 3) || (face == 4)) anode[5] = 1;
           else if ((face == 5) || (face == 6)) anode[8] = 1;
       }
       // sélection collecteur ("ligne" de LEDs)
       if ((face == 1)||(face == 3)||(face == 5)){
           if ((led > 0) && (led < 4)) collecteur.write(0);
           else if ((led > 3) && (led < 7)) collecteur.write(1);
           else if ((led > 6) && (led < 10)) collecteur.write(2);
       }
       else if ((face == 2)||(face == 4)||(face == 6)){
           if ((led > 0) && (led < 4)) collecteur.write(3);
           else if ((led > 3) && (led < 7)) collecteur.write(4);
           else if ((led > 6) && (led < 10)) collecteur.write(5);
       }
       //sélection couleur (base)
       if (couleur == 'r') base_couleur.write(4);
       else if (couleur == 'g') base_couleur.write(2);
       else if (couleur == 'b') base_couleur.write(1);
   }

A partir de ce programme, nous avons conçu une fonction affichant sur une face un chiffre selon le principe d'un dé. Chaque LED sera allumée une par une, mais avec la fréquence de travail très élevée du microprocesseur (environ 100 MHz), notre œil aura l'impression qu'elles sont allumées en même temps. La fonction prend comme paramètre le chiffre affiché, ainsi que le temps d'affichage en secondes :

   void affiche_de(int chiffre, float time){
   Timer t;
   t.start();
   while (t.read() <= time){
       if (chiffre == 1) allume_LED(5,1,'r');
       else if (chiffre == 2) {
           allume_LED(1,1,'r');
           allume_LED(9,1,'r');
       }
       else if (chiffre == 3) {
           allume_LED(1,1,'b');
           allume_LED(5,1,'b');
           allume_LED(9,1,'b');
       }
       else if (chiffre == 4) {
           allume_LED(1,1,'b');
           allume_LED(3,1,'b');
           allume_LED(7,1,'b');
           allume_LED(9,1,'b');
       }
       else if (chiffre == 5) {
           allume_LED(1,1,'g');
           allume_LED(3,1,'g');
           allume_LED(5,1,'g');
           allume_LED(7,1,'g');
           allume_LED(9,1,'g');
       }
       else if (chiffre == 6) {
           allume_LED(1,1,'g');
           allume_LED(3,1,'g');
           allume_LED(4,1,'g');
           allume_LED(6,1,'g');
           allume_LED(7,1,'g');
           allume_LED(9,1,'g');
       }
   }
   t.stop();
}

Nous avons aussi paramétré un générateur d'entiers aléatoires compris entre 1 et 6. A partir d'une bibliothèque obtenue sur le site de développement MBED, nous utilisons une classe "Random" permettant de générer ce chiffre. Ici, un exemple d'affichage d'un chiffre aléatoire :

int main() {
       Random r;
       int i;
       r.init();
       //génération d'un entier aléatoire entre 1 et 6
       uint8_t chiffre = r.getByte();
       chiffre = (chiffre % 6)+1;
       //petite simulation
       for(i=1;i<10;i++) {
           if (i<4) allume_LED(i,1,'r');
           else if ((i>3) && (i<7)) allume_LED(i,1,'b');
           else if (i>6) allume_LED(i,1,'g');
           wait_ms(200);
       }
       //affichage du chiffre aléatoire
       if ((chiffre > 0) && (chiffre < 7)) affiche_de(chiffre,15);
}

Enfin, nous avons pu récupérer la carte électronique de multiplexage élaborée précédemment. Sur cette carte, les pistes ont été dessinées des deux côtés. Nous avons aussi obtenu un boitier de piles fonctionnant via USB que nous utiliserons comme batterie, ainsi qu'une breadboard de petite taille permettant de fixer le microcontrôleur, l'accéléromètre et la board tactile dessus.

Carte électronique du multiplexage des LEDs, côté composants (recto)
Carte électronique du multiplexage des LEDs (verso)


L'objectif pour la semaine prochaine sera de continuer, voire de terminer l'élaboration des circuits électroniques des faces, de travailler sur la carte de multiplexage, ainsi que de continuer le développement des programmes finaux.

Semaine 11 (du 13/04/2015 au 19/04/2015)

multiplexage soudee
Schematic d'une face de LED
PCB face LED 1
PCB face LED 2


Lors de cette semaine, nous avons pu avoir une discussion avec M. Boé, afin de faire le point sur notre projet. Il nous a ainsi suggéré de revoir la taille de notre cube, afin de diminuer la taille des faces. La carte de multiplexage réalisée étant trop grande, nous avons décidé d'envisager une nouvelle carte de multiplexage plus petite, pour ainsi obtenir des faces de dimension 6x6 cm environ. Nous avons aussi décidé de créer un PCB spécialement pour des piles de type CR2032, et qu'un autre pour le MBED, l'accéléromètre et la board tactile, et ainsi abandonner l'idée de la breadboard. Nous avons ainsi revu l'élaboration de la face comportant nos LEDs RGB CMS.


Nous avons tout de même commencé à souder la carte de multiplexage des LEDs pour pouvoir tester les faces du cube :


Côté informatique, nous avons avancé dans notre code en créant une fonction réalisant une petite animation des LEDs, pour l'instant sur une seule face :

//une animation "d'ambiance", pour l'instant sur une seule face
void animations(float duree_anim){
   char couleurs[7] = {'w','j','r','p','b','g','t'};
   int coul_suiv,led_suiv,j;
   Timer t;
   //toutes les LEDs de la même couleur
   for(j=0;j<7;j++){
       t.start();
       while (t.read() <= (duree_anim/7)){
           for(int i=1;i<10;i++) allume_LED(i,1,couleurs[j]);
       }
       t.stop();
       t.reset();
       //changement de couleur progressif, une LED à la fois
       if (j==6) coul_suiv=0;
       else coul_suiv=j+1;
       led_suiv=1;
       t.start();
       while (led_suiv < 10){
           while (t.read() <= (1.5/9)){
               for(int k=1;k<=led_suiv;k++) allume_LED(k,1,couleurs[coul_suiv]);
               for(int i=led_suiv+1;i<10;i++) allume_LED(i,1,couleurs[j]);
           }
           led_suiv++;
       }
       t.stop();
       t.reset();
   }
   anim=true;
}

L'objectif pour la prochaine séance sera de créer une fonction de morpion, ainsi que de tester la carte de multiplexage sur une face.


D'autre part, nous avons réalisé le PCB d'une face de LED dont voici le schematic et le PCB:


Cependant, nous avons dû réaliser le schematic et les empreintes des LEDs dans une nouvelle librairie puisque le composant n'était pas encore réalisé dans les librairies d'Altium. Nous avons pour cela suivi le tutoriel de M. Boé : Composant créé sur Altium

Semaine 12 (du 20/04/2015 au 26/04/2015)

Durant cette semaine, nous avons continué notre code en commençant la programmation d'une fonction "morpion". Cette fonction est assez longue à concevoir, et sera complétée d'une autre fonction vérifiant la victoire au morpion. Voici la fonction "morpion" (la fonction "win" sera élaborée plus tard) :

void morpion(){
   led_eteinte();
   int grille[9]={0,0,0,0,0,0,0,0,0};
   int tour=0;
   char coul;
   bool ligne1=false, ligne2=false, ligne3=false, c1=false, c2=false, c3=false, d1=false, d2=false, gagne=false;
   //déroulement de la partie
   while ((!gagne)||(tour<9)){
       tour++;
       //"sélection" joueur : rouge pour joueur 1, vert pour joueur 2
       if ((tour%2)==1) coul='r';
       else coul='g';
       //sélection case via touches
       //milieu
       if (touche2==1) {
           if (grille[4]==0){
               allume_LED(5,2,coul);
               grille[4]=abs((tour%2)-2); //1 pour joueur 2, 2 pour joueur 1
           }
       }
       else if (touche1==1) {
           wait(1);
           //haut gauche
           if (touche5==1) { 
               if (grille[0]==0){
                   allume_LED(1,2,coul);
                   grille[0]=abs((tour%2)-2);
               }
           }
           //bas gauche
           else if (touche6==1){ 
               if (grille[6]==0){
                   allume_LED(7,2,coul);
                   grille[6]=abs((tour%2)-2);
               }
           }
           //gauche
           else {
               if (grille[3]==0){
                   allume_LED(4,2,coul);
                   grille[3]=abs((tour%2)-2);
               }
           }
       }
       else if (touche5==1) {
           wait(1);
           //haut gauche
           if (touche1==1) { 
               if (grille[0]==0){
                   allume_LED(1,2,coul);
                   grille[0]=abs((tour%2)-2);
               }
           }
           //haut droite
           else if (touche3==1){ 
               if (grille[2]==0){
                   allume_LED(3,2,coul);
                   grille[2]=abs((tour%2)-2);
               }
           }
           //haut
           else {
               if (grille[1]==0){
                   allume_LED(2,2,coul);
                   grille[1]=abs((tour%2)-2);
               }
           }
       }
       else if (touche3==1) {
           wait(1);
           //bas droite
           if (touche6==1) { 
               if (grille[8]==0){
                   allume_LED(9,2,coul);
                   grille[8]=abs((tour%2)-2);
               }
           }
           //haut droite
           else if (touche5==1) {
               if (grille[2]==0){
                   allume_LED(3,2,coul);
                   grille[2]=abs((tour%2)-2);
               }
           }
           //droite
           else {
               if (grille[5]==0){
                   allume_LED(6,2,coul);
                   grille[5]=abs((tour%2)-2);
               }
           }
       }
       else if (touche6==1) {
           wait(1);
           //bas gauche
           if (touche1==1) { 
               if (grille[6]==0){
                   allume_LED(7,2,coul);
                   grille[6]=abs((tour%2)-2);
               }
           }
           //bas droite
           else if (touche3==1){ 
               if (grille[8]==0){
                   allume_LED(9,2,coul);
                   grille[8]=abs((tour%2)-2);
               }
           }
           //bas
           else {
               if (grille[7]==0){
                   allume_LED(8,2,coul);
                   grille[7]=abs((tour%2)-2);
               }
           }
       }
       //allumage du reste de la grille
       for(int k=0;k<9;k++){
           if (grille[k]==1) allume_LED(k+1,2,'r');
           else if (grille[k]==2) allume_LED(k+1,2,'g');
       }
       //vérif ligne complétée
       gagne=win(grille,ligne1,ligne2,ligne3,c1,c2,c3,d1,d2);
   }
   Timer t;
   //vérif victoire joueur 1
   if(((tour%2)==1)&&(gagne)){
       t.start();
       while(t.read()<=5){
           for(int i=0;i<9;i++){
               allume_LED(i,2,'r');
           }
       }
       t.stop();
   }
   //vérif victoire joueur 2
   else if (((tour%2)==0)&&(gagne)){
       t.start();
       while(t.read()<=5){
           for(int i=0;i<9;i++){
               allume_LED(i,2,'g');
           }
       }
       t.stop();
   }
   //vérif match nul
   else if ((tour==9)&&(!gagne)){
       t.start();
       while(t.read()<=5){
           for(int i=0;i<9;i++){
               allume_LED(i,2,'b');
           }
       }
       t.stop();
   }
   morp=true;
}

A noter qu'ici, nous avons modélisé notre grille à l'aide d'un tableau à une dimension. Nous aurions très bien pu le faire aussi sous la forme d'une matrice à deux dimensions.

Côté électronique, nous avons récupéré le PCB d'une face. Nous avons alors procédé au soudage des 9 LEDs CMS composant notre face. Circuit d'une face Soudure de quelque LED et test 1 Soudure de quelque LED et test 2 Face totalement soudee

Nous avons procédé aux tests d'allumage et de multiplexage avec le branchement suivant. Les LEDS se sont bien allumées comme nous le voulions :

Branchement test de la face de LED Test réussi

L'objectif pour les 2 semaines restantes sera de pouvoir au moins présenter un prototype de notre cube montrant son fonctionnement global.

Semaine 13 (du 27/04/2015 au 03/05/2015)

Côté informatique, nous avons continué notre code en intégrant à notre programme final les différentes bibliothèques nécessaires : l'accéléromètre (ADXL345.h), la board tactile (MPR121.h), ainsi que pour le son de notre pièce piézoélectrique (Sound.h). Pour l'émission de ce son, nous avons repris la fonction d'émission d'une mélodie détaillée plus haut, et nous l'avons adaptée pour n'émettre qu'une seule note. Nous avons aussi créé la fonction de vérification de victoire au morpion :

//vérification victoire
bool win(int grille[],bool ligne1, bool ligne2, bool ligne3, bool c1, bool c2, bool c3, bool d1, bool d2){
   bool v1=false, v2=false;
   //verif lignes
   if (!((grille[0]==0)&&(grille[1]==0)&&(grille[2]==0))){
       v1=grille[0]==grille[1];
       v2=grille[1]==grille[2];
       ligne1=v1&&v2;
   }
   if (!((grille[3]==0)&&(grille[4]==0)&&(grille[5]==0))){
       v1=grille[3]==grille[4];
       v2=grille[4]==grille[5];
       ligne2=v1&&v2;
   }
   if (!((grille[6]==0)&&(grille[7]==0)&&(grille[8]==0))){
       v1=grille[6]==grille[7];
       v2=grille[7]==grille[8];
       ligne3=v1&&v2;
   }
   //verif colonnes
   if (!((grille[0]==0)&&(grille[3]==0)&&(grille[6]==0))){
       v1=grille[0]==grille[3];
       v2=grille[3]==grille[6];
       c1=v1&&v2;
   }
   if (!((grille[1]==0)&&(grille[4]==0)&&(grille[7]==0))){
       v1=grille[1]==grille[4];
       v2=grille[4]==grille[7];
       c2=v1&&v2;
   }
   if (!((grille[2]==0)&&(grille[5]==0)&&(grille[8]==0))){
       v1=grille[2]==grille[5];
       v2=grille[5]==grille[8];
       c3=v1&&v2;
   }
   //verif diagonales
   if (!((grille[0]==0)&&(grille[4]==0)&&(grille[8]==0))){
       v1=grille[0]==grille[4];
       v2=grille[4]==grille[8];
       d1=v1&&v2;
   }
   if (!((grille[2]==0)&&(grille[4]==0)&&(grille[6]==0))){
       v1=grille[2]==grille[4];
       v2=grille[4]==grille[6];
       d2=v1&&v2;
   }
   bool win=ligne1||ligne2;
   win=win||ligne3;
   win=win||c1;
   win=win||c2;
   win=win||c3;
   win=win||d1;
   win=win||d2;
   return win;
}

Côté électronique, nous avons en notre possession les PCB des 6 faces du cube.

Nous avons donc effectué la soudure de toutes les faces restantes et donc des 45 LEDs restantes: Faces totalement soudees Cette étape nous a pris un temps considérable :

  • Réalisation des 27 vias sur chaque face
  • Soudure de 9 LED CMS par face
  • Étamage de tous les câbles
  • Soudure des câble pour réaliser les ponts entre les faces

Seulement après tout cela, nous avons pu avoir nos 6 faces correctement soudées. Nous avons continué de travailler jusqu'à la mise en place d'un prototype.

Poursuite du cube & idées

Par la suite, nous avons réalisé un premier prototype du cube de la manière suivante : chaque anode de la première série de trois faces a été reliée à une autre de la deuxième série de trois faces.

Nous avons obtenu le prototype suivant : 1er prototype

Les autres circuits permettant d'obtenir un cube avec l'électronique totalement embarquée n'ont pas été réalisée. Nous avons donc laissé le MBED et la carte de multiplexage à l'extérieur. Voici ce que nous pouvons présenter à l'heure actuelle : Cube à l'état actuel

Le test de ce 1er prototype et des codes développés se fera durant la vidéo.


Pour les cartes supplémentaires, nous avions prévu d'en concevoir 3 : Une carte pour les piles permettant d’alimenter le MBED. Une seconde comportant le MBED, le capacitive Touch Adafruit et l’accéléromètre. Une troisième qui correspond à la carte de multiplexage mais en miniature avec des composants CMS. La liaison entre chaque se faisant par des fils.

Schéma des 3 cartes à réaliser

Conclusion

Ce projet nous aura permis d'approfondir nos connaissances dans deux principaux domaines : la conception de circuits électroniques, ainsi que le développement d'une application orientée microcontrôleur. D’autre part, ce projet nous auras permis d’exercer la gestion de projet et de se rendre compte de nos erreurs. La principale erreur a été de ne pas se projeter assez vite vers un premier prototype. Au lieu de cela, nous sommes restés un moment sur le test de chaque composant séparément en essayant de prévoir son introduction à l’électronique du cube. Nous avons pris du retard en négligeant un peu la partie électronique et création de carte et nous nous sommes rendus compte que celle-ci n’était pas des moindres et prenant un certain temps.

Fichiers Rendus

Rapport du projet : Fichier:Rapport Projet DUPLOUY ZEGGAI.pdf

Code source du dé électronique (langage C++) : Fichier:Code DeElectronique.txt

Code source + bibliothèques : Fichier:Codes et bibliotheques de electronique.zip