Globe à persistance rétinienne

Envoyé par le 18 Août 2014

Le globe à persistance rétinienne consiste à donner l’impression d’un globe de LEDs sur lequel on peut afficher des images, en faisant simplement tourner à grande vitesse un demi-cercle sur lequel sont fixées des LEDs RGB. En allumant les LEDs exactement aux bons instants, on peut produire n’importe quelle image. Voici quelques exemples :

Globe : terre Globe : texte

Ce globe est le résultat du travail d’une succession de personnes au Téléfab. Un premier projet S2 (CHAIEB Hassen, EL AABOUDI Khalid, RAYNAL Damien et TELLAT Wael, étudiants en première année) a permis de construire la structure du globe ainsi que les premières version des logiciels de contrôle et d’obtenir le premier prototype fonctionnel. Un projet d’intersemestre (Boris Claverie et Rémy Bétus, étudiants en troisième année) a permis de travailler sur la conception du contact électrique entre les parties fixes et tournantes et sur la synchronisation de l’image par rapport à la vitesse du moteur. Enfin, divers intervenants du Téléfab (Benoit Larras, Pierre-Henri Horrein et Tristan Groléat) ont travaillé sur la fiabilisation générale du globe (structure, électronique, logiciel). Cet article mis à jour régulièrement présente le fonctionnement du globe dans son état actuel, ainsi que les leçons apprises des tentatives précédentes.

Voici le globe à l’arrêt :

Globe : à l'arrêt

Il est composé de plusieurs parties importantes :

  • la partie fixe qui permet la stabilité du système, avec un moteur à courant continu qui fait tourner le globe ;
  • la partie tournante avec les LEDs contrôlées par un Arduino Mega ;
  • l’interface entre la partie fixe et tournante, qui permet à la partie tournante de recevoir de l’énergie et des ordres, et de détecter sa vitesse de rotation ;
  • la carte électronique de contrôle, fixe, qui fournit une alimentation à différents niveaux de tension, contrôle le moteur, et facilite la communication entre les parties fixes et tournantes ;
  • le logiciel embarqué, qui contrôle le tout ;
  • les logiciels de support, qui permettent de travailler avec le globe.

Le code et les objets 3D utilisés pour la conception du globe sont disponibles sur Github.

La partie fixe

La partie fixe est composée d’une planche de contreplaqué sur laquelle sont fixés quatre mâts faits de profilés d’acier en cornière. Ces mâts sont rejoints en haut par des profilés plats en acier qui se rejoignent au centre. À cet endroit, un trou est percé. L’axe de la partie tournante est une tige filetée. En haut, une tige lisse graissée est vissée sur la tige fileté. C’est ce qui sert à maintenir la tige.

Le bas de la tige est fixé au moteur à courant continu fixé au centre de la planche de contreplaqué. Il s’agit d’un moteur récupéré qui provient apparemment d’un essuie-glace.

Cette structure remplace la précédente qui était faite en bois, avec un seul mât. Elle est beaucoup plus rigide que la précédente, ce qui permet de parer en partie au balancement dû à un mauvais équilibrage de la partie tournante.

La partie tournante

Globe : partie tournante

La structure de la partie tournante est un anneau en plastique. Cette anneau est traversé par une tige filetée servant d’axe. Des trous sont percés sur l’anneau pour laisser passer 39 LEDs RGB réparties uniformément en un demi-cercle. Chaque LED est connectée directement à l’Arduino MEGA accroché sur l’axe au centre de l’anneau. Pour faciliter les connexions, un shield a été créé pour l’Arduino avec une plaque de prototype.

Pour diminuer les connexions, les cathodes des LEDs sont reliées. Ainsi, toutes les cathodes « rouge » sont reliées à un pin de l’Arduino, de même pour les cathodes « vert » et « bleu ». L’anode de chaque LED est connectée à un pin différent de l’Arduino. De cette manière pour contrôler  39 LEDs, il faut 39 + 3 = 42 pins. Cela signifie qu’à un instant donné, toutes les LEDs allumées ont la même couleur. Pour afficher des images, il faut donc allumer très rapidement chaque LED l’une après l’autre.

Cette partie est celle qui a été la moins modifiée depuis le début. La seule nouveauté est le remplacement des serre-joints utilisés pour fixer l’Arduino par des pièces faites à l’imprimante 3D, disponibles sur Github dans le dossier Things (ficher OpenSCAD ou STL arduino_holder).

L’interface fixe/tournant

Globe : connexion tournante

 

