Dé électronique communiquant

De Wiki d'activités IMA
Révision datée du 12 avril 2015 à 22:10 par Mzeggai (discussion | contributions) (Semaine 8 (du 23/03/2015 au 29/03/2015))

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.

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.

L'objectif pour la prochaine séance sera de se décider sur la solution tactile de notre cube, ou sur une alternative à adopter.

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 quelques essais infructueux, 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;}

Voici la vidéo reprenant l'idée de cet algorithme :

/* Vidéo à venir */

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. A l'issue de cette semaine, nous avons pu envoyer notre modèle au service électronique pour élaboration.

/* Images à venir */

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 :

/* Image à venir */

   #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. 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.

/* Images à venir */

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.

Fichiers Rendus