ContrĂ´leur DIY de panneau LED sur CPLD utilisant la modulation BAM

Il y a quelque temps, il a participé à une discussion sur le projet DIY d'une montre à matrice LED.
Et ce qui m'a surpris - l'ancienne matrice LED monochromatique 8x8 avec un pas de 5 millimètres a été utilisée comme dispositif d'affichage. De plus, des cartes de circuits imprimés complexes ont été créées pour eux, une indication dynamique douce a été faite. Et c'est à un moment où les panneaux LED 64x32 polychromes prêts à l'emploi avec un pas de 3 mm sont disponibles depuis longtemps au prix de 10-20 $. Et l'assortiment général de ces panneaux est très grand et a un pas de pixel de 2 à 10 mm et presque toutes les tailles.

Dans le même temps, l'utilisation de tels panneaux dans des conceptions de bricolage est assez difficile - les contrôleurs prêts à l'emploi coûtent beaucoup d'argent et n'ont pas d'API normale. Il est assez difficile de faire un scan assez rapide du panneau sur des microcontrôleurs couramment utilisés en DIY. De plus, les intervalles de temps doivent être maintenus avec une grande précision - sinon une inégalité notable de luminosité commence.

Il existe de bonnes solutions chez Adafruit , mais elles sont toutes assez coûteuses et complexes.

Après réflexion, l'idée est venue - pourquoi ne pas créer une carte extrêmement peu coûteuse qui sera un pont entre une carte penny ordinaire comme un arduino et un panneau LED? Après quelques mois d'agitation, quelque chose de fonctionnel est né.

Cet article décrit la deuxième version améliorée du contrôleur.

Défi


En tant que tâche de base, je voulais pouvoir contrôler un panneau d'une taille totale d'au moins 64x64, tout en ayant la possibilité de travailler au moins en Highcolor (RGB565) tout en maintenant un taux de rafraîchissement d'écran acceptable (au moins 50 Hz). Dans la première version du contrôleur, la tâche de base a été entièrement mise en œuvre, mais l'idée est venue de mettre en œuvre la tâche par une autre méthode très prometteuse, à partir de laquelle la deuxième version est née.

Explication de base de la conception d'un panneau LED typique


Interface d'entrée HUB75:


À chaque entrée de couleur, il y a une chaîne de registres du type HC595 (mais des versions spéciales à 16 canaux pour les LED). Il y a tellement de registres qui sont suffisants pour la largeur du panneau. Les autorisations de destruction, de démarrage parallèle et de sortie sont communes à tous les registres. Les entrées ABCDE - c'est le choix d'une série - vont vers un décodeur classique.

