Dé électronique communiquant : Différence entre versions
(→Semaine 8 (du 23/03/2015 au 29/03/2015)) |
|||
Ligne 208 : | Ligne 208 : | ||
Si (touche12 == 1) alors {led1=1; led2=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. | 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. | ||
Ligne 395 : | Ligne 391 : | ||
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. | 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) == | ||
+ | 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 commencé l'élaboration d'une face comportant nos LEDs RGB CMS. | ||
+ | |||
+ | 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. | ||
+ | |||
+ | == 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, et nous avons procédé aux tests d'allumage et de multiplexage. Les LEDs s'allument comme nous le désirons. | ||
+ | |||
+ | /* Image à venir*/ | ||
+ | |||
+ | L'objectif pour les 2 semaines restantes sera de pouvoir présenter au moins 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. | ||
= Fichiers Rendus = | = Fichiers Rendus = |
Version du 3 mai 2015 à 17:55
Sommaire
- 1 Cahier des charges
- 2 Avancée du projet
- 2.1 Semaine 1 (du 26/01/2015 au 01/02/2015)
- 2.2 Semaine 2 (du 02/02/2015 au 08/02/2015)
- 2.3 Semaine 3 (du 09/02/2015 au 15/02/2015)
- 2.4 Semaine 4 (du 16/02/2015 au 22/02/2015)
- 2.5 Semaine 5 (du 23/02/2015 au 01/03/2015)
- 2.6 Semaine 6 (du 09/03/2015 au 15/03/2015)
- 2.7 Semaine 7 (du 16/03/2015 au 22/03/2015)
- 2.8 Semaine 8 (du 23/03/2015 au 29/03/2015)
- 2.9 Semaine 9 (du 30/03/2015 au 05/04/2015)
- 2.10 Semaine 10 (du 06/04/2015 au 12/04/2015)
- 2.11 Semaine 11 (du 13/04/2015 au 19/04/2015)
- 2.12 Semaine 12 (du 20/04/2015 au 26/04/2015)
- 2.13 Semaine 13 (du 27/04/2015 au 03/05/2015)
- 3 Fichiers Rendus
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)
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).
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 :
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:
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 :
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;}
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.
Semaine 11 (du 13/04/2015 au 19/04/2015)
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 commencé l'élaboration d'une face comportant nos LEDs RGB CMS.
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.
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, et nous avons procédé aux tests d'allumage et de multiplexage. Les LEDs s'allument comme nous le désirons.
/* Image à venir*/
L'objectif pour les 2 semaines restantes sera de pouvoir présenter au moins 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.