Matrice de LED 3D

De Wiki d'activités IMA
Révision datée du 15 mai 2013 à 13:12 par Rex (discussion | contributions) (Présentation)

Présentation

ERROR in secure-include.php: Not allowed to include remote URLs, or inexistant path.

Le but de ce projet est de concevoir une matrice 3D composée de 512 leds (8x8x8) et d'y faire afficher dans un premier temps des formes géométriques (par exemple à partir de formules mathématiques) et dans un second temps de réaliser un jeu de type Snake, pilotable grâce à une manette de Wii. Le tout sera présenté lors des journées Portes Ouvertes de l'école afin de promouvoir le département IMA.

Matériel requis

  • 512 LED et leur connectique
  • un Arduino
  • des composants permettant de commander les 64 entrées et 8 sorties de la matrice avec beaucoup moins de sorties disponibles sur l'Arduino
    • (x1) SN74HCT138 - 3-line to 8-line Decoder (pour les etages)
    • (x8) 74HCT595 - 8-bit Serial-in/serial or parallel-out shift register with output latches 3-state
    • (x8) 74HCT244 - 8-bit buffer/line driver with 3-state outputs
    • 2e solution :
      • 74HC154 decoder 4-16
      • (x8) ULN2804 buffer 8 bit ou (x8) UDN2981 buffer 8 bit
  • de quoi alimenter les LED et les composants (bloc secteur pour l'Arduino, un régulateur 5V pour les composants)
  • un Nunchuck

Rendu

Avancement du projet

Lundi 4 Février

Cette première séance a été mise à profit afin de mieux cerner le projet, en discutant avec les enseignants et en commançant les recherches sur la manière de réaliser la matrice.

Jeudi 7 Février

Traçage de plans de montage, remise en question quant au moyen de commander les 64 colonnes de leds (le multiplexage semblait le plus évident mais d'autres possibilités comme des registres à décalage pourraient également convenir).

Lundi 11 Février

Définition des moyens en composants pour créer le circuit de commande. Création du patron du guide qui servira à aligner les leds et les souder facilement.
Ce patron a été transmis à la personne qui se chargera de fabriquer le support par commande numérique.

Jeudi 14 Février

Séance mise à profit pour compter et tester les 512 LEDs (en y ajoutant quelques pièces en cas de souci au montage).

Lundi 25 Février

Recherche à propos du moyen de connecter un nunchuck en filaire ou une Wiimote en bluetooth. La Wiimote requiert un type de connexion non offert nativement par les cartes Arduino (Bluetooth HID). Une solution serait d'utiliser un shield bluetooth externe, mais cela complique le montage et réduit le nombre de broches. En revanche brancher un Nunchuck en filaire ne semble pas poser de problème particulier.
Création de PCB pour la carte qui supportera les composants et redéfinition des composants nécessaires (les ULN2803 seront utilisés à la place des 74HCT244 dans la première solution).

Mercredi 27 Février

Le travail de création du PCB est bien avancé, il a été retardé car il fallait recréer des librairies de composants utilisés dans le montage.
Un petit inconvénient est survenu, il semble que les ULN2803 ne soient pas parfaitement adaptés, en effet il nous faudrait plutôt des montages de transistors capables de fournir de la puissance vers les LEDs. À première vue il faudrait utiliser des composants de type "Source type darlington transistor array" (comme le M54564P).
Le nunchuck est connecté sur Arduino Uno dans un premier temps (problèmes de drivers pour un Mega sur Windows), nous reconsidérons l'utilité de prendre un Mega pour ce projet. Une Uno semble suffire du point de vue matériel.
Le nunchuck utilise I2C, nous savons récupérer les différentes informations provenant de celui-ci (accéléromètre X,Y,Z, joystick X,Y, boutons Z et C). Pour le connecter sur Arduino nous avons utilisé un adaptateur "wiichuck" mais nous avons également pensé fabriquer cet adaptateur par nous-mêmes au vu de la simplicité du montage.
Point à travailler : savoir quels seuils de l'accéléromètre sont exploitables pour l'utilisation envisagée (choix des modes de jeu, etc...), ceux-ci sont différents en fonction de la vitesse à laquelle le nunchuck est déplacé.

Jeudi 28 Février

Après quelques recherches il semble que nos doutes soient fondés, il faut remplacer les ULN2803 initialement prévus par des TD62783 APG/AFG/AFWG. En effet les ULN2804 sont des "sink drivers" alors qu'il nous faut des "source drivers" comme les TD62783.
Au niveau de l'Arduino, l'acquisition des données provenant du Nunchuck est à présent fonctionnelle, on peut donc passer au traitement de ces données.

Lundi 4 Mars

Nous contrôlons des LEDs grâce au nunchuck. On peut remarquer que les axes X,Y et Z de l'accéléromètre ne réagissent pas de la même manière et ne sont pas réellement indépendants. Ceci pose un problème de choix de l'axe à utiliser pour telle ou telle fonction : les axes Y et Z réagissent quasiment de la même manière à un mouvement vers le haut.
De plus les broches 0 et 1 numériques servent à la liaison série (RX TX), ce qui pose problème pour l'instant car nous avons besoin de toutes les broches numériques et si on initialise le port série dans le code( Serial.begin), ces 2 broches deviennent uniquement utilisées pour la liaison série. Cependant les broches analogiques non utilisées semblent pouvoir être utilisées en tant que sorties numériques.

Mercredi 6 Mars

Test du jour : gérer l'allumage d'une ligne de leds, une par une et dans les 2 sens, grâce au nunchuck (accéléromètre X), choix de la vitesse de défilement avec le joystick.
Réflexion quant à l'algorithme du jeu Snake, et à l'implémentation sur l'arduino.
La structure du code se déroule ainsi :

  • setup : initialisation du nunchuck, calibrage des valeurs des accéléromètes, joystick et boutons
  • loop :
    • demande et réception des données du nunchuck et décodage de ces données
    • partie traitement des données : calcul des ordres à donner à la matrice
    • affichage sur la matrice



Lundi 11 Mars

Voici l'avancement du PCB de la carte qui commandera les 512 LED (partie Hardware) :



PCB commande matrice.png


Il reste quelques pistes à relier sur le PCB suite à quoi nous pourrons commencer les tests sur plaquette grâce aux composants reçus.

Niveau informatique : détermination des seuils de perception d'allumage des LEDs en multiplexage, c'est-à-dire quelle est la durée maximale qui permet de voir les LEDs (allumées l'une après l'autre) comme si elles étaient allumées en même temps.
On obtient pour 6 LEDs de test un temps de pause maximal de 4 ms par LED, soit une boucle de 24 ms max (rafraichissement de 42 Hz minimum).

L'Arduino Uno avec le Nunchuck

Mercredi 13 Mars

Réception d'un nouveau Nunchuck. Un peu de temps perdu à devoir retester et recalibrer les valeurs, car les accéléromètres réagissent différemment de ceux du Nunchuck que nous avions emprunté.
D'un autre côté, nous avons commencé à écrire un algorithme de jeu Snake en utilisant une matrice 2D 8x8 Sparkfun en attendant la vraie matrice 3D. Cette matrice de développement a l'avantage de représenter une méthode de transfert qui ressemble en partie à la solution que nous avons adoptée pour la matrice 3D, c'est à dire que l'on envoie les informations bit par bit en série.
Une fois l'algorithme opérationnel en 2D, ajouter une troisième dimension devrait être assez aisée.
Le PCB de la carte de commande est a priori terminé, désormais il faut faire des tests pour assurer le fonctionnement du modèle électronique choisi.


La matrice 2D de test affichant un Snake

Mercredi 20 Mars

Nous avons maintenant un Snake totalement fonctionnel en 2D sur matrice 8x8, pilotable par le nunchuck. La troisième dimension est codée, il ne restera qu'à la tester une fois en possession de la matrice 3D.
Cependant il faut revoir le moyen de stocker les valeurs du serpent en mémoire. Un tableau[8][8][8] est le plus simple mais pas le plus efficace pour envoyer les données à la matrice. Un tableau de 8 octets est mieux adapté mais plus compliqué à mettre en œuvre.

Nous avons reçu les registres à décalage et le multiplexeur et avons créé un PCB pour insérer les composants CMS sur des plaques de test. Le premier test à réaliser est d'essayer d’allumer toutes les LEDs en même temps à travers le 74HCT595D pour savoir si le composant peut délivrer un courant suffisant.

Plaque de test du composant 74HCT595D


plaque d'adaptation CMS vers ThroughHole du 74HCT595D

La partie Arduino qui réalise la liaison entre Hardware et Software a été commencée. Le but est de construire une fonction qui prend en paramètre la matrice 8x8x8 et qui envoi les bons signaux sur les pattes de sortie de l'Arduino pour commander la carte électronique que nous avons conçue. Jusqu'à présent nous avons utilisé les interruptions internes de l'Arduino grâce à la bibliothèque MsTimer2 qui permet de déclencher une fonction grâce à une interruption survenant toutes les n millisecondes. Les interruptions permettent de gérer l'affichage indépendamment du programme qui est en cours d’exécution.

Mercredi 27 Mars

Remplacer le tableau de 1 octet pour 1 LED par un tableau de 1 octet pour 8 LEDs n'est finalement pas si efficace que cela. D'un côté on gagne en mémoire (dans le premier cas on n'utilisait qu'un bit sur 8), d'un autre côté cela oblige à manipuler les bits par des masques et des fonctions de conversion tableau <-> octet, ce qui au final alourdit le code et oblige à réaliser de nombreuses opérations supplémentaires à chaque rafraichissement de l'affichage.

L'utilisation des interruptions (bibliothèque MsTimer2) amène de nouveaux problèmes : le nunchuck ne peut pas être interrompu lorsqu'on l'interroge et si on appelle la fonction qui gère le nunchuck dans l'interruption, elle ne fonctionne pas car son temps d'exécution est trop grand pour une interruption. Au final utiliser les interruptions pose plus de problèmes que cela n'en résout. Il suffit de positionner correctement des delay() dans la boucle pour que le rafraichissement soit correct et que le nunchuck réponde.

Le circuit imprimé de la carte de commande est terminé, il ne reste plus qu'à réaliser la carte. D'un point de vue logiciel de pilotage de la carte plusieurs tests ont étés réalisés et un programme "final" est prêt. L'affichage de la matrice est réalisé toutes les 20 millisecondes par interruption récurrente.

  • Premier test : test d'allumage des LEDs en simultanées

Le premier test a prouvé que l'on pouvais allumer toutes les LEDs avec un 74HCT595D et avec un bon niveau de luminosité.

  • Deuxième test : test d'allumage des LEDs en "condition réelle"

Toutes les LEDs sont allumées en même temps mais seulement 1/8ème de temps. La luminosité n'est pas importante voire insuffisante.

  • Programme final : Contrôle des 512 LEDs et affichage aléatoire des LEDs en mode "rideau de pluie".

Ce programme pourra être testé quand nous aurons la matrice de LEDs et la carte réalisée et soudée.

Mercredi 03 Avril

L'utilisation des interruptions sur Arduino est maintenant opérationnel, le problème précédent venait de l'utilisation abusive de la commande delay(), qui est interdite dans les interruptions. Quelques tests ont permis de trouver le bon timing à appliquer.
Amélioration du code du Snake sur de nombreux points, notamment simplification de certaines fonctions peu optimisées.

Lundi 08 Avril

Le PCB de la carte de commande a été entièrement recréé pour suivre les indications techniques, notamment l'écartement des pistes, la largeur des vias et pour simplifier le tracé des pistes. Des connecteurs HE10 de 50 broches ont étés ajoutés pour permettre de brancher plus facilement la carte de commande avec la matrice. En effet un support sous forme de carte électronique doit être fabriqué pour brancher directement la matrice.

Pendant les vacances

En attente de réception des composants commandés, nous nous attardons plus particulèrement sur l'optimisation et la simplification du programme Arduino. En effet, la version précédente fonctionnait sur les 64 LED de la matrice 2D, mais crashait avec des tableaux prévus pour la matrice 3D (512 LED), ceci en raison de dépassements de mémoire : l'Aruino Uno ne dispose que de 2ko de RAM, or nous les dépassions à cause de 2 tableaux de 512 cases d'entiers.
Après refonte d'une grosse partie du code, nous somme parvenus à régler le dépassement de mémoire en supprimant complètement un tableau (son utilité était de sauvegarder l'état de serpent avant l'état suivant ; un simple changement d'ordre des actions réalisées et l'ajout d'une variable globale stockant la taille du serpent l'a remplacé) et en transformant complètement la manière de stocker en mémoire l'état des LED : au lieu d'utilise un octet par LED, on n'utilise plus qu'un bit, ce qui réduit la taille de ce tableau par 8. Ainsi l'occupation de la mémoire se situe aux alentours de 1400 octets.

Vendredi 03 Mai

Nous avons enfin reçu les composants manquants, et plus important encore : la matrice est terminée. Il nous faut réaliser les derniers montages (soudage des derniers composants, sertissage des nappes de commande,...). En raison du manque de temps et de contraintes techniques, les cartes qui auraient dû servir à la connexion avec la matrice et à l'alimentation ne peuvent être réalisées, nous nous contentons donc de montages sur breadboard.

Explications techniques

Le jeu Snake

Le but du jeu est de tenir le plus longtemps possible en mangeant des "fruits" qui apparaissent sur la matrice. Il faut diriger le serpent vers ces fruits, une fois mangés la queue du serpent s'allonge d'une unité. Si le serpent arrive en bord de la matrice, il réapparait par la face opposée. Le joueur perd lorsque le serpent rencontre sa propre queue.

Protocole I2C

I2C (Inter Integrated Circuit) est la norme à utiliser pour dialoguer avec le nunchuck. Celle-ci utilise 2 fils (data et clock), les 2 autres fils étant l'alimentation et la masse. L'utilisation de cette norme impose d'utiliser les broches A4 et A5 sur un Arduino Uno car seules celles-ci sont utilisables pour ce protocole. En utilisant un adaptateur comme le wiichuck, on se retrouve à devoir envoyer VCC sur A3 et GND sur A2 :

#define pwrpin PORTC3
#define gndpin PORTC2
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);

_BV sert à assigner une sortie particulière plutôt que de devoir assigner tout le port comme en assignation explicite.

Commande de la matrice

La matrice est accessible par les 64 colonnes et les 8 étages. Ceci signifie qu'il faudrait, si l'on souhaitait connecter toutes ces entrées / sorties directement sur les sorties d'un Arduino, utiliser 72 broches, ce qui n'est pas possible. Il faut donc réduire le nombre de broches à commander grâce à du multiplexage et des registres à décalage.
Pour commmander les sorties, on peut soit faire une boucle qui assigne la bonne valeur à chaque broche, soit écrire directement dans le port qui gère ces sorties, ce qui semble être plus rapide et évite de devoir utiliser les Digital.Write().

Alimentation

Pour les tests, l'Arduino est connecté au PC par USB. Cependant dans le montage final, il faudra alimenter l'Arduino ainsi que les composants électroniques.
L'Arduino peut s'alimenter en 9V à partir d'un bloc branché sur secteur. Les composants de commande sont alimentés en 5V, on utilise un régulateur à partir de la tension délivrée par le bloc secteur pour obtenir les 5V.