Pilotage d'une "matrice de LED" via "shift registers"
#1
Posté 20 août 2011 - 12:06
Je suis l'heureux possesseur d'une carte myAVR 2 usb, qui fonctionne parfaitement, avec l'aide d'AVR-dude sur MacOSX.
Après avoir fait quelques tests concluants, j'ai souhaiter m'attaquer au pilotage d'une matrice de LED 8x8 (pré-fabriquée).
Pour éviter d'utiliser tous les ports du µcontroller, j'ai utilisé 2 shift registers (8 bits, serial in / parallel out).
- Les 8 sorties du premier shift-register sont reliées aux 8 colones;
- Les 8 sorties du second shift-register sont reliées aux 8 lignes, en passant par des resistances 1 kohm;
- Les 2 shift-registers sont reliés ensemble "en cascade" (je ne connais pas le terme exact)
- J'arrive à piloter indépendament chaque LED de la matrice, en activant le bit correspondant a la ligne et en désactivant celui correspondant à la colone. La luminosité de la LED est bonne.
- Dans une boucle, j'arrive à allumer successivement différentes LED de mon choix, une par une, en mettant un petit delais entre chaque allumage. J'ai donc un pixel qui se déplace (ce fut une grande victoire !).
J'aimerais maintenant pouvoir afficher une "image", plusieurs LED en même temps.
J'ai compris qu'il fallait les afficher une par une, successivement, très rapidement.
J'ai donc supprimé le delais entre chaque allumage de LED.
L'image complete est bien visible, mais la luminosité est très faible (en plein jour), ce qui me semble logique vu que chaque LED reste allumée tres peu de temps comparé au temps ou elle sont éteinte. Par contre, je ne percois pas de clignotement.
Je me demandais donc comment je pourrais avoir une luminosité convenable avec un tel montage.
Est-ce du au temps de communication entre le µcontroller et les shift-registers ?
Quelques précisions :
J'ai commencé par "envoyer" chaque pixel de mon image au shift-register (1 par 1);
Maintenant, j'ai "optimisé" en envoyant directement lignes par lignes, la luminosité semble un peu augmenter mais reste très faible.
De même, j'ai d'abord mis le traitement image vers shift-register dans la boucle principale du programme, et maintenant dans un timer, ce qui m'ouvre de nombreuses possibilités, mais le probleme de luminosité reste le même.
Merci de me renseigner si vous le pouvez !
Cordialement,
Nicolas.
#2
Posté 20 août 2011 - 10:09
Les résitances que j'utilise (1kohm) sont adaptées pour l'allumage "normal" (permanent) d'une diode.
Comme ici elle clignotent tres rapidement, en restant éteinte un grande partie du temps, visiblement, je peux baisser la valeur de la résistance, grace au principe de PWM ("pulse width modulation" / "Modulation de largeur d'impulsion").
Je suppose que l'on peut calculer la valeur de résistance idéale selon le temps d'allumage, mais je n'en suis pas encore la.
En tout cas, en réduisant les résistances, voire en les enlevants, la luminosité est nettement meilleure !
#3
Posté 20 août 2011 - 07:58
Essais ca
Ce code sur une matrice 8X8 allume les LED en forme de coeurs
/*
* matrixMpxAnimation sketch
* animates two heart images to show a beating heart
*/
// the heart images are stored as bitmaps - each bit corresponds to an LED
// a 0 indicates the LED is off, 1 is on
byte bigHeart[] = {
B01100110,
B11111111,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000,
B00000000};
byte smallHeart[] = {
B00000000,
B00000000,
B00010100,
B00111110,
B00111110,
B00011100,
B00001000,
B00000000};
const int columnPins[] = { 2, 3, 4, 5, 6, 7, 8, 9};
const int rowPins[] = { 10,11,12,15,16,17,18,19};
void setup() {
for (int i = 0; i < 8; i++)
{
pinMode(rowPins[i], OUTPUT); // make all the LED pins outputs
pinMode(columnPins[i], OUTPUT);
digitalWrite(columnPins[i], HIGH); // disconnect column pins from Ground
}
}
void loop() {
int pulseDelay = 800 ; // milliseconds to wait between beats
show(smallHeart, 80); // show the small heart image for 100 ms
show(bigHeart, 160); // followed by the big heart for 200ms
delay(pulseDelay); // show nothing between beats
}
// routine to show a frame of an image stored in the array pointed to
// by the image parameter.
// the frame is repeated for the given duration in milliseconds
void show( byte * image, unsigned long duration)
{
unsigned long start = millis(); // begin timing the animation
while (start + duration > millis()) // loop until duration period has passed
{
for(int row = 0; row < 8; row++)
{
digitalWrite(rowPins[row], HIGH); // connect row to +5 volts
for(int column = 0; column < 8; column++)
{
boolean pixel = bitRead(image[row],column);
if(pixel == 1)
{
digitalWrite(columnPins[column], LOW); // connect column to Gnd
}
delayMicroseconds(300); // a small delay for each LED
digitalWrite(columnPins[column], HIGH); // disconnect column from Gnd
}
digitalWrite(rowPins[row], LOW); // disconnect LEDs
}
}
}
Ce code est extrait de Arduino cookbook de M. Margolis EditionO'Reilly
Par contre, la valeur des résistances est a respecter en fonction de ta tension et de la puissance des LEDs
Cdlt
Yves
#4
Posté 20 août 2011 - 10:44
Mon code ressemble à quelque chose comme ça, et je n'ai pas de probleme d'affichage ou de controlle des pixels (sauf que je n'affiche pas des coeurs
Mon probleme est vraiment au niveau luminosité. Dans ton exemple, quelles sont les valeurs de résistances utilisées ?
EDIT : en réalité mon code est un peu différent car j'utilise des shift registers, ce qui me permet de n'utiliser que 3 pins.
#5
Posté 21 août 2011 - 01:59
Il m'est donc impossible de te donner la valeur de cette résistance sans connaitre les caractéristiques de tes LEDs ainsi que la tension d'alimentation.
Mais je peux te donner la formule que tu dois appliquer pour calculer cette valeur.
Tu dois applique la loi d'Ohm
U=R*I
Donc
R= U/I
Mais tu dois d'abord, calculer la tension d'adaptation. Donc, soustraire la tension d'alimentation nominale de ta LED à la tension que tu souhaites apporter.
R= (U - UI ) / I
R : Résistance (Ohm)
U : Tension de l'alimentation (transformateur en V)
UI : Tension de la LED (V)
I : Intensité de la LED (A)
Regarde dans le lexique, j'avais fait un petit "tuto" sur les LEDs (à l'époque de Robotix mais il a certainement été transféré ici)
Mais pour faire simple, voilà un tableau qui devrait t'aider.
Couleur ------ Volt led(V) ------ Intensité (A)
Rouge----------2,1-2,3 ---------------- 0,02
Orange---------3,2-3,4 ---------------- 0,02
Jaune-----------2,1-2,3 ---------------- 0,02
Vert--------------3,1-3,3 ---------------- 0,02
Bleu-------------3,0-3,2 ---------------- 0,02
Rose------------3,2-3,4 --------------- 0,02
U.V---------------3,2-3,4 --------------- 0,02
Blanc -----------3,2-3,4 --------------- 0,02
Les valeurs que tu vas obtenir sont bien sur les valeurs idéales. Toutefois, tu peux (dans une proportion raisonnable) les baisser ou les augmenter en fonction de la luminosité que tu souhaites obtenir.
Plus tu augmentes la valeur, moins ta LED sera luminuse, et bien sûr, plus tu la baisses plus elle sera éclairée. Toutefois, passé un certain pourcentage, tu vas réduire considérablement la durée de vie de tes LEDs. Voir même les cramer immédiatement.
Cdlt
Yves
#6
Posté 21 août 2011 - 07:14
Tu as tout à fait raison. En plus des explications de Yves, voici le complément dans le cas où tu ne pilotes pas ta LED 100% du temps.Si ça interesse quelqu'un, j'ai un peu avancé sur le sujet.
Les résitances que j'utilise (1kohm) sont adaptées pour l'allumage "normal" (permanent) d'une diode.
Comme ici elle clignotent tres rapidement, en restant éteinte un grande partie du temps, visiblement, je peux baisser la valeur de la résistance, grace au principe de PWM ("pulse width modulation" / "Modulation de largeur d'impulsion").
Je suppose que l'on peut calculer la valeur de résistance idéale selon le temps d'allumage, mais je n'en suis pas encore la.
Il faut chercher le datasheet de tes LEDs pour vraiment bien dimensionner tes résistances.
Il faut récupérer:
* Le courant continu admissible
* Le courant pic admissible
* La chute de tension directe
C'est soit le courant "continu admissible", soit le "courant pic admissible" qui vont déterminer le courant maxi. S'il n'y avait que le "courant continu admissible", tu pourrais dimensionner ta résistance en calculant le courant moyen. Par exemple, si ta LED accepte 10mA en "courant continu admissible" et que tu ne la pilotes au maximum que 20% du temps, alors tu devrait pouvoir lui injecter
10mA / 0.20 = 50mA.
Mais il est possible que cette intensité dépasse le "courant pic admissible". Il faut sélectionner le plus contraignant des 2 (le plus faible).
A toi de vérifier ça.
Après, pour le calcul de la résistance, c'est comme Yves vient juste de l'expliquer.
BOB4, mon drone hélicoptère autonome d'intérieur http://heli.bot.free.fr/
BOB3, mon robot autonome d'intérieur avec WiFi + Foxboard Linux http://ze.bot.free.fr/
BOB5, robot bipède simulé, puis tentative de réalisation (fail)
#7
Posté 21 août 2011 - 01:49
Effectivement, je sais caculer la résistance pour une LED allumée à 100% (apres en avoir sacrifié quelques unes...).
Il faut chercher le datasheet de tes LEDs pour vraiment bien dimensionner tes résistances.
Il faut récupérer:
* Le courant continu admissible
* Le courant pic admissible
* La chute de tension directe
Je vais essayer de trouver ces infos pour un allumage à 12.5% (1/8e, j'ai 8 lignes que j'allume successivement).
Je vous tiens au courant.
Répondre à ce sujet
1 utilisateur(s) li(sen)t ce sujet
0 members, 1 guests, 0 anonymous users













