3 points par GN⁺ 2023-12-03 | 1 commentaires | Partager sur WhatsApp
  • Prototype d’un dispositif d’affichage 3D de la taille de la paume, basé sur l’effet de persistance rétinienne (POV), obtenu en faisant tourner l’ensemble formé par une petite matrice de LED, une carte RP2040, une batterie LIR2450 et un moteur
  • Une matrice LED 8x10 est mise en rotation, un capteur IR lit la période, puis un tampon volumétrique est affiché en fonction de la vitesse mesurée
  • En exploitant les deux cœurs du RP2040 et le contrôle simultané des GPIO, un cœur mesure l’intervalle de rotation tandis que l’autre émet les données LED cycle par cycle
  • Le circuit de protection de batterie, la méthode de charge, la durabilité du support imprimé en 3D et l’absence de limitation de courant des LED sont les principales contraintes ; dans le prototype, une alerte s’affiche en dessous d’environ 3,6 V
  • Des tranches polaires 3D ainsi que des données de simulation de fluide et de flamme ont été créées avec Blender, mais la sensation de relief apparaît moins bien à la caméra qu’en réalité, et la prochaine version devra améliorer l’alignement et la résolution

Idée d’une bougie électronique rotative

  • L’objectif était de créer une bougie électronique qui ressemble à une flamme vacillante quel que soit l’angle d’observation
  • Les affichages classiques à persistance rétinienne nécessitent des structures de support comme des roulements et des bagues collectrices ; l’approche choisie a donc été de rendre le moteur et la batterie suffisamment petits pour que l’ensemble de l’appareil tourne d’un seul bloc
  • La carte de la matrice LED a été fabriquée rapidement en l’ajoutant à une autre commande de PCB
    • En Chine, les petits PCB sont de toute façon peu coûteux, et la rapidité de livraison comptait davantage
  • Une machine de pick-and-place Charmhigh CHM-T36VA a été utilisée
    • Le chargement des bobines de composants prend du temps, mais cette matrice LED n’utilisait qu’un seul type de composant, ce qui permettait de répéter l’assemblage rapidement
  • Le pochoir n’a pas été fabriqué de manière classique ; il a été gravé au laser sur de l’acétate
  • La matrice LED a été réalisée en versions avec composants 0603 et 0805, et une future version prévoit un PCB circulaire servant de support à angle droit

Configuration matérielle

  • Le microcontrôleur choisi est le Waveshare RP2040-tiny, pour sa petite taille et sa capacité de flash
    • Le Raspberry Pi Pico a pour avantages ses deux cœurs à 125 MHz, jusqu’à 16 Mo de flash et son faible coût, mais la carte elle-même est trop grande
    • Un RP2040 nu nécessite une flash QSPI externe, un quartz, des condensateurs auxiliaires, etc., ce qui le rend peu pratique à utiliser seul
    • Le RP2040-tiny est en quelque sorte un Pico réduit de moitié ; le port USB ainsi que les boutons reset/boot se trouvent sur une carte auxiliaire reliée par une nappe flexible
  • La batterie utilisée est une LIR2450
    • Elle est rechargeable en lithium-ion et peut fournir plus de 100 mA
    • Une batterie Li-ion plus petite réduirait la capacité et le courant disponible
    • La carte RP2040 mesurant environ 29 mm en diagonale, utiliser une batterie plus petite ne réduirait pas vraiment la taille finale
  • Le support de batterie a été imprimé en 3D en PETG
    • La première version avait des parois de 0,5 mm et deux pièces collées, avec pour faiblesse une ligne de collage qui se rompait à chaque chute
    • Des essais ont ensuite été faits avec des parois de 1 mm et une autre orientation d’impression
  • La détection de rotation est assurée par un capteur IR TCRT5000
    • Sa sortie est analogique, mais un pull-up permet de le connecter directement à un GPIO
    • Les entrées du RP2040 disposent d’un trigger de Schmitt désactivable par logiciel, ce qui permettait de l’utiliser en pratique comme un comparateur
  • Le moteur choisi est un RF-410CA
    • Des moteurs similaires de lecteurs CD/DVD avaient des diamètres et longueurs d’axe légèrement différents
    • Pour atteindre 30 FPS, il fallait environ 1800 RPM, alors que beaucoup de petits moteurs tournent à vide entre 5000 et 10000 RPM, ce qui est trop rapide
    • La vitesse est donc réduite via PWM