Contact électrique

L’interface entre les parties fixes et tournantes est une partie cruciale du globe. Elle sert avant tout à alimenter en énergie la partie tournante. Pour cela, deux contacts doivent être faits : la masse, et un 9V qui permet d’alimenter l’Arduino Mega par le pin Vin. Un composant appelé collecteur tournant est disponible dans le commerce pour réaliser des contacts électriques tournants. Mais celui utilisé est fait maison à l’imprimante 3D. Les plans sont sur Github dans le dossier Things. (fichier OpenSCAD connection-base, les fichiers STL sont aussi disponibles).

Le principe est simple : deux larges rondelles sont utilisées comme contacts tournants. Elles sont fixées à la partie tournante par des pièce réalisées à l’imprimante 3D (une base, un séparateur pour éviter le contact entre les deux rondelles, et des petites cales pour tenir le tout fixé). Des fils électriques passent par l’intérieur de la base et sont soudés aux rondelles. Sur la partie fixe, deux petites vis poussées par des ressorts appuient sur les rondelles. Elles sont visibles à gauche sur la photo. Elles sont maintenues par une pièce faite à l’imprimante 3D, et sont chacune soudées à un fil électrique arrivant par derrière.

Ce mécanisme permet d’alimenter l’Arduino MEGA sans avoir de problèmes de fils qui s’emmêlent. Le défaut est que cela crée des frottements et du bruit. Mais le contact est fiable. Pour s’assurer que l’Arduino fonctionne sans problème en rotation, une grosse capacité a été placée sur la partie tournante en parallèle de l’alimentation de l’Arduino. Elle agit comme une mini batterie en cas de coupure de très courte durée.

Ce contact électrique a été une source majeure de difficultés dans la conception de ce globe. Différentes solutions ont été tentées : enrouler du fil de fer sur la partie tournante et tendre un fil entre deux bouts de bois pour appuyer sur la partie tournante, coller du scotch cuivré sur la partie tournante et tendre des bandes de cuivre avec une pièce faite à l’imprimante 3D, utiliser une prise jack en faisant tourner la partie mâle dans la partie femelle. Toutes ces solutions ont marché pendant un temps, mais se sont vite usées et ont cessé de fonctionner. La solution actuelle a duré beaucoup plus longtemps que ces solutions.

Détection de la vitesse de rotation

Une fonction annexe de l’interface fixe/tournant est de permettre à l’Arduino MEGA de détecter un point fixe lors de la rotation, pour avoir une référence et permettre d’afficher une image fixe. Ceci est réalisé grâce à une LED cachée dans le petit cube noir visible à droite sur la photo précédente. La LED est constamment allumée et fixe. Dans la partie tournante, en face de la LED, se trouve une photorésistance (fils violets qui arrivent en haut de la photo). Quand la photorésistance passe devant la LED, elle détecte la lumière. La photorésistance est directement connectée à l’Arduino MEGA, avec un montage pull-down, qui fait que la valeur 0 est lue constamment, sauf quand la photorésistance est devant la LED. Dans ce cas, la valeur 1 est lue par l’Arduino.

Au début, nous utilisions un montage pull-up, la photorésistance lisait un 1 constamment et un 0 en passant devant la LED. Mais nous avons remarqué que ce montage était beaucoup plus sensible au bruit provoqué par l’alimentation instable, provoquant des fausses détections difficiles à ignorer côté logiciel.

La carte électronique de contrôle

Globe : carte électronique

Alimentation

L’objectif principal de cette carte est d’alimenter l’Arduino et le moteur. Elle reçoit en entrée du 12V (ou un peu plus) fourni par un vieux transformateur récupéré. Pour alimenter l’Arduino, elle contient un simple régulateur 9V.

L’alimentation du moteur est un peu plus complexe car nous voulons pouvoir contrôler sa vitesse. Cela permet de le ralentir pour montrer aux gens le fonctionnement de la persistance rétinienne. Pour cela, nous utilisons un potentiomètre visible en bas à droite sur la photo. Mais le moteur demande beaucoup de puissance, il n’est donc pas possible de le mettre simplement en série avec le potentiomètre. La meilleure manière de contrôler un moteur à courant continu est d’utiliser des PWM, c’est à dire un signal carré alternant rapidement entre la tension maximale (les 12V reçus en entrée) et 0. Selon le rapport cyclique entre la durée à 12V et la durée à 0v, la vitesse du moteur change. Pour générer ces PWMs à rapport cyclique variable en fonction de la valeur d’un potentiomètre, nous avons utilisé un montage à partir du composant NE 555 trouvé sur instructables. Le montage décrit dans l’article est exactement celui réalisé ici. Les valeurs de résistance sont adaptées pour aller avec la valeur du potentiomètre, selon la formule indiquée dans l’article. Les PWMs générées ne supportent pas assez de puissance pour contrôler le moteur. C’est pourquoi elles sont utilisées comme signal de contrôle pour un transistor MOSFET, qui contrôle le moteur, suivant le montage décrit dans la partie « Simple Power MOSFET Motor Controller »  de cet article.

