Table des matières:

Matrice LED RVB : 5 étapes
Matrice LED RVB : 5 étapes

Vidéo: Matrice LED RVB : 5 étapes

Vidéo: Matrice LED RVB : 5 étapes
Vidéo: LED-матрицы для видео-экранов 2024, Juillet
Anonim
Image
Image
Conception de matériel
Conception de matériel

Recherchez Instructable, et vous pouvez trouver de nombreux projets de matrice LED. Aucun d'entre eux n'était tout à fait ce que je voulais, c'est-à-dire explorer les interactions de la conception matérielle et logicielle pour produire quelque chose, et produire le produit final dans un PCB soigné avec un pilote qui me permet de dessiner sur "l'écran LED" en utilisant un haut niveau constructions (par exemple, tracer une ligne au lieu de définir des pixels spécifiques). Cette partie était importante pour moi, car de nombreux pilotes matriciels LED sont simples et ne fournissent pas grand-chose en termes de création par programmation d'une image ou d'une animation. Cela ne signifie pas que vous ne pouvez pas créer d'images et d'animations avec les autres pilotes, mais simplement que vous auriez à faire un travail plus répétitif d'un projet à l'autre.

Alors je me suis mis à accomplir ma vision. La première étape consistait à concevoir le matériel. C'était probablement le plus difficile pour moi, car mon expérience est plus logiciel. Encore une fois, il y avait de nombreux modèles pré-cuisinés, et je les ai certainement utilisés pour m'inspirer, mais je voulais apprendre en faisant, alors j'ai prototypé une matrice 4x4 sur une planche à pain. J'ai beaucoup appris grâce à ce processus, car mes premières itérations n'ont pas fonctionné. Mais j'ai fait une conception matérielle qui a fonctionné, ce qui m'a permis de commencer à développer un pilote.

J'ai choisi l'Arduino comme plate-forme de pilotes car il est largement disponible et contient de nombreuses références en ligne. Bien que l'expérience professionnelle m'ait permis d'obtenir une version fonctionnelle d'un pilote plus facilement que mes efforts matériels, il y avait encore beaucoup d'itérations pendant que j'optimisais les performances du pilote pour le microcontrôleur ATMega et développais une API de programmation que j'aimais.

Ce Instructuctable documente la conception et certains enseignements clés de mon projet. Vous trouverez plus d'informations sur ce projet sur mon site Web ici, y compris des kits complets que vous pouvez acheter pour créer votre propre matrice LED RVB.

Étape 1: Conception du matériel

L'objectif principal de ma conception matérielle était de créer une gamme de LED RVB que je pouvais programmer, mais je ne voulais pas non plus dépenser beaucoup d'argent. L'approche sur laquelle j'ai opté consistait à utiliser des registres à décalage 74HC595 pour contrôler les LED. Afin de minimiser le nombre de registres à décalage nécessaires, j'ai disposé les LED RVB dans une disposition matricielle où les anodes communes étaient liées ensemble en rangées et les fils cathodiques rouge, vert et bleu étaient liés ensemble en colonnes. Pour la matrice 4x4, le schéma de circuit ressemblait au schéma de circuit ci-joint.

Une chose que vous remarquerez tout de suite est qu'étant donné le circuit matriciel, il existe certaines configurations d'éclairage LED qui ne peuvent pas être réalisées avec toutes les LED souhaitées allumées en même temps. Par exemple, la matrice ne peut pas allumer simultanément deux LED qui sont en diagonale l'une de l'autre car l'alimentation des lignes et des colonnes provoquera l'allumage des deux LED opposées sur la diagonale perpendiculaire aux LED souhaitées. Afin de contourner ce problème, nous utiliserons le multiplexage pour parcourir chaque ligne. Il existe de nombreuses ressources sur le web qui couvrent la technique du multiplexage, je ne vais pas essayer de les reproduire ici.

Étant donné que j'utilise des LED à anode communes, cela signifie que les rangées fournissent une alimentation positive et que les colonnes tombent à la terre. La bonne nouvelle est que les registres à décalage 74HC595 peuvent à la fois fournir et absorber de l'énergie, mais la mauvaise nouvelle est qu'ils ont une limite sur la quantité d'énergie qu'ils peuvent fournir ou absorber. Les broches individuelles du 74HC595 ont une consommation de courant maximale de 70 mA, mais il est préférable de conserver moins de 20 mA. Les couleurs individuelles de nos LED RVB ont chacune un tirage d'environ 20 mA. Cela signifie que le 74HC595 ne peut pas alimenter directement une rangée entière de LED si je souhaite les allumer toutes.

