Forum: Mikrocontroller und Digitale Elektronik Problem LED-Matrix


von Marcel P. (Gast)


Lesenswert?

Hallo,

ich bin gerade an der Umsetzung einer 5x5 LED-Matrix. Dazu habe ich die 
Spalten per BC548 Transistor an 5V verbunden. Die Basen der 5 npn habe 
ich mit dem PORTD eines Atmega8 verbunden. Die Zeilen habe ich nun über 
je einen 82 Ohm Widerstand am PORTC des selbigen AVRs angeschlossen. Die 
LEDs (3,2V , 20mA) kann ich statisch alle samt ansteuern (einzeln), 
indem ich eben den jeweiligen Spaltentransistor durchschalte, und die 
Zeilen so maskiere, dass an den LEDs die leuchten sollen Masse liegt 
(logische 0). Sobald ich nun aber 2 LEDs abwechselnd leuchten lasse, 
also multiplexe, leuchten 2-3 LEDs ganz schwach mit. Ich habe die 
komplette Verschaltung noch mal überprüft und auch fremdkontrollieren 
lassen. Ich stehe nun vor dem Problem, dass ich warscheinlich eine 
tückische Sache übersehe. Auch hab ich die Leckströme der abgeschaltenen 
LEDs in betracht gezogen, aber kann das der Grund sein?

Vielen Dank vorab für eure Hilfe

Marcel P.

von Thomas E. (thomase)


Lesenswert?

Erstmal ist dein Widerstand viel zu groß. In einer 5x5- Matrix leuchten 
von den 25 LEDs maximal 5 gleichzeitig, für 1/5 der Zeit. D.h. die LED 
muß mit dem fünffachen Strom geschaltet werden.
Dafür dürfte der Atmega-Port aber ein wenig zu schlapp sein. Also auch 
Masse über einen Treiber. ULN2003 z.B.

mfg.

von holger (Gast)


Lesenswert?

Das kann an der Reihenfolge deiner Aktionen liegen.
Bevor man ein neue Spalte einschaltet muss die
zuletzt eingeschaltete Spalte erst mal ausgeschaltet
werden. Dann erst die Zeilen ändern und die neue
Spalte einschalten.

von Thomas E. (thomase)


Lesenswert?

holger schrieb:
> Das kann an der Reihenfolge deiner Aktionen liegen.
>
> Bevor man ein neue Spalte einschaltet muss die
>
> zuletzt eingeschaltete Spalte erst mal ausgeschaltet
>
> werden. Dann erst die Zeilen ändern und die neue
>
> Spalte einschalten.

Genau! Hab ich noch vergessen.

mfg.

von Marcel P. (Gast)


Lesenswert?

Okay, das dachte ich mir schon, nur sind die LEDs sowieso zu grell für 
die meine Bedürftnisse. Aber daran sollte es eigentlich ja auch nicht 
liegen, dass andere LEDs mitleuchten, oder doch?!

von Marcel P. (Gast)


Lesenswert?

Auch das mit der Reihenfolge habe ich bedacht. Ich setzte vor jeder 
Änderung der Zeilenmasken alle Spalten auf 0. Außerdem würden dann die 
falschen LEDs doch genauso hell leuchten oder nicht? Sind ja dann auch 
einen Taktzyklus lang an.

von Thomas E. (thomase)


Lesenswert?

Marcel P. schrieb:
> Auch das mit der Reihenfolge habe ich bedacht. Ich setzte vor jeder
>
> Änderung der Zeilenmasken alle Spalten auf 0. Außerdem würden dann die
>
> falschen LEDs doch genauso hell leuchten oder nicht? Sind ja dann auch
>
> einen Taktzyklus lang an.

Da muß noch eine kleine "Schutzzeit" rein. Wenn Du PortD auf 0 setzt, 
wird das Portregister auf 0 gesetzt und dann schaltet der Port. Das 
dauert eben auch ein wenig. Setz' da ein paar NOPs zwischen und mache 
das Umschalten nicht mit vollem Takt, sondern wesentlich langsamer, z.B 
1000x in der Sekunde.

mfg.

von Lehrmann M. (ubimbo)


Lesenswert?

Servus,

lies mal bitte den Artikel hier: 
http://www.mikrocontroller.net/articles/LED-Matrix

von Marcel P. (Gast)


Lesenswert?

Hallo nochmal,