Principe de fonctionnement:

  • dĂ©finissez les donnĂ©es sur les entrĂ©es RVB, cliquez sur le bouton CLK. RĂ©pĂ©tez jusqu'Ă  ce que nous chargions toute la ligne
  • dĂ©sactiver les sorties OE = 1 (pour qu'il n'y ait pas d'interfĂ©rence)
  • donner au dĂ©codeur le numĂ©ro de la ligne chargĂ©e
  • cliquez sur charge parallèle LAT - les donnĂ©es de ligne sont transfĂ©rĂ©es vers les registres de sortie
    activer les sorties OE = 0
  • rĂ©pĂ©ter pour la ligne suivante

C'est une indication dynamique classique. Il est clair qu'avec cette méthode dans un tel cycle, nous ne pouvons allumer / éteindre que chaque LED spécifique.

Afin d'obtenir des gradations de luminosité avec PWM classique, un tel cycle doit être répété N-1 fois, où N est le nombre de gradations de luminosité (256 pour RGB888). Et étant donné qu'en même temps, il scintille toujours - tout cela doit être fait très, très rapidement.

Il existe une solution de contournement: la modulation d'angle de bit (BAM). Dans ce cas, le temps de lueur dans chaque cycle est proportionnel au poids du bit affiché. Autrement dit, pour RGB888, vous n'avez besoin que de 8 cycles d'affichage. Un peu plus en détail ici .

La première version du contrôleur utilisait le PWM classique, qui imposait une limite stricte sur le nombre de cycles de balayage. Dans la deuxième version, BAM est implémenté, ce qui a donné un énorme gain de vitesse.

Implémentation


Il était évident qu'un microcontrôleur conventionnel ne tire que de petits panneaux - les grands n'ont tout simplement pas assez de vitesse. Par conséquent, CPLD ou FPGA est indispensable ici - il est physiquement impossible de produire des dizaines de Mo / s sur des microcontrôleurs à faible coût.

En tant que mémoire, j'ai été recommandé sur le forum IXBT par la très intéressante mémoire FIFO Averlogic AL422B, qui a environ 400 Ko de mémoire et peut fonctionner à des fréquences allant jusqu'à 50 MHz.

Étant donné que ma principale exigence était le faible coût maximum des composants, afin que l'écharpe finie soit accessible aux fabricants de produits maison, l'Altera EPM3064 - CPLD avec 64 macrocellules a été choisie. En même temps, un si petit nombre de macrocellules ne permet pas de créer une carte configurable dynamiquement - la configuration doit être compilée directement dans CPLD.

→ Le circuit résultant se trouve ici

Détails:

  • CPLD EPM3064ATC44-10 - le prix d'Ali est d'environ 13-15 $ pour une douzaine
  • FIFO RAM AL422B - le prix d'Ali est d'environ 15 $ la douzaine
  • Oscillateur Ă  cristal 50 MHz. La carte permet l'installation dans des boĂ®tiers DIP14 / DIP8 / 7050. Le prix d'Ali est d'environ 6-7 $ la douzaine
  • Stabilisateur 3,3 V dans le boĂ®tier SOT223. Prix ​​en Chip and Dip - 40r chacun
  • Connecteur IDC-10MS. Prix ​​en Chip & Dip - 3 p / pièce
  • Connecteur IDC-16MS. Prix ​​en Chip & Dip - 8 r / pièce
  • Connecteur IDC-14MS. Prix ​​en Chip & Dip - 7 r / pièce
  • Condensateurs 1 microfarad 0805 - 8 pièces d'environ 1 r / pièce
  • Condensateur 0.1uF 0805 - environ 1 r / pièce
  • RĂ©sistance 10k 0805 - un sou

Le total en détail est obtenu 1,5 + 1,5 + 0,7 = 3,7 $ et 40 + 3 + 8 + 7 + 8 * 1 + 1 = 67 p. Tous ensemble dans 5 $ - un sou.

→ L'image originale du tableau est ici

→ Fichiers Gerber préparés pour la commande

La carte est préparée pour la première version, dans laquelle il n'y avait pas de contrôle RE. Pour l'utiliser avec la deuxième version, vous devez couper le cavalier entre les bornes 23 et 24 de AL422B et jeter les fils de la borne 28 de EPM3064 (il est amené au bornier) à la borne 24 de AL422B.

Lors du soudage de la carte, n'oubliez pas de souder les cavaliers d'alimentation à l'arrière de la carte.





Calculs


Les calculs des paramètres requis sont assez compliqués.

Le fait est que dans le contrôleur, deux processus sont exécutés en parallèle - chargement des données de la ligne suivante / indiquant une ligne déjà chargée.

Les processus démarrent simultanément, mais se terminent à des moments différents, donc un processus plus rapide attend l'achèvement d'un processus plus long.

→ Une tablette Excel a été réalisée pour le calcul

Données sources:

  • CRYSTAL_FRQ (MHz) - frĂ©quence du gĂ©nĂ©rateur (50 MHz)
  • PIXEL_COUNT - le nombre de pixels dans la barre de tĂ©lĂ©chargement. Plus de dĂ©tails dans la section commutation.
  • RGB_INPUTS - le nombre d'entrĂ©es RGB utilisĂ©es dans l'interface HUB75E du panneau utilisĂ©. 1 ou 2
  • BYTES_PER_PIXEL - octets par pixel. Dans notre cas, toujours 3 - RGB888
  • SCAN_LINES - nombre de lignes de numĂ©risation dans le panneau utilisĂ©. 16/08/32

Paramètres sélectionnés:

  • PRE_DELAY - dĂ©lai entre le signal LAT et la mise sous tension de l'OE, dĂ©fini par ticks
  • PRESCALER - Prescaler pour le compteur principal. Autrement dit, si la liste de prix est 8 et que le poids du bit actuel est 4, OE sera activĂ© pendant 8 * 4 = 32 cycles
  • POST_DELAY - dĂ©lai minimum entre la mise hors tension de l'OE et le signal LAT suivant, dĂ©fini par ticks

Par exemple, nous avons un panneau 32x32 qui a 8 lignes de balayage et 2 entrées RVB. Un tel panneau a deux connecteurs HUB75E, c'est-à-dire que physiquement ce sont deux panneaux 32x16. Nous connectons ces panneaux en série, c'est-à-dire que ce panneau ressemblera logiquement à 64x16.

PRE_DELAY et POST_DELAY sont des intervalles de suppression avant et après l'activation de la sortie (OE) afin que les multiplexeurs puissent commuter les sorties et les touches ouvrir / fermer. Sans eux, il y aura des «astuces» de la gravure des pixels aux lignes adjacentes. Les valeurs sont sélectionnées expérimentalement pour un panneau particulier. Habituellement, 15 mesures sont suffisantes (fixées en mesures).

Cela soulève la question du choix du prescaler - comment le choisir.

Une valeur de mise à l'échelle faible donne un temps d'affichage d'image court, mais réduit la luminosité globale. La valeur élevée du détartreur augmente le temps d'affichage de la trame, c'est-à-dire que lorsqu'il énumère, il scintille à l'écran.

Essayons PRESCALER = 1

Nous obtenons:

OE_EFFICIENCE - 8,3%, c'est-à-dire que le panneau ne fonctionnera que 8,3% de la luminosité maximale possible
FRAMES_PER_SECOND - 2034 ips - mais le taux de rafraîchissement de l'image sera énorme - plus de 2000 ips.

La perte de luminosité est déjà très importante.

Essayons PRESCALER = 16

Nous obtenons:

OE_EFFICIENCE - 72,9% c'est-à-dire que le panneau fonctionnera à 72,9% de la luminosité maximale possible
FRAMES_PER_SECOND - 1117 - et le taux de rafraîchissement de l'image est très bon - plus de 1000 fps.
Eh bien, c'est tout à fait normal - une efficacité de plus de 50% est tout à fait normale et la fréquence d'images est très bonne.

La règle générale est que PRESCALER est environ 8 fois plus petit que le produit PIXEL_COUNT * RGB_INPUTS

Eh bien, continuez de compter et de vérifier.

Commutation des panneaux LED


Tous les panneaux sont connectés en série. Schéma de connexion: d'abord de droite à gauche, puis de bas en haut. Autrement dit, nous connectons d'abord les horizontales en série, puis la sortie de la rangée du bas à l'entrée de la deuxième rangée du bas, etc. à la rangée supérieure.

Le contrôleur s'accroche au panneau inférieur droit.

Il y a des panneaux qui ont deux connecteurs d'entrée et deux de sortie. De tels panneaux ne sont essentiellement qu'un assemblage mécanique de deux panneaux verticalement. Commutée en deux panels indépendants.

Après l'assemblage, nous devons calculer la longueur totale de la chaîne en pixels - pour cela, nous regardons - combien de panneaux totaux étaient dans la chaîne et multiplier ce nombre par la largeur du panneau en pixels. Ce nombre devra ensuite être introduit dans la valeur PIXEL_COUNT pendant la configuration CPLD et dans le calculateur de synchronisation.

Micrologiciel FPGA


Tous les fichiers nécessaires sont sur github . Vous devez télécharger directement avec le dossier.

Après l'enregistrement, vous devez télécharger et installer Quartus II 13.0sp1 à partir du site Web d'Altera. Vous devez télécharger EXACTEMENT CETTE version - les versions plus récentes ne prennent plus en charge la série MAX3000. Il n'est pas nécessaire de le casser - la version (gratuite) de l'édition Web suffit. Lors du téléchargement, assurez-vous de cocher les cases pour la prise en charge du MAX3000 et du programmeur. Au cas où, je vous préviens - le paquet est gros, environ deux concerts. Vous aurez également besoin d'Altera USB Blaster - le prix habituel pour ali est d'environ 3 $.

Ouvrez le projet al422_bam.qpf. Sur la gauche, ouvrez l'onglet fichier et ouvrez le fichier al422_bam.v - il s'agit du fichier de projet principal. Vous devez y configurer les paramètres:

Combien d'entrées RVB sur un panneau - sur les panneaux avec une entrée HUB75, il peut y avoir 1 ou 2 entrées RVB. Pour savoir exactement combien d'entrées sont possibles de cette façon - nous prenons le nombre de pixels dans le panneau verticalement. Divisez-le par le nombre de lignes de balayage (indiqué par exemple dans la désignation du panneau 8S). Divisez par le nombre de connecteurs d'entrée (1 ou 2). Par exemple - j'ai un panneau 32x32, un balayage 8S et deux connecteurs d'entrée - 32/8/2 = 2 - ce qui signifie deux entrées RVB.

`define RGB_outs 2 

Combien de lignes de numérisation sur le panneau - puisque la norme HUB75E est prise en charge, elle peut aller jusqu'à 32x. Le nombre de lignes de balayage est généralement dans le nom du panneau sous la forme de 8S / 16S / 32S, respectivement.

Une seule ligne doit être décommentée:

 `define SCAN_x8 1 //`define SCAN_x16 1 //`define SCAN_x32 1 

Nombre total de pixels horizontaux dans la chaîne. Les pixels sont pris en compte dans toute la chaîne de panneaux - voir la section ci-dessus «Commutation des panneaux LED»

 `define PIXEL_COUNT 64 

Les phases des signaux de sortie. La configuration la plus typique est la suivante: OE est actif à un niveau bas (commentaires supprimés), CLK fonctionne à l'avant (les commentaires sont activés), LAT est actif à un niveau élevé (les commentaires sont activés). Toutes sortes d'options étranges sont possibles. Découvrez lequel vous n'avez qu'à titre expérimental ou en supprimant le circuit et en recherchant des fiches techniques pour les puces utilisées).

 //`define LED_LAT_ACTIVE_LOW 1 `define LED_OE_ACTIVE_LOW 1 //`define LED_CLK_ON_FALL 1 

Délai avant et après le signal OE par rapport au LAT et pré-échelle pour le compteur principal. Voir ci-dessus.

 `define OE_PRESCALER 16 `define OE_PREDELAY 31 `define OE_POSTDELAY 31 

Tout, appuyez sur ctrl-L - le projet est compilé. Si vous ne l'avez pas gâché, il y aura plusieurs avertissements, mais il ne devrait y avoir aucune erreur. Ensuite, nous accrochons la carte soudée au USB Blaster, appliquons l'alimentation à la carte. Dans Quartus, accédez à tools - programmer. Sélectionnez USB-blaster dans la configuration matérielle, cliquez sur Démarrer. Voilà, CPLD est programmé.

Pièce microcontrôleur


La sortie de données vers le contrôleur, en général, est extrêmement simple - nous réinitialisons l'adresse d'écriture, puis émettons séquentiellement des octets de données, en les caressant avec le signal WCLK. Et il semble que même un arduinka banal suffit au travail. Mais il y a deux problèmes:

a) Cela prend beaucoup de mémoire. Même un petit panneau 32x32 en mode RGB888 nécessite 3 Ko de mémoire pour un tampon d'écran. L'Atmega328 basé sur Arduino ordinaire ne contient que 2 Ko de RAM. Vous pouvez bien sûr utiliser une carte Mega basée sur Atmega2560, qui contient jusqu'à 8 Ko de RAM, mais cela n'est pas suffisant pour les panneaux de taille normale - un panneau 128x64 en mode RGB565 nécessite 16 Ko de mémoire.

b) Dans le processus de travail avec AL422B, un problème qui n'a été documenté nulle part est sorti - lors de l'écriture de données à une vitesse inférieure à 2 Mo / s, le compteur d'adresses ne fonctionne pas correctement et écrit les données «absentes». C'est peut-être un petit problème de ma fête. Peut-être pas. Mais ce problème doit être contourné. Étant donné que l'AVR8 fonctionne à 16 MHz, il est presque impossible d'en obtenir des données aux vitesses souhaitées.

La solution proposée est d'opter pour des foulards bon marché basés sur le contrôleur STM32F103C8T6 32 bits. Une telle écharpe coûte à Ali environ 2,5 $ par pièce, soit environ 1,7 $ lors de l'achat d'une douzaine, c'est-à-dire encore moins cher qu'un Arduino Nano. Dans le même temps, nous obtenons un microcontrôleur 32 bits à part entière fonctionnant à 72 MHz et disposant de 20 Ko de RAM et de 64 Ko de flash (à comparer avec le Atmega328 2 Ko / 8 Ko, qui est sur Nano).

Dans le même temps, ces cartes sont programmées avec succès dans l'environnement Arduino. À ce sujet, il y a un bon article sur l' horloge , donc je ne le reproduirai pas. En général, faites tout comme décrit dans l'article.

Dans un environnement Arduino, choisissez la carte Generic STM32F103C, variante STM32F103C8. Les données transitent par DMA, vous pouvez donc utiliser n'importe quelle option d'optimisation.

La commutation se produit comme suit:

Fermement cloué dans la bibliothèque:
A0..A7 → DI0..DI7 AL422B
B0 → WCLK AL422B
B1 → WRST AL422B

Attribué dans un croquis au contrôleur:
B10 → WE AL422B

Fil commun:
G → GND

N'oubliez pas de fournir une alimentation 5V / GND du panneau aux broches du contrĂ´leur correspondantes.

Retirez le brochage du connecteur du contrĂ´leur du circuit .



Partie logiciel


Comme la tâche était de tout rendre aussi simple et abordable que possible, tous les logiciels ont été conçus pour l'environnement Arduino et ont été conçus comme une bibliothèque LED_PANEL .

La bibliothèque LED-PANEL utilise activement la bibliothèque Adafruit GFX , elle doit donc être installée.

Je recommande fortement de ne pas mettre la bibliothèque LED_PANEL dans le répertoire des bibliothèques, mais de la laisser dans le dossier d'esquisse. Le fait est qu'il y a beaucoup de paramètres liés au fer, et si vous voulez transférer le travail vers un microcontrôleur plus "gros", vous devrez changer beaucoup de choses dans le code lui-même.

L'initialisation se présente approximativement sous la forme suivante:

 #include "LED_PANEL.h" #define width 32 #define height 32 #define bpp 3 #define scan_lines 8 #define RGB_inputs 2 #define we_out_pin PB10 LED_PANEL led_panel = LED_PANEL(width, height, bpp, scan_lines, RGB_inputs, we_out_pin); 

c'est-à-dire que nous créons une instance de la classe LED_PANEL, pour laquelle nous spécifions les paramètres:

width - la largeur totale du panneau en pixels (total)
height - la hauteur totale du panneau en pixels (total)
bpp - octet par pixel, 3 pour RGB888. La version BAM ne fonctionne qu'en RGB888
scan_lines - le nombre de lignes de scan est 8/16/32. Il doit correspondre au mode flashé dans le contrôleur.
RGB_inputs - le nombre d'entrées RGB dans le connecteur HUB75 est 1/2. Il doit correspondre au mode flashé dans le contrôleur.
we_out_pin - broche à laquelle la sortie WE est accrochée

Veuillez noter que lors de l'initialisation, seule la broche WE est spécifiée. Toutes les autres broches sont enregistrées de manière rigide dans le code, car elles sont liées au minuteur et aux canaux DMA utilisés et leur modification entraînera des modifications importantes du code.

Démarrage et effacement de l'écran dans la section de configuration:

  led_panel.begin(); led_panel.clear(); 

commencer initialise les broches nécessaires à la sortie, connecte une minuterie et un DMA
clear efface le tampon

Pour le dessin, vous pouvez utiliser toutes les procédures standard de la bibliothèque Adafruit GFX - du plus simple drawPixel à la sortie de texte. Pour sortir les procédures tracées vers le tampon, on utilise:

 led_panel.show(); 

Sous cette forme, show lance le transfert de données vers le contrôleur via DMA et retourne immédiatement le contrôle. Découvrez si le transfert s'est terminé à l'aide de la fonction led_panel.OutIsFree () - s'il est vrai, le transfert est terminé. Il y a une fonctionnalité - si vous appelez show alors que le transfert n'est pas encore terminé - elle sera simplement ignorée.

 led_panel.show(false); 

analogue de show (), mais si vous appelez show (false) et que le transfert n'est pas encore terminé, la procédure attendra la fin du transfert, puis démarrera un nouveau contrôle de transfert et de retour:

 led_panel.show(true); 

analogue de show (false), mais si vous appelez show (true), puis après le début d'un nouveau transfert, la procédure ne renverra le contrôle qu'une fois le transfert terminé.

En général, c'est tout.



Quelques notes sur le logiciel:

a) La correction gamma est introduite lors du recalcul de la couleur à partir de RGB565 (que la bibliothèque utilise) avec la fonction ExpandColor. Dans tous les autres cas, une fonction de transfert linéaire est utilisée, c'est-à-dire que la luminosité est directement proportionnelle à la valeur.
b) Le logiciel vous permet de connecter plusieurs contrôleurs LED à une seule carte microcontrôleur. Pour ce faire, envoyez le bus de données, les lignes RST et CLK aux contrôleurs en parallèle. Le contrôleur souhaité est sélectionné via la ligne WE. Dans le logiciel, vous devez créer une instance distincte de la classe LED_PANEL pour chaque contrôleur, et chaque instance doit avoir des lignes WE différentes (le dernier paramètre) lors de l'initialisation.

Ă€ FAIRE


- Traitez le "ramassage" des fleurs dans les rangées voisines. Cela ressemble à un mauvais câblage du panneau lui-même (les clés sont sales), mais vous devez vérifier. Je viens d'arriver un nouveau panneau - je vais vérifier;
- Faire une nouvelle version de la carte - avec RE déjà divorcé et l'ajout de convertisseurs de niveau de sortie en 5V;
- Créer la classe META_LED_PANEL, qui permettra de combiner plusieurs LED_PANEL en un seul écran virtuel - cela permettra de créer de très grands écrans avec plusieurs contrôleurs;
- À l'avenir, passez à une série CPLD plus puissante, par exemple CycloneIV. Cela augmenterait considérablement les capacités tout en maintenant un faible coût (EP4CE6E22 coûte environ 5 $ pour les chinois, alors qu'il y a 100 fois plus de macrocellules et environ 32 Ko de mémoire interne). Mais je le ferai un jour plus tard. Si je veux. Étant donné que de tels développements prennent trop de temps.

Source: https://habr.com/ru/post/fr409743/


All Articles