Ainsi, au lieu d'alimenter la rangée directement, le 74HC595 pilotera à la place un transistor pour chaque rangée, et le transistor activera ou désactivera le courant alimentant la rangée. Étant donné que la conception utilise une LED d'anode commune, le transistor de commutation sera PNP. Si nous utilisions une LED à cathode commune, le transistor de commutation serait NPN. Notez qu'avec l'utilisation d'un transistor PNP pour piloter une rangée, le réglage du registre à décalage pour l'activer devient maintenant bas car un transistor PNP a besoin d'une tension négative entre l'émetteur et la base pour être activé, ce qui permettra à un courant positif de circuler dans le ligne.

Une autre chose à considérer est la disposition des bits souhaitée des registres à décalage. C'est-à-dire, parmi les registres à décalage, quels bits contrôlent quelles lignes ou colonnes dans la matrice. La conception avec laquelle j'ai envoyé est l'endroit où le premier bit, ou "bit le plus significatif", envoyé aux registres à décalage en guirlande contrôle l'élément rouge de la colonne de LED, le deuxième bit contrôle l'élément vert de la première colonne, le troisième bit contrôle l'élément de la première colonne élément bleu, le quatrième bit contrôle l'élément rouge de la deuxième colonne, … ce motif est répété dans les colonnes de gauche à droite. Ensuite, le prochain bit envoyé contrôle la dernière ligne ou la dernière ligne, la suivante l'avant-dernière ligne, … cela se répète jusqu'à ce que le dernier bit envoyé, ou "bit le moins significatif", contrôle la première ou la première ligne de la matrice.

Enfin, je devais déterminer quelles résistances j'utiliserais pour chacune des LED de la LED RVB. Bien que vous puissiez utiliser la formule standard qui combine la tension directe et le courant souhaité pour calculer la résistance requise, j'ai constaté que le réglage du courant de chaque LED à 20 milliampères entraînait une couleur blanc cassé lorsque toutes les LED rouges, vertes et bleues étaient allumées. Alors j'ai commencé à l'observer. Trop de rouge dans le blanc signifiait augmenter les ohms de la résistance de la LED rouge pour réduire le courant. J'ai répété l'échange de résistances d'ohms différents jusqu'à ce que je trouve une combinaison qui produise une couleur blanche qui me semble correcte. La combinaison finale était de 180 pour la LED rouge, 220 pour la LED verte et 100 pour la LED bleue.

Étape 2: Construction de matériel - Planche à pain

Construction de matériel - Planche à pain
Construction de matériel - Planche à pain
Construction de matériel - Planche à pain
Construction de matériel - Planche à pain

La première phase du constructeur de matériel était la planche à pain. Ici, j'ai fait une matrice 4x4 avec les LED RGB. Cette matrice nécessiterait 16 bits à contrôler, 12 pour les colonnes RVB et 4 pour chaque ligne. Deux registres à décalage 74HC595 peuvent tout gérer. J'ai d'abord recherché et conçu un circuit qui, selon moi, fonctionnerait, puis je l'ai construit sur la maquette.

Le plus gros défi de la construction de la maquette était probablement la gestion de tous les fils. J'ai ramassé un kit de fil préformé pour les planches à pain, mais il était alors un peu difficile à manier. Une astuce que j'ai trouvée utile était de créer un "port" pour se connecter à la carte Arduino. Autrement dit, plutôt que de connecter les broches de l'Arduino directement aux différentes broches IC de la maquette, dédiez quelques lignes sur la maquette au point de connexion de l'Arduino, puis connectez les broches d'identification pertinentes à ces lignes. Pour ce projet, vous n'avez besoin que de cinq connexions à l'Arduino: +5V, masse, données, horloge et verrou.

Une fois la construction de la maquette terminée, je devais la tester. Cependant, sans une sorte de pilote pour envoyer les bons signaux aux registres à décalage, je n'ai pas pu tester pour voir si la configuration matérielle fonctionnait.

Étape 3: Conception du logiciel du pilote

Image
Image

