Forum: Mikrocontroller und Digitale Elektronik noch ein RGB-LED Projekt


von Philipp K. (phil323)


Lesenswert?

Ich will eine Matrix aus RGB-LED mit einem Mikrocontroller ansteuern.
Die Matrix soll anfangs aus 100 einzeln ansteuerbaren RGB-LEDs
bestehen. Die Anzahl soll skalierbar sein. Es soll auch möglich sein
mehrere LEDs an einen Kanal anzuschließen.

Es gibt zwar in diesem Forum bereits zahlreiche Beiträge mit dem Thema
RGB-LED, die ich alle aufmerksam gelesen habe. Trotzdem konnte ich
bisher nichts passendes zu meinem Projekt finden.

Mit eiem Atmel AVR MEGA8 ist es mir bisher gelungen 3 RGB-LEDs direkt
über die Pins anzusteuern. Das Programm (in C, bisher sehr quick and
dirty) schaltet zu Beginn alle Pins ein und eine Funktion, die laufend
aufgerufen wird, schaltet die Pins dann je nach gewünschter Intensität
der einzelnen Kanäle wieder ab. Ein Timer Interrupt lässt das Programm
dann wieder von vorne beginnen. Das Funktioniert schon sehr gut.
Farbübergänge sind flüssig. Das Spektrum ist für mein Empfinden
vollständig.

Jetzt suche ich aber nach einer geeigneten Methode mehr RGB-LEDs
anzusteuern. Ich will kurz meine Ideen vorstellen, sowie ihre
jeweiligen Vor- und Nachteile aufzählen:

1) Latches
Jeder Farbkanal jeder LED erhält einen Adressierbaren Latch, an dem mit
einem Wiederstandsnetzwerk ein einfacher D/A Wandler realisiert ist. Für
die Verstärkung des analogen Signals kommt ein Operationsverstärker zum
Einsatz.
(+) Entlastung des Mikrocontrollers
(+) kein Flackern o. ä. Wenn der Mikrocontroller mit etwas anderem
beschäftigt ist, wie z. B. Empfang von IR Signalen
(+) gute Skalierbarkeit
(-) hoher Aufwand, viele Teile, hoher Platzbedarf, hohe Kosten

2) Sample and hold Baustein
Der Analog Ausgang des µC kann analoge Werte in Adressierbare s/h
Bausteine schreiben, die über einen Operationsverstärker mit den LEDs
verbunden sind.
(+) entlastung des µC
(+) kein Flackern
(-) System arbeitet wahrscheinlich langsamer. Dauert jeweils lange bis
analoge Spannungen stabil genug zum samplen sind. dadurch
(-) bedingte Skalierbarkeit
(-) hohe Kosten (s/h Bausteine)
(-) hoher Platzbedarf

3) Multiplexer
Mit zwei mal 5 Pins könnte man 32 Zeilen und 32 Spalten ansteuern. Bei
3 Farben pro LED ließen sich so mehr als 300 LEDs ansteuern. Benutzt
man einen Latch als zwischenspeicher könnte man die Wort oder
Adresslänge einfach verdoppeln.
Der Zustand jedes Farbkanals jeder LED wird z. B. in einem Latch
zwischengespeichert. Das Programm arbeitet dann ähnlich, wie mein
Testprogramm: Zu beginn eines Umlaufs werden alle LED eingeschaltet und
dann nach und nach abgeschaltet. Durch die hohe Geschwindigkeit von
Digitalbausteinen sollte das gut funktionieren.
(+) eher geringe Kosten: ein 8 Bit Latch kann Daten für 2 2/3 LEDs
speichern
(+) Skalierbarkeit: Man kann den Adressraum sehr großzügig anlegen.
(-) Hohe Belastung des µC: Die einzelnen Kanalintensitäten werden nicht
zwischengespeichet. Der µC ist also nicht für andere Aufgaben
verfügbar.

4) Spezialbaustein
Die Suche nach einem Chip, der exra für solche Aufgaben konzipiert ist
blieb bisher ohne Ergebnis. Sollte es etwas in dieser Richtung geben
rechne ich mit hohem Preis und schwieriger Beschaffung. Ich bin aber
für Vorschlage dankbar.

