Forum: Mikrocontroller und Digitale Elektronik Übersprechen bei LED-Multiplex


von Guenter B. (gbl)


Lesenswert?

Hallo,

ich habe mir eine LED-Matrix gebaut. 6*8 LED.
An Port B0-7 (Mega8)hängen über einen Widerstand von 330 Ohm die Anoden 
der LED's.
Die Kathodenstränge werden über 6 BC547B nach Minus geschaltet.
Die Transistoren werden über einen 4,7kOhm Widerstand über Port D0-5 
angesteuert.
Die Schaltung funktioniert soweit. Das Multiplexen passiert in einer 
timergesteuerten Interruptroutine.
Allerding habe ich Übersprechen dh. es leuchten LED's ganz schwach mit.
Und zwar im Muster der am Port B ausgegeben Daten.
Da es sich um sehr empfindliche, helle, weisse LED's handelt, fällt es 
doch etwas auf (Trotz des hohen Widerstandes von 330 Ohm).
Ein Kondensator (100nF) direkt an die betreffenden LED's gelötet, 
schafft Abhilfe.

Aber das kann doch nicht die Lösung sein ?

Gruß

Günter

von Floh (Gast)


Lesenswert?

Guenter B. schrieb:
> Aber das kann doch nicht die Lösung sein ?

Programmfehler?

von Micha (Gast)


Lesenswert?

Das ist Programmgesteuert. überlege mal wie und wann Du die Ausgänge 
schaltest.

von Guenter B. (gbl)


Lesenswert?

Ich denke nicht.


ISR
{
Ich schalte zuerst Port B auf 0.
x
Wechsele dann auf den nächsten Strang (Inhalt von Port D*2)und
x
gebe dann das nächste Bitmuster auf Port B aus.
Beim nächsten Aufruf ist das nächste Muster dran.
}



Ich habe an den Stellen mit "x" auch schon ein Delay eingebaut.

Die Leiterbahnzwischenräume saubergekratzt (Streifenraster).

Und den Transistoren einen Widerstand von 2,2 kOhm nach Masse verpasst.

Es ist ja auch nicht bei allen LED gleich stark.

von Guenter B. (gbl)


Lesenswert?

Hier die ISR:
Hatte übrigens in meinem Anfangsposting Port B und Port D vertauscht.
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD= 0;  
4
  //_delay_us(100);
5
  PORTB= SegCount; //1.Reihe an
6
  //_delay_us(100);
7
  PORTD= a[ByteCount]; //1.Byte Laden
8
  if (SegCount<32)
9
      {SegCount=SegCount*2;}
10
      else
11
      {SegCount=1;}
12
  if (ByteCount<5)
13
      {ByteCount=ByteCount+1;}
14
      else
15
      {ByteCount=0;}
16
}

Die jeweiligen 6 auszugebenen ByteWerte befinden sich in der 
Feldvariablen a[0-5].
Takt: 8Mhz
ISR-Takt 8Mhz/256

Den Variablen a[0-5] werden im Laufe des Programms verschiedene Werte 
zugeordnet.


zB

main
{
a[0]++; oder ähnlich
loop;
}


Oder sollte man die Schaltung besser umgekehrt mit PNP-Transistoren 
aufbauen und Port D nicht 1 für "LED an" sondern 0 für "LED an" schalten 
?

von Jonas Quin (Gast)


Lesenswert?

Guenter B. schrieb:
> Allerding habe ich Übersprechen dh. es leuchten LED's ganz schwach mit.

Das ist in 99,99% aller Fälle ein Programmierfehler.

von Captain S. (captainsubtext)


Lesenswert?

Guenter B. schrieb:
> Hier die ISR:
> Hatte übrigens in meinem Anfangsposting Port B und Port D vertauscht.
>
>
1
> ISR (TIMER0_OVF_vect)
2
> {
3
>   PORTD= 0;
4
>   //_delay_us(100);
5
>   PORTB= SegCount; //1.Reihe an
6
>   //_delay_us(100);
7
>   PORTD= a[ByteCount]; //1.Byte Laden
8
>   if (SegCount<32)
9
>       {SegCount=SegCount*2;}
10
>       else
11
>       {SegCount=1;}
12
>   if (ByteCount<5)
13
>       {ByteCount=ByteCount+1;}
14
>       else
15
>       {ByteCount=0;}
16
> }
17
>
>
Was unschön ist:
Du erhöhst im selben Durchlauf ByteCount und SegCount. Hier hast Du 
Glück, dass beide Variablen verschiedene Wertebereiche haben.
Wenn der Wertebereich aber gleichgroß wird überspringt deine ISR den 
Großteil der 'Pixel'.

Stell es am Besten so um, dass du nur dann die Zeile änderst, wenn du 
alle Spalten einmal durchlaufen hast.

von Anja (Gast)


Lesenswert?

Guenter B. schrieb:
> ISR-Takt 8Mhz/256
> _delay_us(100);

Negative Zeitachse oder? Ich hätte auch immer gern 200us Zeit wenn nur 
32us zur Verfügung stehen.

Ich würde die Multiplex-Frequenz auf ca 100 Hz für einen Durchlauf 
setzen (also ca 600 Hz für die Interrupt-Routine).
Dann klappts auch mit 100us delay. Brauchen wirst Du ca 5us für die 
Transistoren.

Gruß Anja

von Karl H. (kbuchegg)


Lesenswert?

Ich wüds so umbauen
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD = 0;
4
  PORTB = 0;  
5
6
  SegCount = SegCount << 1;
7
  if (SegCount == 0b01000000)
8
    SegCount = 1;
9
10
  ByteCount++;