ich habe nun die Pausen eingefügt, dennoch zeigt die Matrix scheinbar 
zufällige Leuchtbilder. Dabei leuchtet bei folgender Einstellung eine 
LED am hellsten, 2 weitere leuchten schwach mit.
1
    PORTC = 0;
2
    PORTD = 1;
3
    _delay_loop_1(4);
4
    PORTD = 0;
5
    _delay_loop_1(4);
6
    
7
    PORTC = 0;
8
    PORTD = 2;
9
    _delay_loop_1(4);
10
    PORTD = 0;
11
    _delay_loop_1(4);
12
    
13
    PORTC = 0;
14
    PORTD = 4;
15
    _delay_loop_1(4);
16
    PORTD = 0;
17
    _delay_loop_1(4);
18
    
19
    PORTC = 0b00000001;
20
    PORTD = 8;
21
    _delay_loop_1(4);
22
    PORTD = 0;
23
    _delay_loop_1(4);
24
    
25
    PORTC = 0;
26
    PORTD = 16;
27
    _delay_loop_1(4);
28
    PORTD = 0;
29
    _delay_loop_1(4);

Im Vergleich zu vorher habe ich nun lediglich in die Masseleitungen je 
einen BC548 eingefügt und zur "erhöhten" Lichtausbeute einen 
zusätzlichen Widerstand parallel zum alten mit ebenfalls 82 Ohm gelötet.
Ist in diesem Abschnitt das Problem mit den Pausen soweit richtig 
umgesetzt?

Vielen Dank soweit für die bisherige Hilfe =)

Marcel P.

von Peter D. (peda)


Lesenswert?

Was soll der Quatsch mit den Delayloops.
Nimm _delay_ms(1), damit man auch weiß, wie groß die Delays sind.
Ich vermute mal Deine Delays sind viel zu kurz, 1kHz reicht dicke.

Beim Emitterfolger brauchst Du auch keine zusätzlichen Delays, der ist 
schnell genug.
1
  PORTD = 0;          // aus
2
  PORTC = BITMUSTER0; // neues Bitmuster
3
  PORTD = 1<<0;       // an
4
  _delay_ms( 1 );     // 1kHz
5
6
  PORTD = 0;          // aus
7
  PORTC = BITMUSTER1; // neues Bitmuster
8
  PORTD = 1<<1;       // an
9
  _delay_ms( 1 );     // 1kHz
10
11
  PORTD = 0;          // aus
12
  PORTC = BITMUSTER2; // neues Bitmuster
13
  PORTD = 1<<2;       // an
14
  _delay_ms( 1 );     // 1kHz
15
16
  // usw.


Peter

von Thorsten S. (whitejack)


Lesenswert?

PORTC = 0;
    PORTD = 1;              //Spalte 1 an
    _delay_loop_1(40);
    PORTC = 0;
    PORTD = 0;
    _delay_loop_1(4);

    PORTC = 0;
    PORTD = 2;              //Spalte 2 an
    _delay_loop_1(40);
    PORTC = 0;
    PORTD = 0;
    _delay_loop_1(4);

    PORTC = 0;
    PORTD = 4;              //Spalte 3 an
    _delay_loop_1(40);
    PORTC = 0;
    PORTD = 0;
    _delay_loop_1(4);

    PORTC = 0b00000001;
    PORTD = 8;              //Spalte 4 an
    _delay_loop_1(40);
    PORTC = 0;
    PORTD = 0;
    _delay_loop_1(4);

    PORTC = 0;
    PORTD = 16;             //Spalte 5 an
    _delay_loop_1(40);
    PORTC = 0;
    PORTD = 0;
    _delay_loop_1(4);

von Thorsten S. (whitejack)


Lesenswert?

...das Beispiel von Peter ist doch besser...

und am besten in eine Funktion verpacken die immer eine Spalte nach der 
anderen macht, also bei jedem Aufruf die nächste SPalte bearbeitet...


Ausführlich wäre das dann so ähnlich:

//Variablen für die 5 Zeile global für den ersten Versuch

void Matrix_Update (void)
{
  static uint8_t zaehler=0;
  switch (zaehler)
  {
    case 0:
    {
      PORTD = 0;          // aus
      PORTC = BITMUSTER0; // neues Bitmuster
      PORTD = 1<<0;       // an
      break;
    }
    case 1:
    {
      PORTD = 0;          // aus
      PORTC = BITMUSTER1; // neues Bitmuster
      PORTD = 1<<1;       // an
      break;
    }
   ...
  }
  zaehler++;
  if (zaehler>4)
  {
    zaehler=0;
  }
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.