Circuit et assemblage du prototype

  • La matrice LED, en configuration 8x10, utilise 18 GPIO
    • Il faut en plus prévoir 1 entrée capteur, 1 sortie de commande moteur et 1 entrée de surveillance de tension batterie
  • La LED WS2812 présente sur la carte était connectée au GPIO16 ; pour récupérer ce GPIO pour la matrice, la LED a été retirée et un fil émaillé a été soudé
  • La commande du moteur utilise un petit MOSFET SOT-23 et une diode de roue libre, montés en dead-bug
  • La LED IR est connectée directement à la ligne d’alimentation
    • Idéalement, elle serait pilotée par logiciel pour économiser de l’énergie à l’arrêt, mais cela a été omis dans le prototype afin d’économiser un GPIO
  • La matrice LED est reliée directement aux GPIO, sans résistances de limitation de courant ni transistors drivers
    • Le courant total source/sink des GPIO du RP2040 est d’environ 50 mA
    • Le montage repose sur la résistance à l’état passant des GPIO et sur la limitation du duty cycle PWM ; si la puce se bloque et que la matrice reste allumée fixe, les LED risquent d’être suralimentées
  • Le pôle positif de la batterie est connecté directement au VBUS de la carte
    • Dans cette configuration, brancher un câble USB peut appliquer 5 V aux bornes de la batterie ; cela relève donc d’un bricolage provisoire de prototype
  • Un petit trou a été percé à l’arrière pour retirer la batterie et, après rupture du plastique, un élastique a servi à la maintenir en place

Logiciel de contrôle de l’affichage

  • Le logiciel surveille le capteur IR et utilise le temps entre deux déclenchements pour déterminer la vitesse d’affichage de la matrice
  • Le RP2040 tire parti du fait qu’il peut configurer ou lire tous les GPIO dans le même cycle d’horloge
    • Sur STM32, même avec un processeur 32 bits, les E/S sont regroupées dans des registres 16 bits et des problèmes de contention de bus apparaissent lorsqu’on essaie de les modifier simultanément
  • Les données GPIO nécessaires sont prétraitées à l’avance puis émises séquentiellement en proportion de la vitesse de rotation mesurée
  • Les deux cœurs ARM Cortex-M0 sont utilisés avec des boucles d’attente active plutôt qu’avec des interruptions
    • Le premier cœur surveille le capteur IR et mesure en cycles, via SysTick, l’intervalle entre déclenchements
    • Le second attend le signal lumineux puis parcourt le tampon volumétrique avec sa propre base SysTick, avec une précision au cycle près
  • La commande moteur a commencé avec une logique simple
    • Si le RPM est inférieur à 1200, le moteur tourne à 90 % de puissance
    • Sinon, il passe à 60 %
    • Grâce à l’inertie et à la résistance de l’air, ce contrôle simple suffit sur le prototype actuel
  • La matrice est balayée colonne par colonne
    • Vue de dessus, chaque ligne radiale devient légèrement hélicoïdale, mais cela reste plus facile à corriger qu’une hélice complète
    • Le duty cycle des LED proches du centre est réduit proportionnellement par rapport à celles de la périphérie

Surveillance de la tension batterie et charge

  • Une cellule LIR2450 nue n’a pas de circuit de protection ; si sa tension descend trop bas, elle peut être endommagée de façon permanente
    • Le problème apparaît bien en dessous de 3 V, la limite réelle étant d’environ 2,7 V selon la cellule
  • La surveillance se fait via un pont diviseur constitué de deux résistances de 100K, connecté au dernier GPIO disponible
  • Sur le RP2040-tiny, la tension de référence de l’ADC était variable
    • Si la référence ADC est la tension d’alimentation, il devient difficile de détecter correctement la baisse de tension batterie lorsque l’alimentation elle-même chute
    • Le LDO RT9193-33 à 3,3 V a un dropout de 220 mV à 300 mA ; quand la batterie atteint 3,52 V, l’alimentation du RP2040 commence elle aussi à baisser
    • Le prototype a donc été réglé pour afficher une alerte sous environ 3,6 V
    • Une future version ajoutera une tension de référence dédiée
  • Au départ, la batterie était retirée pour être chargée dans un chargeur séparé, mais le nouveau chargeur est tombé en panne dès la première utilisation
  • Ensuite, une alimentation de laboratoire a été configurée avec une limitation de courant à 50 mA et une tension constante de 4,2 V pour charger la cellule lithium-ion unique
    • Comme il n’était pas certain que la capacité soit de 120 mAh ou 60 mAh, un courant de charge plus conservateur que 1C a été choisi
  • Pour faciliter le développement, une carte d’interception USB a été fabriquée et insérée entre le PC et la carte de programmation du RP2040-tiny
    • La ligne 5 V est isolée et les broches batterie exposées, ce qui permet de connecter l’alimentation sans retirer la batterie
    • Les lignes de données restent connectées, ce qui permet de programmer avec la batterie en place
  • Plus tard, un circuit de charge Li-ion BQ21040DBVR a été ajouté au milieu de cette carte d’interception USB
    • Il devient alors possible de charger la batterie tout en laissant le câble de programmation branché
    • Le prototype ne s’éteint pas et seule la LED IR consomme en permanence environ 9 mA ; le courant de veille total est d’environ 15 mA, si bien que la condition de fin de charge complète n’est jamais atteinte
    • À cause de la chute de tension dans le câble, la tension batterie peut aussi ne jamais dépasser 4,1 V

Création des données volumétriques avec Blender

  • Les données d’affichage doivent être générées sous forme polaire 3D r, theta, z
  • Le premier test a été réalisé avec un cube filaire
    • Le modificateur wireframe a été appliqué au cube par défaut de Blender
    • Le cube a été tourné de 45 degrés sur l’axe x et de atan(1/sqrt(2)) sur l’axe y afin qu’une arête pointe vers le haut
  • Pour générer les tranches, un autre cube a été transformé en fine coupe et utilisé avec un modificateur booléen
    • La caméra et la tranche ont été parentées à un Empty, puis la rotation en Z de cet Empty a été animée
    • La caméra a été réglée en orthographique avec une résolution de 8x10
    • Le fond a été mis en noir, le matériau du cube en émissif, et le colour ramp du compositor a servi à fixer le seuil
  • L’écran actuel n’utilise que des voxels 1 bit
    • Chaque voxel est simplement allumé ou éteint
    • Dans Blender, le seuil a été ajusté visuellement pour choisir un cutoff convenable
  • Render animation génère les 24 images de tranche du cube filaire, puis un script Python les convertit en fichier d’en-tête inclus dans le code
  • Des drivers Blender sont utilisés pour piloter la rotation de la caméra et celle du cube à l’aide de formules basées sur les frames
    • La rotation de la caméra utilise (frame/24)*2*pi
    • La rotation en y du cube utilise floor(frame/24)*pi/24 afin qu’il pivote progressivement à chaque tour complet
    • L’objectif était de conserver chaque frame de données sous forme discrète afin d’ajuster la vitesse de lecture en fonction du RPM du moteur

Simulations de fluide et de flamme

  • Les simulations de fluide de Blender sont faciles à lancer, mais le grand nombre de paramètres rend difficile l’obtention du résultat voulu
  • Les simulations de liquide sont relativement faciles à transformer en mesh de particules, donc à convertir vers un affichage volumétrique
  • L’idée était de simuler à une vitesse de 1/24 puis d’extraire les données volumétriques polaires de la même manière, mais cette échelle de temps très lente introduisait des instabilités et aucune méthode simple n’a été trouvée pour ralentir la lecture
  • Les fonctions Multi-view ou Stereoscopy ont aussi été examinées
    • Elles permettent d’ajouter plusieurs caméras et de rendre simultanément plusieurs points de vue
    • Mais il n’était pas clair comment faire tourner rapidement 24 caméras de manière uniforme, et il fallait aussi rendre en même temps le modificateur booléen servant aux tranches
  • Un contournement consistant à utiliser la distance de clipping de la caméra pour rendre une fine tranche de scène a aussi été tenté
    • Le problème était que l’intérieur des objets coupés n’était pas rempli : seule la surface était dessinée
    • Des essais ont été faits avec des matériaux volumétriques pour combler cela partiellement, sans résultat concluant
  • Finalement, un script Python Blender a exécuté 24 rendus
    • La rotation Z de l’Empty a été changée pour 24 angles, puis l’animation complète a été rerendue à chaque angle
    • Cette méthode permet de conserver la simulation de fluide en temps réel tout en obtenant les tranches pour chaque direction de rotation
  • La simulation de flamme a été bake en OpenVDB puis réimportée dans Blender
    • Le modificateur Volume to Mesh a servi à seuiller les données volumiques
    • Ensuite, les tranches caméra et le modificateur booléen ont été appliqués, puis le même script a été relancé

Qualité d’affichage et prochaine version

  • Sur l’appareil réel, la sensation de relief est plus marquée qu’en photo ou en vidéo
  • Les erreurs d’alignement des LED peuvent aussi être corrigées par logiciel
    • La position de la tranche booléenne peut être légèrement décalée par rapport au centre pour correspondre au véritable axe de rotation
    • Pour compenser le motif de balayage de la matrice, on pourrait aussi utiliser une forme légèrement courbée au lieu d’un cube allongé
    • À cette résolution, ces améliorations peuvent toutefois rester peu visibles
  • La condition la plus importante est que chaque voxel individuel en périphérie apparaisse comme un point unique sous n’importe quel angle
    • Si l’alignement est mauvais, un voxel peut sembler allumé deux fois et apparaître allongé
  • Le caractère central m est rendu selon une méthode distincte pour rester lisible dans toutes les directions
    • Le texte défile de façon à être lisible aussi bien de face que de dos
  • Le prochain prototype doit améliorer l’alignement et la résolution
  • Faute de petit interrupteur à glissière, aucune fonction d’arrêt sans retirer la batterie n’a été intégrée ; une petite lamelle d’acétate insérée entre la batterie et le contact sert de solution de fortune
  • Comme un capteur IR est déjà présent, l’ajout d’une télécommande semble possible, mais le capteur actuel n’est pas de type démodulé
  • Le code source est publié sur GitHub : source code on github

1 commentaires

 
GN⁺ 2023-12-03
Commentaires sur Hacker News
  • Quelques idées d’amélioration me viennent à l’esprit. S’il y a un moteur identique en rab, on pourrait en démonter deux pour fabriquer un système de transfert d’énergie en rotation avec les balais des deux assemblages
    Il faut sacrifier deux moteurs par appareil, mais l’ajustement est parfait et très stable, et en y ajoutant un condensateur et un redresseur, il n’y a plus besoin de se soucier de la batterie
    Le redresseur peut aussi fournir un signal indiquant qu’un tour complet a été effectué, ce qui permet de garder la stabilisation de l’image sur la base de la position réelle plutôt que d’estimer le cycle
    Il serait peut-être aussi possible d’envoyer l’énergie par induction, mais je n’arrivais pas à la transmettre avec une efficacité suffisante, il aurait donc fallu trop augmenter la tension d’entrée, et cela m’inquiétait à cause du risque d’incendie
    Ce conseil vient d’un projet artistique de Burning Man en 2001. Des photos d’un prototype initial absolument catastrophique sont ici : https://github.com/sowbug/tqw/blob/master/photos/side.jpg. L’installation finale fonctionnait très bien

    • Tout à fait d’accord, mais j’aime aussi la solution utilisant un capteur IR pour la synchronisation. Le fait de faire tourner l’affichage en changeant la position du doigt était vraiment élégant, et il n’y avait rien à deviner
    • C’est une assez bonne idée. Les balais devraient tenir longtemps. Heureusement, la recharge sans fil des téléphones est maintenant répandue, donc on peut trouver des kits comme [1] ou [2]
      Je me demande aussi comment les fabricants de LIDAR gèrent ce genre de problème
      1: https://www.adafruit.com/product/1407
      2: https://www.adafruit.com/product/2162
    • Autre idée : pourquoi ne pas placer un petit écran TFT au-dessus du moteur ? On peut en trouver des modèles bon marché sur aliexpress
    • Et si on laissait le moteur tel quel et qu’on utilisait un deuxième moteur comme générateur ?
    • Si le moteur d’entraînement est un moteur asynchrone, on pourrait peut-être alimenter l’électronique tournante via les enroulements d’induction du rotor, mais le déphasage pourrait devenir assez extrême
  • C’est l’un de ces coups de génie qui paraissent évidents après coup
    Quand on voit un résultat aussi convaincant obtenu en assemblant à la main des composants individuels relativement primitifs, on se demande pourquoi, d’ici Noël prochain, il n’y aurait pas une version couleur haute résolution vendue sur Amazon par une obscure marque de dropshipping au nom de 7 lettres

    • Ce n’est pas une idée nouvelle, cela s’appelle un affichage volumétrique à balayage et cela existe depuis longtemps [1]
      Mais la plupart ne sont guère plus que des gadgets. Si tout ce qu’on peut faire, c’est une surface lumineuse transparente qu’on ne peut pas toucher, les usages réels restent limités
      On peut aussi voir des versions bien plus grandes, non rotatives, faites avec des LED suspendues à des câbles [2] ; c’est très impressionnant, mais l’effet de nouveauté s’estompe vite, et on se rend compte que ce n’est pas un écran destiné à des usages productifs
      Si l’on veut une véritable visualisation 3D permettant un rendu de haute qualité et de l’interaction, des casques VR/AR semblent plus adaptés. Il existe aussi de nouveaux moniteurs 3D sans lunettes, mais peu de gens les ont encore vus en vrai
      On arrivera peut-être à fabriquer un jouet vendable sur Amazon, mais je ne suis pas certain qu’il y ait une killer app pour ce genre d’objet
      [1] https://en.wikipedia.org/wiki/Volumetric_display#Swept-volum...
      [2] https://www.ledpulse.com/
    • Pour un écran de 32 pouces, j’ai l’impression que le moteur devrait tourner à une vitesse énorme sur une zone de pi*32^2
  • C’est vraiment un super petit projet. Il faut absolument regarder les autres projets aussi. Certains avaient déjà été postés sur HN il y a longtemps
    https://mitxela.com/projects/hardware
    Personnellement, mon préféré est le sifflet coulissant MIDI

    • En voyant le projet d’ampli casque[0], ça m’a un peu rappelé le livre Schiit Happened
      [0] https://mitxela.com/projects/headphone_amps
    • Exact, il y avait aussi le projet qui convertissait du HDMI en affichage OLED, et c’était vraiment dingue
  • C’est créatif. J’ai peut-être la persévérance et l’intérêt nécessaires pour mener ce genre de chose jusqu’au bout, mais il me manque l’imagination pour concevoir un projet aussi génial
    Heureusement qu’il y a Internet, qui permet de voir les choses impressionnantes que les gens créent

    • C’est une méthode que Tom 7 a évoquée dans l’une de ses vidéos : tenir une liste d’idées et tout noter dès qu’une pensée surgit, même si elle paraît idiote. Le tri vient plus tard
      Comme ça, quand on a l’énergie pour se lancer dans un projet, on ne la gaspille pas à chercher une idée
      Ça change énormément la quantité de choses qu’on peut réellement terminer dans un side project. Il est probable qu’on ait plus d’idées intéressantes qu’on ne le pense. Le problème, c’est que si le moment où l’idée apparaît ne coïncide pas avec celui où l’on a le temps et l’énergie de l’exécuter ou de la développer, elle disparaît
    • J’ai le problème inverse. Les idées créatives continuent d’arriver, et au moment où je suis en train de faire un prototype v1 ou v2 de l’idée A, l’idée B surgit et m’empêche de pousser A jusqu’au bout
      Et même si on acquiert de la persévérance et de la discipline, il faut ensuite payer les factures, donc la distraction n’est plus l’idée B mais simplement le travail ordinaire
    • La créativité peut aussi se travailler comme n’importe quelle autre compétence :)
      Je suis d’accord sur le fait de noter les choses. Comme pour la plupart des activités, si on s’exerce sérieusement, on s’améliore
      Ce qu’on néglige souvent, c’est (1) les connaissances techniques, (2) l’invention systématique, (3) la motivation
      Les connaissances techniques permettent de savoir si un projet est possible, ou économiquement viable, et de cartographier les obstacles sur le chemin. Une invention impossible n’a pas beaucoup d’utilité
      L’invention systématique, c’est examiner les choses de manière structurée plutôt que d’attendre une illumination au hasard. Par exemple, analyser (a) « je veux fabriquer un affichage volumétrique » et (b) « je veux donner vie à un objet 3D virtuel ». Il y a une nuance subtile entre les deux
      L’affichage volumétrique (a) recouvre tout un éventail, depuis les light field displays au fondement théorique élégant jusqu’à l’affichage volumétrique par persistance rétinienne montré ici. Si on étudie en profondeur l’espace du problème, on finira probablement par atteindre les solutions possibles
      Donner vie à un objet 3D (b) peut désigner un espace de problèmes bien plus vaste : fabrication numérique, lunettes VR, interaction haptique, robotique, etc.
      La motivation est aussi vraiment importante. Comprendre pourquoi on invente et ce qu’on veut faire exister dans le réel a beaucoup de sens. Par exemple : apporter de la joie aux gens, faire quelque chose de simplement très cool, ou créer un dispositif médical utile qui pourrait sauver des vies
      On peut aussi apprendre à se concentrer sur des sujets qui en valent la peine, et cela améliore beaucoup les capacités d’invention. Bien sûr, fabriquer des choses simplement parce qu’on les aime reste important et tout à fait valable :)
      Personnellement, la partie la plus importante, c’est de prendre du plaisir dans le processus
  • C’est très proche du fonctionnement des ventilateurs holographiques. Toute l’électronique se trouve dans la partie rotative
    Ces ventilateurs utilisent souvent le transfert d’énergie sans fil pour alimenter la carte du haut
    https://youtu.be/bT716nyK0AY

  • Si vous êtes à Londres ou de passage, l’exposition de 180 Studios [1] utilise souvent ce type de technologie dans ses shows artistiques
    Si vous vous intéressez à l’art et à la technologie, ça vaut le détour
    [1] https://www.180studios.com/

    • Intéressant. Est-ce qu’il existe aussi des musées art x technologie aux États-Unis ?
  • Si vous aimez ce genre de choses, c’est une excellente chaîne YouTube
    Je me demande s’il serait possible de rafraîchir des écrans OLED bon marché assez vite pour obtenir une résolution bien plus élevée. C’est peut-être faisable, mais l’espace entre les segments radiaux risque d’être bien plus grand que le pas des pixels, donc le résultat pourrait au contraire paraître pire

  • Le problème de centrage pourrait sans doute être résolu en plaçant deux cartes LED au-dessus, dos à dos
    On pourrait aussi décaler les LED d’une demi-largeur sur l’une des cartes pour créer un effet d’entrelacement et doubler en même temps la résolution

    • Ou alors il suffit de ne pas centrer, et de modifier les équations pour tenir compte du fait que les LED ne sont pas au centre
    • Il devrait sûrement y avoir un moyen de remplacer la structure qui fait tourner la rangée de LED par quelque chose de plus léger. Des miroirs, ou une matrice de guides de lumière en acrylique, par exemple ?
  • S’il existait une version RGB plus grande, quelque chose comme 50x50, suffisamment robuste, et capable d’afficher différentes images sans programmation, je serais prêt à payer plus de 200 dollars

    • Ce n’est pas un affichage volumétrique, mais c’est quand même très cool, et ça pourrait convenir à certains usages : https://spinprojector.com/
  • Il y a aussi un autre chouette projet d’affichage volumétrique, publié récemment mais passé plutôt inaperçu
    https://news.ycombinator.com/item?id=38406824