11
  if (ByteCount > 5)
12
    ByteCount = 0;
13
14
  PORTB = SegCount;
15
  PORTD = a[ByteCount];
16
}

Das verschafft dir nach dem Ausschalten der LED und vor dem Einschalten 
der nächsten Spalte etwas Zeit, so dass sich eventuelle externe 
Kapazitäten entladen können und die Transistoren sicher abgeschaltet 
haben.

PORTB und PORTD sind sicher auf Ausgang geschaltet?

von Captain S. (captainsubtext)


Lesenswert?

Vergiss bitte, was ich geschrieben habe, ich hab' zwei große Denkfehler 
gehabt.
Wenn es so dagestanden hätte, hätte ich es etwas besser verstanden:
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD= 0;
4
  //_delay_us(100);
5
  PORTB= SegCount; //1.Reihe an
6
  //_delay_us(100);
7
  PORTD= a[ByteCount]; //1.Byte Laden
8
  if (ByteCount<5) {
9
      ByteCount=ByteCount+1;
10
      SegCount=SegCount*2;
11
  } else {
12
      ByteCount=0;
13
      SegCount=1;
14
  }
15
}

;-)

von gbl (Gast)


Lesenswert?

@captain subtext

Ich muss doch das entsprechende Bitmuster (Bytecount)ausgeben und die 
entsprechende Spalte (Segcount) auswaehlen. Im Prinzip arbeiten hier 
zwei Zaehler fuer dieselbe Sache:
1,2,4,8,16,32 fuer die Spalte und
O,1,2,3,4,5 als Index fuer Feldvariable mit dem entsprechenden 
Bitmuster.

@Anja

Die 100us waren nur testweise drin.
Ausserdem bin ich bei meinem Halbwissen davon ausgegangen, dass 
innerhalb einer ISR Interrupts gesperrt sind und ich somit mehr Zeit 
habe.

Gruß

Gbl

von Captain S. (captainsubtext)


Lesenswert?

gbl schrieb:
> Ich muss doch das entsprechende Bitmuster (Bytecount)ausgeben und die
> entsprechende Spalte (Segcount) auswaehlen. Im Prinzip arbeiten hier
> zwei Zaehler fuer dieselbe Sache:
> 1,2,4,8,16,32 fuer die Spalte und
> O,1,2,3,4,5 als Index fuer Feldvariable mit dem entsprechenden
> Bitmuster.

Das habe ich im zweiten Anlauf ja auch begriffen. ;-)
Es wäre für Andere übersichtlicher, derart abhängige Variablen gemeinsam 
zu bearbeiten. Siehe dazu meinen zweiten Post.

von Guenter B. (gbl)


Lesenswert?

@captain subtext

Da hatten sich wohl unsere Postings überschnitten.
Ich hatte deinen Beitrag erst gesehen, als ich meinen abgesandt hatte.

Aber du hast recht: Man könnte das Ganze etwas übersichtlicher lösen.


@Karl Heinz Buchegger
D=0
B=0
Werde ich heute Abend ausprobieren.

Zu den Ports:
Ich meine schon die Ports auf Ausgang geschaltet zu haben.
Ansonsten würde es doch gar nicht funktionieren oder ?
Werde es aber auch jeden Fall kontrollieren.

Gruß

gbl

von Edi R. (edi_r)


Lesenswert?

Guenter B. schrieb:
> Zu den Ports:
> Ich meine schon die Ports auf Ausgang geschaltet zu haben.
> Ansonsten würde es doch gar nicht funktionieren oder ?

Doch, eventuell schon. Wenn die Ports auf Eingang geschaltet sind, dann 
schaltest Du nur die internen Pull-Ups ein (was ein HIGH über den 
Pull-Up am Ausgang ergibt) oder aus (was die Ausgänge hochohmig macht). 
Mit einem npn-Transistor am Ausgang kann das funktionieren, der 
Transistor ist dann aber langsamer.

von Matthias L. (Gast)


Lesenswert?

Was noch interessant ist: Wenn du die Transistoren in Emitterschaltung 
betreibst, haben die nach Sättigung eine ziemlich lange Speicherzeit.
Poste doch mal die Schaltung. Wie gross ist der Basisstrom, die 
Stromverstärung und der Kollektorstrom?

Abhilfe würde hier ein Verkleinern des Basisstromes, oder das Umstellen 
auf Kollektorschaltung helfen.

von Guenter B. (gbl)


Lesenswert?

@ Karl Heinz Buchegger
Habe die Routine mal eingbaut:
Keine Veränderung.
Auch nicht wenn ich nach
B=0
D=0
ein
_delay_us(5) oder (20)
ausgebe.

@edi
DDRB = 0xFF;
DDRD = 0xFF;
hatte ich gesetzt

@Matthias Lipinsky
Die Transistoren
werden über 4,7 kOhm angesteuert.
IB=(5-0,7)/4700=0,91mA
IC=(5-2-0,1)/330=8,8 mA
Verstärkung ca 250 (laut HFE-Messbuchse am DMM)
I gesamt (Alle LED's an) -> ca 90mA


Gruß

gbl

von Karl H. (kbuchegg)


Lesenswert?

Jetzt mal Butter bei den Fischen.

Exakten Schaltplan
Exaktes Programm
Wie sieh der Aufbau aus? Steckplatine, Lochraster, geätzte Schaltung? 
Wenn geht: Photo

von Martin (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> Poste doch mal die Schaltung. Wie gross ist der Basisstrom, die
> Stromverstärung und der Kollektorstrom?

Und gleich noch ein Oszillogramm vom Strom zweier benachbarter Reihen 
beim Umschalten der Transistoren...

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.