5) Dezentralisierung
ganz andere Idee: Ich setze einfach viele MEGA8 ein. Wie in meinem oben
beschriebenen Testaufbau steuert jeweils ein MEGA8 3 oder 4 RGB-LEDs an.
über z. B. I^2C erhalten die MEGA8 ihre Befehle von einem zentralen
MEGA8, der auch für die Schnittstelle zum Menschen zuständig ist. Das
ermöglicht sogar interessante Betriebsmodi: Der CPU könnte zum Beispiel
Verlaufsinformationen, Offsets oder absolute Werte für Frabtemperatur,
Farbton, Helligkeit direkt schicken. Nichtlineares Verhalten
(Pulsdauer/Helligkeit) könnte direkt in den slave Mega8s kompensiert
werden.
(+) quasi unbegrenzte Skalierbarkeit
(+-) vertretbarer Aufwand (MEGA8=2.75 bei Reichelt)
(-) Änderungen im Code für die slave MEGA8 aufwändig.
offene Fragen:
-kann ich mit einem Quarzoszillator mehr als ein (beliebig viele)
bausteine takten? Gibt es Obergrenzen für Leitungslängen? Kann ich das
Taktsignal falls nötig verstärken?

6) gepulster Betrieb
ähnlich dem Multiplexer, nur ohne Zwischenspeicherung der Digitalen
Werte in den Latches. Die Zeilen werden nacheinander angesteuert. Bei
20 Zeilen bekäme dann jeder Kanal jeder LED je nach gewünschter
Leuchtkraft eine Impulslänge von 0p - 1/20p (p ist Zeit für einen
Umlauf) bei zwanzigfachem Strom. (Zahlen nur exemplarisch)
(+-) mittelmäßige Skalierbarkeit
(+-) Aufwand nicht zu hoch
(-) Hohe Anforderungen an die Stromversorgung (Spannung muss trotz
starker Stromschwankungen konstant bleiben)
(-) Leistungselektronik erfoderlich
(-) µC wird stark belastet. Ausserdem muss das Zeitauflösungsvermögen
sehr hoch sein. Mindestens 1/200 * 1/20p bei p höchstens 1/200s.
(-) fehler im Programmcode oder Systemabstürze führen zur Zerstörung
der LEDs

(7) Mischung
Während ich das hier schreibe, stellt sich für mich eine favorisierte
Lösung heraus: Die Kombination aus 3) und 5). Ein Mega8 stellt das
Interface zum Menschen dar und errechnet die Gewünschte Helligkeit
aller LEDs. Ein oder je nach größe mehrere slave Mega8 werden von ihm
z. B. über I^2C angesteuert und steuern wiederum wie in 3 Beschrieben
LEDs an. Ist der Master Beschäftigt, weil er z. B. Daten über IR oder
uart empfängt, behalten die LEDs trotzdem ihre Farbe und flackern
nicht.

-----------------------------
Das ist jetzt etwas länger geworden.
Vielleicht gibt es jemanden, der sich schon mal gedanken über sowas
gemacht hat, oder sogar schon so etwas entwickelt hat.
Ich bin für jede Idee und jeden Hinweis dankbar.

Philipp

von Hauke Radtki (Gast)


Lesenswert?

Deine Letzte idee (7) ist wohl die sinnvollste.
Du hast die vorteile ja schon aufgeschrieben.

Zur frage mit dem takt: Du solltest für jeden controller einen eigenen
quarz verwenden, da die leitungen nach möglichkeit nur wenige cm lang
sein sollten (am besten direkt am controller)

Auf jeden fall eine interessante Idee!

von Thomas O. (Gast)


Lesenswert?

Ich würde Latches ala 573n nehmen da kannst du z.b. an einen Port 16
parallel hängen.

Dann gibts nen dann gibts nen Baustein(Bezeichnung gerade nicht im
Kopf) dem kannst du über 4 Leitungen bestimmen welcher von 16 Ausgängen
high zeigen soll, damit kannst du also jeweils von 16 Latches dazu
bewegen die Ausgabe am Port zu übernehmen. Dann hättest schonmal ne
Matrix von 128 Punkten.

Das ganze kannste beliebig fortsetzen, vorrausgesetzt die
Latcheseingänge sind im Tristate-Betrieb hochohmig genug. Damit sie den
Port nicht zu stark belasten da ja mehrere parallel hängen.

Von der Geschwindigkeit her wirds kaum ne schnellere Möglichkeit geben,
du gibst einen Wert am Port aus und übermittels über einen anderen Port
welches Latches das Empfangssignal bekommt, schon ist das ganze
übertragen das Signal zum Latch wird gelöscht und dieser gibt das ganze
selbständig an die Leds weiter.

Eine andere Möglichkeit wäre das du 2 große Schieberegister(16Bit)
zusammenhängst und nur eine 1 durchrotierst um die Latches auszuwählen,
damit könntest du ne Matrix mit 32x8 zusammenbekommen.

Wenn dir der Bauteileaufwand aber zu hoch ist musste dich doch ans
Multiplexen machen, wobei der µC ja schnell genug ist.

von Philipp K. (phil323)


Lesenswert?

Danke für die schnellen Antworten.
Die Lösung mit den Latches und dem Demultiplexer (hatte oben
Multiplexer mit Demux verwechselt) kommt mir jetzt auch gut vor. Das
mit den Schieberegistern ist nicht ideal, da ich ja nicht Zeile für
Zeile ansteuere, sondern immer diejenige Zeile brauche, in der gerade
die LED abgeschaltet werden muss. Beim ständigen Schieben des einen
Bits würde ich viel mehr CPU Takte benötigen als mit einem Demux.

Hab mir das Datenblatt vom 573 durchgelesen. Der scheint mir geeignet.
Danke für den Tipp. Aber eine Frage: Der Tri-State Modus bezieht sich
doch nur auf die Ausgänge. Der Eingangswiederstand der Latcheingänge
wird dadurch doch nicht beeinflusst, oder? Darüber hinaus glaube ich
auch, dass ich den Tri-State Modus garnicht benötige (Hi, wenn LED an;
Low, wenn aus). -> /OE => Vcc.

Als Demux ist der 238 geeignet. der schlüsselt zwar nur 3 Bit auf, hat
aber den Vorteil geg. dem 154 (4Bit), dass die Ausgänge nicht
invertiert sind. So brauche ich kein zus. Inverter und kann die LE der
einzelnen Laches direkt ansteuern. Es kommen dann zwei 238 zum einzatz,
wobei ein µC Pin den enable-Eingang als most significant Bit steuern. So
kommt dann auch eine Tiefe von 4 Bit, also 16 Kanalen zustande. So komme
ich dann auf 16x8 = 128, also gut 40 RGB-LED.

Besorgt bin ich aber die Kommunikation. Arbeitet der Chip im reinen
Slave modus, muss er ja pro Zyklus 256 Bytes empfangen. (Jeder Kanal,
adressiert). Aber es gibt ja kein Zeitfenster, in dem der µC Leerlauf
zum Empfang hat (Das Ausschalten der LED muss ja zu jedem Zeitpunkt
möglich sein)
Idee: Die 8 Pins, die mit den Latches verbunden sind, könnten Signale
aus dem Master µC auslesen. Das geht ja viel schneller, als seriell
über I^2C. Um zu vermeiden, dass Pins des Master CPU mit Low-Potential
anliegen, während der slave CPU dann die LED-Latches ansteuert, könnte
man da einen weiteren Latch zwischenschalten, dessen Tri-State Modus
von einem Ausgangspin des slave CPU gesteuert wird. (Ist komisch
ausgedrückt, ich hoffe es ist trotzdem irgendwie klar, was ich meine)

Nochmals vielen Dank an Hauke Radtki und Thomas O. Es macht viel mehr
Spass über solche Hardware nachzudenken, wenn man sieht, dass man nicht
alleine mit Problemen dasteht.

von Hauke Radtki (Gast)


Lesenswert?

Nunja. Du musst ja nicht immer einen kompletten "frame" übertragen. Du
könntest (müsstest) die zustände der LEDs im controller
speichern/verwalten. So könntest du dann mit dem master controller nur
LEDs umschalten die sich ändern. Das ganze geht dann in richtung
display controller, wie es sie in allen arten von displays eben gibt.

Und dann musst du dir ausrechnen, bei welcher frequenz du das ganze
betreiben willst. Wenn der controller mit 16MHz rennt und das SPI
schnell genug läuft denke ich nicht, dass du großartige probleme haben
wirst.

Das gesammte bild musst du mit ca 30 "fps" refershen, damit es fürs
auge als ein bild steht.

Und du kannst ja die Displaydaten genau in den zeitabständen zwischen
einer  zeile und der nächsten verarbeiten. Und z.b. mit einem noch
freien µC pin eine art busy flag errichten. So sendet der master µC
erst wieder daten sobald du im slave die daten verarbeitet hast.

von Thomas O. (Gast)


Lesenswert?

Eingänge sind ja in der Regel immer hochohmig, es kann aber sein das
erst eine Belastung ansteht wenn du das Latchs einschaltet, also ich
habe problemlos 3 Latches parallel betrieben um die Adressleitungen
eines EEPROMS zu beschalten, hatte sogar ein Widerstandsnetzwerk drin
damit die die Eingänge der Latches sicher auch Low bleiben.

von Philipp K. (phil323)


Lesenswert?

ich hatte eigentlich schon vor, zumindest die Möglickeit zu haben
komplette Frames zu übertragen. Bei einem abrupten Farbwechsel z. B.,
sollen wirklich alle LEDs, zumindest fürs Auge, gleichzeitig wechseln.
Kommen keine neuen Farbinformationen, wird die bisherige Farbe
natürlich beibehalten.
ich glaube 30 FPS reichen bei weitem nicht aus. Ich habe gelesen, dass
z. B. Kino oder Fernsehbilder nur deshalb mit 24 FPS flüssig wirken,
weil ein Bild unmittelbar aufs andere folgt. Es gibt also keine
"Dunkelzeiten", wie bei meinen PWM-gesteuerten LEDs. Ich habe bisher
mit 250 fps gute Resultate erziehlt.