Compte tenu de ma propre expérience professionnelle dans le développement de logiciels, c'était la partie du projet que j'étais probablement la plus claire sur la voie à suivre. J'ai interrogé de nombreux autres pilotes matriciels LED basés sur Arduino. Bien qu'il existe certainement de bons pilotes disponibles, aucun n'avait le design que je voulais. Mes objectifs de conception du pilote étaient:

  • Fournissez une API de haut niveau pour pouvoir créer des images et des animations par programmation. La plupart des pilotes que j'ai vus étaient plus concentrés sur les images codées en dur. De plus, étant programmeur C++ de formation, je voulais utiliser une bonne conception orientée objet pour mettre en œuvre et gérer les activités de dessin sur la matrice LED.
  • Utilisez une approche à double tampon pour gérer l'image à l'écran. Un tampon est ce qui est dessiné par programme, tandis que l'autre représente l'état des pixels de la matrice à un moment donné. L'avantage de cette approche est que vous n'êtes pas obligé de restituer complètement la prochaine mise à jour de trame pour l'écran entre les cycles de mise à jour du multiplexage.
  • Utilisez PWM pour autoriser plus que les sept couleurs primitives qu'un RVB peut rendre grâce à des combinaisons simples des éléments rouge, vert et bleu.
  • Ecrivez le pilote de telle sorte qu'il "fonctionne" simplement avec des matrices de LED RVB de différentes tailles qui suivent mon approche générale de conception de matrice. Notez que bien que ma conception matérielle utilise des registres à décalage 74HC595, je m'attendrais à ce que mon pilote fonctionne avec n'importe quel mécanisme d'activation/désactivation de style registre à décalage qui est conçu à l'aide d'une disposition de bits similaire à celle de ma conception matérielle. Par exemple, je m'attendrais à ce que mon pilote fonctionne avec une conception matérielle utilisant des puces DM13A pour contrôler les colonnes et une puce 74HC595 pour contrôler les lignes.

Si vous souhaitez consulter directement le code du pilote, vous pouvez le trouver sur GitHub ici.

La première itération de mon pilote était un peu une courbe d'apprentissage sur les capacités de la plate-forme Arduino. La limitation la plus évidente est la RAM, qui est de 2K octets pour les Arduino Uno et Nano. L'utilisation d'objets C++ dans un tel scénario est souvent déconseillée en raison de la surcharge mémoire des objets. Cependant, je sentais que si c'était bien fait, les avantages des objets en C++ l'emportaient sur leur coût (en RAM).

Le deuxième défi majeur consistait à déterminer comment implémenter la modulation de largeur d'impulsion via les registres à décalage afin que je puisse générer plus que les sept couleurs primitives de la LED RVB. Ayant programmé pendant de nombreuses années sur des plates-formes Linux, j'avais l'habitude d'utiliser des constructions telles que des threads pour gérer des processus nécessitant un timing cohérent. La synchronisation de l'opération de mise à jour du registre à décalage finit par être assez critique lors de la création d'un pilote pour une matrice de LED qui utilise le multiplexage. La raison en est que même si le multiplexage se produit si rapidement que vos yeux ne peuvent pas voir les LED individuelles clignoter, vos oui peuvent détecter des différences dans le temps total cumulé pendant lequel l'une des LED est allumée. Si une rangée de LED est constamment allumée pendant une période plus longue que les autres, elle paraîtra plus lumineuse pendant le multiplexage. Cela peut entraîner une luminosité inégale dans la matrice ou un échantillonnage périodique de la matrice dans son ensemble (cela se produit lorsqu'un cycle de mise à jour prend plus de temps que les autres).

Étant donné que j'avais besoin d'un mécanisme de synchronisation cohérent pour que les mises à jour du registre à décalage soient consenties, mais que l'Arduino ne prend pas officiellement en charge le thread, j'ai dû créer mon propre mécanisme de type thread. Ma première itération consistait simplement à créer un minuteur de boucle qui dépendait de la fonction Arduino loop() et déclencherait une action lorsqu'un certain laps de temps s'était écoulé depuis la dernière fois que l'action avait été déclenchée. Il s'agit d'une forme de « multitâche coopérative ». Cela semble bien, mais en pratique, cela s'est avéré incohérent lorsque la cadence de tir a été mesurée en microsecondes. La raison en est que si j'avais deux de ces minuteries en boucle, l'une de leurs actions prenait souvent assez de temps pour que la deuxième action se déclenche plus tard que souhaité.