Dans sa première version, le globe n’avait aucune carte de contrôle. Une alimentation réglable à deux sorties était donc nécessaire pour le faire fonctionner, ce qui était encombrant. Dans une version suivante, une alimentation de PC a été récupérée, et la vitesse du moteur était contrôlée par un gros potentiomètre en série avec le moteur. Ce système fonctionnait mais toute la puissance non utilisée par le moteur était dissipée par le potentiomètre, qui chauffait beaucoup et risquait de brûler l’utilisateur. La version actuelle est plus compacte et ne chauffe quasiment pas.

 Communication avec la partie tournante

Globe : circuit comm.

Envoyer des informations à la partie tournante sans l’arrêter permet d’apporter de l’interactivité au globe. Pour ce faire, un bus de communication entre la partie fixe et la partie tournante est nécessaire. Mais nous ne disposons que de deux conducteurs entre la partie fixe et mobile : la masse et le 9V. Pour ne pas compliquer la mécanique, l’alimentation peut être modulée par un Arduino fixe pour envoyer des informations à l’Arduino MEGA tournant. Pour ceci, il modifie la masse en la passant à 5V pendant de très courts instants, ce qui crée des impulsions. Le délai entre les impulsions permet de coder des 1 et des 0, et donc d’envoyer des messages binaires.

Le mécanisme pour créer ces impulsions sur le fil de masse est intégré à la carte. Il est visible sur la partie gauche de la photo et détaillé sur le schéma ci-dessus. La sortie GND_MOD peut être utilisée à la place de la vraie masse pour alimenter la partie tournante. Un condensateur branché en parallèle sur l’alimentation de l’Arduino évite qu’il ne soit perturbé par les impulsions. Ce condensateur est isolé du PIN de lecture (3) par une diode pour rendre les impulsions visibles par le PIN 3. L’entrée CTRL est un signal géré par l’Arduino externe. Quand cette entrée passe à 0, GND_MOD passe à 5V à cause du transistor (un MOSFET N) par l’intermédiaire d’une résistance de pull-up d’1kΩ. Sinon GND_MOD reste à la masse. Si aucun fil n’est connecté à CTRL, GND_MOD reste à la masse grâce à la résistance de pull-up de 10kΩ sur CTRL. L’Arduino de contrôle externe est donc facultatif.

Le circuit qui permet de générer les impulsions a été fait « au feeling », en s’inspirant du système de communication 1-wire. Des retours d’experts pour améliorer le circuit seraient les bienvenus. Mais pour le moment, ce circuit fonctionne bien.

Le logiciel embarqué

Le logiciel embarqué est en une librairie qui gère l’affichage et la communication, et des exemples d’utilisation. Tout le code est sur Github dans le dossier « Globe ».

Librairie : l’affichage

L’affichage est géré par la classe singleton Globe. Cette classe fournit une méthode d’initialisation (begin), à partir de son appel, l’affichage sur le globe est géré par l’Arduino. La classe fournit aussi des méthodes de dessin (setLedgetLedrotate, setLedRot, getLedRot) qui permettent de modifier l’image affichée sur le globe. Les changements sont visibles dés le prochain rafraichissement de l’image. Enfin, la librairie contient des méthodes de synchronisation (delayRound, passedRound) qui permettent de synchroniser le déroulement du programme par rapport à la vitesse de rotation.

Le fonctionnement de la librairie est entièrement basé sur des interruptions : les interruptions du capteur de tour permettent de mesurer la vitesse de rotation et de commencer l’affichage ; les interruptions d’un timer permettent d’allumer les LEDs les unes après les autres. L’exécution de la librairies est critique et les interruptions ne doivent pas être inhibées. La librairie utilise une part non négligeable du temps du processeur, qui augmente avec la vitesse de rotation.

L’affichage de l’image se fait colonne par colonne et LED par LED. Une seule LED est allumée à un instant donné. Chacune des trois couleurs est gérée en binaire (allumée ou éteinte), ceci à cause du faible nombre de sorties analogiques de l’Arduino. Il serait possible d’afficher les colonnes couleur par couleur (rouge puis vert puis bleu) au lieu de LED par LED pour aller plus vite. Cette alternative a été tentée, mais elle nuit au mélange des couleurs.

Librairie : la communication

La communication entre la partie fixe et tournante ne fonctionne que dans un seul sens : l’Arduino fixe envoie des ordres à l’Arduino MEGA tournant. L’Arduino fixe est donc le maître et l’Arduino tournant est l’esclave. La librairie est donc divisée en deux classes : BusMaster et BusSlave. Elles ont toutes les deux une méthode d’initialisation (begin). Ensuite la classe maître a une méthode send et la classe esclave a des méthodes available, read et readString pour savoir si un message est disponible, lire un octet du message, ou lire une chaine entière.

La communication fonctionne par impulsions. Il y a 3 symboles : 0, 1, et fin qui correspondent à des délais différents entre deux impulsions. Chaque octet est envoyé suivi de 2 bits permettant de numéroter l’octet, d’un bit de parité, et d’un symbole fin. Chaque octet est envoyé à 3 reprises. Cette redondance est ajoutée pour fiabiliser la communication. Deux facteurs rendent la communication complexe : le bruit dû au contact tournant et l’imprécision de mesure due au fait que l’Arduino esclave s’occupe déjà de l’affichage, ce qui l’empêche de mesurer les délais avec précision. Le second facteur est au moins aussi important que le premier.

Du côté maitre, les messages sont envoyés de manière bloquante en utilisant la fonction Arduino delay. Du côté esclave, les mesures sont faites à l’aide d’interruptions et de deux timers. Nous avons essayé d’utiliser un ICP (Input Capture Pin) de l’ATMega pour rendre les mesures plus précises (le timer est déclenché automatiquement par les interruptions) mais les interruptions ICP ont une priorité trop forte qui ne peut pas être réglée, ce qui empêche le fonctionnement de l’affichage du globe.

Les exemples

Différents exemples sont disponibles avec la librairie : une carte du monde qui tourne sur lui-même, un texte qui défile et un bonhomme qui court à contre-sens du globe. Deux exemples interactifs sont aussi disponibles : la possibilité d’afficher le texte qu’on veut en l’envoyant sur le port série de l’Arduino fixe, ainsi qu’un jeu de Snake pouvant se jouer à 2. Pour ce dernier jeu, des joysticks doivent être connectés à l’Arduino fixe.

Les logiciels de support

Certains logiciels ne servent pas directement à faire fonctionner le globe, mais sont utiles pour le programmer. C’est le cas par exemple du programme ImageConverter disponible sur Github. Il a été développé en Java par les premiers étudiants qui ont travaillé sur le globe. Il permet de prendre une image, de diminuer sa résolution, de convertir ses couleurs, et de générer un format qui permet d’intégrer l’image dans du code pour l’afficher le globe. C’est ainsi qu’a été fait le programme avec la carte du monde qui tourne.

3 Commentaires

  1. Bravo à toute l’équipe; excellent boulot. J’ai vu votre globe fonctionner à Victor Ségalen, je peux témoigner que c’est un succès. En tant qu’électronicien (amateur – assez pointu quand même…) et informaticien (programmation, bases de données) et bricoleur occasionnel, j’aurais suivi les mêmes voies que vous, mais j’apprends de l’expérience que vous avez la grâce de publier « open source ». Entre autres défauts, je suis de ce bord-là, même si, pour des raisons pratiques, je suis plus souvent sous ce bon vieil XP (pas si mal: à la base, c’est pas du Krô$ôft :-).
    Bonne continuation et
    A+

  2. J’ai beaucoup appréciée votre réalisation, mais pourquoi vous n’avez pas pensé d’utiliser une communication sans fil (exemple module XBee 2.4GHz) pour assurer la transmission des données entre la partie fixe et la partie tournante? De cette façon vous pouvez avoir une bande passante importante.

  3. Bonjour,
    Effectivement c’est une bonne idée que je n’ai pas testée. Je me suis posé des questions sur l’effet de la rotation et je ne voulais pas ajouter un shield à la partie tournante.

    Un groupe d’étudiants est en train de réaliser une version améliorée du globe pour laquelle la quasi totalité de l’électronique sera immobile, ce qui évitera cette question.

Laisser une réponse

Votre adresse e-mail ne sera pas publiée.