Ich werde mal einen Testaufbau mit einem slave mit 3-8 Multiplexer und
8 8-Bit latches realisieren. Wenn ich dann pro Frame alle Daten
übertragen will, währen das 128 Byte. Wenn ich das parallel mache, und
vorsichtig geschätzt 10 Takte pro Byte brauche (möglicherweise warten
bis das Signal korrekt anliegt, auslesen, Mitteilung machen, dass
empfangen wurde, zwischenspeichern). Bei einer Taktung von 16 Mhz würde
das eine Zeit von 80 µs beanspruchen. Das entspricht einem 50-tel der
Framedauer. Dann werde ich versuchen, ob das Licht einer LED, die mit
einem 50-tel der Framedauer beschaltet ist schon sichtbares Licht
erzeugt. Falls nicht, kann ich ja dann alle LEDs einschalten, Daten
empfangen und anschließend die LEDs nach und nach abschalten. Falls
tatsächlich schon Licht zu sehen sein sollte, werde ich einfach Daten
empfangen, bevor ich die LEDs einschalte und somit auf 1/50 der
Intensität verzichten.
Das ich die Daten komplett als Block empfange, ist mir deshalb wichtig,
weil es bessere Skalierbarkeit ermöglicht. Der Master kann dann der
Reihe nach die Slaves mit Daten versorgen. Andernfalls müsste der
Master für jedes einzelne Byte auf Empfangsbereitschaft der einzelnen
Slaves hören.
Die Kommunikation über I^2C geht laut Datenblatt mit maximal 400kbps.
Wobei es sich warscheinlich um einen Theoretischen Wert handelt.
(Protokoll, Handshake, Adressierung, ...) Sollte der Theoretische Wert
erreicht werden, benötige ich dann immernoch 20µs für ein Byte. 128
Bytes würden bereits gut 2,5ms benötigen. Das sind bei 250 fps mehr als
50% der dauer eines Frames.
OK, mann könnte einwenden, dass ich bei 250 fps vielleicht nicht
wirklich alle Bytes auf einmal übertragen muss und trotzdem einen
schnellen Farbübergang aller LEDs erreichen kann. Bei 4 Bytes pro Frame
(Dauer min. 100µs) würde die komplette Farbänderung 32 Frames, also
128ms dauern. Das ist zwar recht schnell, aber wohl trotzem
wahrnehmbar. Ein schneller kontinuierlicher Farbverlauf aller LED währe
in dem Fall nur möglich, wenn man spezielle Befehle definiert, die vom
Slave selbständig ausgeführt würden.
Ob es tatsächlich parallele oder serielle Komunikation wird, wird das
Experiment entscheiden. Trotz der Vorteile der seriellen Kommunikation,
wie die Möglichkeit längere Kabel zu benutzen, weniger Adern...
bevorzuge ich moentan noch die parallele Variante.

---
Ich glaube das mit den Latches sollte problemlos funtionieren. Es wird
je immer nur einer eingeschaltet, nicht alle gleichzeitig. Ausserdem
sind die µC Ausgänge ja relativ stark. Bei der Kommunikation zw. master
und slave könnte ich sogar ganz auf latches verzichten, weil ich die µC
Pins hochohmig machen kann. Trotzdem werde ich in der Testphase einen
zwischenschalten, damit, nicht durch einen Programmierfehler, ein High
Ausgang eines Chips an einem Low-Ausgang eines andren Chips anliegt.

von Hauke Radtki (Gast)


Lesenswert?

Du könntest ja eine art kommando einführen, der ansagt, dass ein
kompletter frame übertragen wurde. So aktualisierst du dein display an
sich mit 250 fps aber die daten werden erst übernommen wenn der ganze
bildschirm aktualisiert wurde. So brauchst du zwar doppelt so viel Ram
aber es könnte sicher eine gute alternative sein.

Bei LCDs wird sowas auch verwendet. Da wird aus dem display ram auf das
LCD geschrieben. Jetzt schreibt man in eine andere Position im Ram neue
daten. Sobald der übertragungsvorgang abgeschlossen ist, wird der
"sichtbare" ram bereich auf den aktualisierten bereich gelegt und der
nächste frame in den alten ram bereich geschrieben. Ist zwar etwas
kompliziert ausgedrückt ist aber nur halb so schwer wenn mans erst mal
kapiert hat.

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.