J'ai trouvé que la solution à ce problème consiste à utiliser le mécanisme d'interruption d'horloge natif d'Arduino. Ce mécanisme vous permet d'exécuter un petit morceau de code à des intervalles très cohérents. J'ai donc conçu le code du pilote autour de l'élément de conception consistant à utiliser une interruption d'horloge pour déclencher le code permettant d'envoyer aux registres à décalage de la matrice la prochaine mise à jour du cycle de multiplexage. Pour ce faire et permettre aux mises à jour de l'image de l'écran de ne pas interférer avec un vidage actif dans les registres à décalage (quelque chose que nous appellerions une "condition de course"), j'ai utilisé une approche consistant à avoir des tampons jumeaux pour les bits du registre à décalage, un pour l'écriture et une pour la lecture. Lorsque l'utilisateur met à jour l'image matricielle, ces opérations se produisent dans le tampon d'écriture. Lorsque ces opérations sont terminées, les interruptions sont temporairement suspendues (cela signifie que l'interruption d'horloge ne peut pas se déclencher) et le tampon d'écriture est échangé avec le tampon de lecture précédent et ce n'est pas le nouveau tampon de lecture, puis les interprétations sont réactivées. Ensuite, lorsque l'interruption d'horloge se déclenche, indiquant qu'il est temps d'envoyer la configuration de bit suivante aux registres à décalage, ces informations sont lues à partir du tampon de lecture actuel. De cette façon, aucune écriture ne se produit jamais dans un tampon qui pourrait être en cours de lecture pendant une interruption d'horloge, ce qui pourrait corrompre les informations envoyées aux registres à décalage.

La conception du reste du pilote était un cas relativement simple de conception orientée objet. Par exemple, j'ai créé un objet pour gérer l'image binaire du registre à décalage pour un état d'écran donné. En encapsulant le code relatif à la gestion de l'image binaire, la création de l'approche des tampons jumeaux susmentionnée était en soi un exercice simple. Mais je n'ai pas écrit ce Instructable pour vanter les vertus de la conception orientée objet. Un autre élément de conception comprend le concept d'un glyphe et d'une image RVB. Un glyphe est une construction d'image de base qui n'a pas d'informations de couleur innées. Vous pouvez le considérer comme une image en noir et blanc. Lorsque le glyphe est dessiné sur l'écran LED, des informations de couleur sont fournies pour indiquer comment les pixels "blancs" doivent être colorés. Une image RVB est une image où chaque pixel a sa propre information de couleur.

Je vous encourage à consulter les exemples de croquis Arduino et à consulter la documentation de l'en-tête du pilote pour vous familiariser avec l'utilisation du pilote pour créer des images et des animations sur une matrice LED RVB.

Étape 4: Fantôme LED

Fantôme LED
Fantôme LED
Fantôme LED
Fantôme LED

Dans une matrice de LED, le "fantôme" est le phénomène d'une LED dans la matrice qui brille lorsque cela n'est pas souhaité, généralement à un niveau très réduit. Ma conception matérielle d'origine était sensible aux images fantômes, notamment dans la dernière rangée. La cause de cela est due à deux choses: les transistors ne s'éteignent pas immédiatement et une capacité parasite dans les LED RVB.

Lorsque nous balayons les lignes, du fait que les transistors ne s'éteignent pas immédiatement, la ligne précédente du cycle de balayage est toujours partiellement alimentée lorsque la ligne suivante est activée. Si une colonne donnée qui était éteinte dans la rangée précédente est nouvellement allumée lorsque la nouvelle rangée est alimentée, la LED de cette colonne de la rangée précédente s'allumera pendant un court instant pendant que le transistor de commutation de cette rangée précédente est toujours en train de tourner. désactivé. Ce qui fait que le transistor met un temps considérable à s'éteindre, c'est la saturation de la base du transistor. Cela amène le chemin collecteur-émetteur du transistor à continuer à conduire lorsque le courant est retiré de la base, au moins jusqu'à ce que la saturation se dissipe. Étant donné que notre cycle de mise à jour de multiplexage provoque l'activation volontaire des lignes pendant une période mesurée en microsecondes, la durée pendant laquelle le transistor saturé de la ligne précédente reste conducteur peut être une fraction notable de celle-ci. En conséquence, votre œil peut percevoir cette très petite quantité de temps pendant laquelle la LED de la rangée précédente est allumée.

Pour résoudre le problème de saturation du transistor, une diode Schottky peut être ajoutée au transistor entre la base et le collecteur pour provoquer un petit retour de courant vers la base lorsque le transistor est allumé, empêchant le transistor de se saturer. Cela entraînera à son tour la désactivation du transistor plus rapidement lorsque le courant est retiré de la base. Voir cet article pour une explication détaillée de cet effet. Comme vous pouvez le voir sur l'image de cette section, sans la diode, les images fantômes sont assez perceptibles, mais l'ajout de la diode au circuit pour chaque rangée supprime considérablement les images fantômes.

Les LED RVB sont sensibles à un autre phénomène appelé capacité parasite. La cause principale de ceci est le fait que chacune des trois LED de couleur de l'unité LED RVB a chacune des tensions directes différentes. Cette différence de tensions directes peut provoquer l'effet de la capacité électrique entre chacune des couleurs de LED individuelles. Étant donné qu'une charge électrique s'accumule dans l'unité LED lorsqu'elle est alimentée, lorsque l'alimentation est coupée, la capacité parasite doit être déchargée. Si la colonne LED de cette colonne est allumée pour l'alimentation d'une autre rangée, la charge parasite se déchargera à travers la LED de cette colonne et la fera briller brièvement. Cet effet est bien expliqué dans cet article. La solution est d'ajouter un chemin de décharge pour cette charge parasite autrement que par la LED elle-même, puis de laisser le temps à la LED de se décharger avant que la colonne ne soit à nouveau alimentée. Dans ma conception matérielle, cela est accompli en ajoutant une résistance à la ligne électrique de chaque rangée qui relie la force à la terre. Cela entraînera une consommation accrue de courant lorsque la rangée est alimentée, mais fournit un chemin de décharge pour la capacité parasite lorsque la rangée n'est pas alimentée.

Il convient toutefois de noter qu'en pratique, je trouve que l'effet de la capacité parasite est à peine perceptible (si vous le cherchez, vous pouvez le trouver), et je considère donc que l'ajout de cette résistance supplémentaire est facultatif. L'effet du temps de ralentissement pour les transistors saturés est beaucoup plus fort et perceptible. Néanmoins, si vous inspectez les trois photos fournies dans cette section, vous pouvez voir que les résistances suppriment complètement les images fantômes qui se produisent encore au-delà des temps d'arrêt lents du transistor.

Étape 5: Fabrication finale et prochaines étapes

Image
Image

La phase finale de ce projet était pour moi de créer une carte de circuit imprimé (PCB). J'ai utilisé le programme open source Fritzing pour concevoir mon PCB. Bien qu'il y ait eu beaucoup de tâches répétitives à accomplir pour disposer 100 LED sur une carte 10x10, j'ai en fait trouvé cette phase du projet étrangement satisfaisante. Déterminer comment chaque voie électrique serait disposée était comme un casse-tête, et résoudre ce casse-tête a créé un sentiment d'accomplissement. Comme je ne suis pas configuré pour fabriquer les circuits imprimés, j'ai utilisé l'une des nombreuses ressources en ligne qui font de petites séries de circuits imprimés personnalisés. Souder les pièces ensemble était assez simple puisque ma conception utilisait toutes les pièces traversantes.

Au moment d'écrire ce Instructable, j'ai les plans suivants pour mes projets de ma matrice LED RVB:

  1. Continuez à améliorer le pilote au niveau de la couche API pour permettre au programmeur de bénéficier de fonctionnalités de plus haut niveau, notamment le défilement de texte.
  2. Créez des conceptions matricielles plus grandes, telles que 16x16 ou même 16x32.
  3. Explorez l'utilisation de MOSFET au lieu de BJT pour la commutation de puissance de ligne
  4. Explorez l'utilisation des pilotes à courant constant DM13A plutôt que les 74HC595 pour la commutation de colonne
  5. Créez des pilotes pour d'autres plates-formes de microcontrôle, telles que Teensy, ODROID C2 ou Raspberry Pi.

Notez que la conception matérielle et le pilote ont été publiés sous la licence open source GPL v3 dans ce référentiel GitHub. De plus, puisque même si les fabricants de PCB font de "petites séries" de ma conception de PCB, j'obtiens toujours beaucoup plus que ce dont j'ai personnellement besoin. Je vends donc des kits complets pour mes différentes conceptions de matrice LED RVB (PCB et toutes les pièces incluses) à partir de mon site Web ici.

Conseillé: