Schönen guten Tag!
Ich möchte gerne die Einzelteile eines Displays parallel von jeweils
einem eigenen µC steuern lassen. Daten für die Darstellung kommen aus
einem externen Flash, und ich habe mir das so vorgestellt: Ein
Master-Controller kümmert sich um das Einlesen der Daten und verschickt
die jeweils interessanten Teile an den entsprechenden Slave, der sich
dann um die Darstellung kümmert.
Damit die einzelnen Teile des Displays auch gleichzeitig aktualisiert
werden, müssen nach dem (seriellen) Übertragen der Daten alle Slaves zu
einem gemeinsamen Zeitpunkt ein "Startsignal" bekommen. Das könnte z. B.
in Form eines externen Interrupts passieren. Alle Slaves hängen
gemeinsam an einem Ausgang des Masters, der dann im entscheidenden
Moment umgeschaltet wird, um den Interrupt bei den Slave auszulösen.
Da ich ziemlich viele Daten schnell übertragen möchte, fällt TWI mit
seinen max. 400 kbps wohl zugunsten von SPI flach ... Oder wäre es u. U.
schlauer, jeden Slave selber direkt aus dem Flash lesen zu lassen,
anstatt den Umweg über den Master zu gehen? Wie könnte in diesem Fall
das anschließende "Startsignal" aussehen?
Grüße,
Alex
Hallo Travel Rec.
Waren denn die Fragen am Ende meines Beitrags nicht konkret genug? Ich
wüßte gerne, welche möglichen Nachteile die von mir skizierte Variante
zum Verteilen der Bilddaten von einem zentralen Controller aus hat und
ob Ihr mir noch andere Alternativen ans Herz legen könnt.
Mit welchen weiteren Informationen zu meinem Vorhaben kann ich Euch
helfen zu helfen? Ich würde ganz gerne sowas wie den ATmega 8/16 als
Master und irgendeinen ATtiny für die Slaves benutzen. Das scheint mir
auf den ersten Blick zu reichen. Je nachdem, wie der Ablauf nun im
Detail aussehen wird, müßte ich dann ggf. was passenderes wählen ...
Gruß,
Alex
Ok, fangen wor mal ganz vorne an:
WAS BITTE sind die EINZELTEILE eines Displays?
Glasscheibe?
Metallrahmen?
Schrauben?
Stecker?
Und WARUM merkst Du nicht selbst, dass damit niemand etwas anfangen
kann?
Warum merkst Du das nicht selbst?
Woran genau liegt das?
Wie ist das erklärbar, dass Du das selbst nicht merkst?
Jochen Müller
ich denke das geht ehr in die Richtung das ein 2x16 oder 4x16 aufgeteilt
werden soll. Ein uC (Applikation) pro Zeile.
Ich hatte sowas auch schon mal vor gehabt. Aber die einzige Lösung wäre
ein 4x27, da es 2 Controller hat. Somit könnten sich 2 Applikationen das
Diplay "teilen".
Sonst bleibt nur ein Master für das Display exclusiv und die Slaves
füttern ihn mit den Daten.
Hallo Jochen!
> Ok, fangen wor mal ganz vorne an:>> WAS BITTE sind die EINZELTEILE eines Displays?
Es geht im Speziellen um ein LED-Display, welches tatsächlich auch aus
Schrauben, Steckern usw. besteht. Mit den Einzelteilen meinte ich
jedoch, daß ich eine größere Matrix in kleinere 8×8-Blöcke (ggf. noch
kleiner) zerlegen möchte, da das gesamte Teil über Multiplex angesteuert
werden soll und sich für kleinere Matrizen Pulsströme und
Multiplexfrequenz in Grenzen halten.
Jeder Block soll nun von einem eigenen Controller "gezeichnet" werden.
Das scheint mir notwendig, um größere Datenmengen (z. B. durch
Animationen oder eine Software-PWM, so sie denn tatsächlich mit diesem
Aufbau zu realisieren sein wird) bewältigen zu können. Da die Teilblöcke
zusammen ein großes Gesamtbild ergeben, muß das Anzeigen jeweils
möglichst zeitgleich geschehen.
> Und WARUM merkst Du nicht selbst, dass damit niemand etwas anfangen> kann?> Warum merkst Du das nicht selbst?> Woran genau liegt das?> Wie ist das erklärbar, dass Du das selbst nicht merkst?
Wenn als einzige Antwort zurückkommt, ich solle bitte konkreter werden,
hilft mir das nicht viel beim Erraten, auf welche Informationen Ihr
speziell aus seid. Daher meine Nachfrage. Ich dachte, ich halte es
vorerst allgemein, weil ich auch mit allgemeinen Antworten zu den
skizzierten Abläufen gerechnet hatte, etwa: "Also um mehrere Controller
zu einem Zeitpunkt zu synchronisieren, macht man besser dies statt das
..." Damit lag ich offenbar daneben, hoffe aber, daß mit der obigen
Beschreibung in diesem Beitrag nun etwas klarer geworden ist, in welche
Richtung es gehen soll.
Gruß,
Alex
Wie groß ist denn das gesamte Display ? Das ist denke ich die wichtigste
Info, denn davon hängt ab, wieviele Daten für jedes Bild übertragen
werden müssen.
Hallo Stephan!
> ich denke das geht ehr in die Richtung das ein 2x16 oder 4x16 aufgeteilt> werden soll. Ein uC (Applikation) pro Zeile.
Tut mir leid für das Ratespiel (siehe dazu auch mein voriger Beitrag).
Ich möchte tatsächlich ein größeres Display in kleinere Teile zerlegen,
die dann (hoffentlich) einfacher anzusteuern sind. Prinzipiell wäre es
natürlich schön, beliebig viele 8×8-Blöcke zusammenschalten zu können.
Vermutlich wird aber wirklich das Rumschicken der Bilddaten an die
Slaves ab einer bestimmten Größe zum Engpaß, wenn beispielsweise (wegen
Multiplex und Soft-PWM) je eine Zeile 8×100×256 = 204800 mal pro Sekunde
gezeichnet werden muß. Nur eben parallel auf mehreren der Teildisplays,
die dann z. B. 25 mal pro Sekunde mit neue Bilddaten versorgt werden
müssen ...
Gruß,
Alex
Grüße Dich, Benedikt!
> Wie groß ist denn das gesamte Display ? Das ist denke ich die wichtigste> Info, denn davon hängt ab, wieviele Daten für jedes Bild übertragen> werden müssen.
Toll wäre natürlich eine Lösung, die beliebig viele Einzelblöcke
ermöglicht. Da das wohl ohne größere Rechner nicht zu machen sein wird,
würde ich es erstmal gerne mit 32×32 oder auch 24×24 Pixeln versuchen.
Gruß,
Alex
OK, das sind doch mal konkrete Zahlen.
32x32 = 1024Pixel = 1kByte
Ist das ein RGB Display ? Denn das verdreifacht die Pixel.
Aber selbst 3kByte x 25fps sind gerade 75kByte/s, was selbst mit etwas
höher getaktetem I2C (z.B. 1MHz) noch funktionieren sollte.
Ich würde die Daten zentral einlesen und dann weiter verteilen. Die
Verteilung der Daten würde ich per SPI machen, damit kommt man bis auf
1/4 CPU Takt, als ein paar MHz. Ich würde die ganzen Blöcke alle in
Reihe schalten und die Daten quasi der Reihe nach durchschieben (oder
zumindest in jeder Zeile). Dann kommt ein Latch Signal, mit dem die
ganzen Controllern die Daten übernehmen und in den internen Speicher
kopieren.
Für jeden Controller einen eigenen ChipSelect Anschluss wird schnell
ziemlich aufwendig: Bei 32x32 Pixel sind es schon 4x4 also 16
Chipselects.
>Daten quasi der Reihe nach durchschieben
Ja, das ist vermutlich das sinnvollste. Dasselbe Prinzip verwenden ja
auch entsprechende Treiber.
Du solltest dir allerdings überlegen, ob es sinnvoll ist einen µC für
jeden Block zu nehmen. Bei den dafür notwendigen Taktraten hast du
schnell Latenzprobleme im µC. Vielleicht sind fertige ICs dafür
sinnvoller.
Hallo Benedikt!
> 32x32 = 1024Pixel = 1kByte> Ist das ein RGB Display ? Denn das verdreifacht die Pixel.> Aber selbst 3kByte x 25fps sind gerade 75kByte/s, was selbst mit etwas> höher getaktetem I2C (z.B. 1MHz) noch funktionieren sollte.
Nein, kein RGB. Aber ich möchte schon versuchen, eine 8-Bit-PWM zu
integrieren, um für jeden Pixel einige Graustufen darstellen zu können.
Aber das hast Du in der Rechnung ja offenbar schon berücksichtigt.
Wenn ich nun ein Paket von 1 kByte zu Beginn eines neuen Frames am Stück
senden (und empfangen) möchte, können sich die Controller für diesen
Zeitraum nicht mit dem Darstellen der Bilddaten befassen. Richtig? Der
Timer zum Aktualisieren der nächsten Zeile im Multiplexbetrieb würde die
Übertragung etliche Male unterbrechen. Ich könnte das Paket also
möglichst schnell übermitteln, bevor das Zeichnen der nächsten Zeile
ansteht. Das würde (für diesen kurzen Moment) eine ziemlich hohe
Datenrate benötigen ... Oder ich laß über die Dauer eines Frames alle
0,9 ms ein Byte durch die Leitung "tröpfeln", bis zum Beginn des
nächsten Frames alle Daten übermittelt wurden. Funktioniert das in
dieser Form?
> Ich würde die ganzen Blöcke alle in Reihe schalten und die Daten quasi> der Reihe nach durchschieben (oder zumindest in jeder Zeile). Dann kommt> ein Latch Signal, mit dem die ganzen Controllern die Daten übernehmen> und in den internen Speicher kopieren.
Etwas in der Art möchte ich für die eigentlich Darstellung eines
einzelnen Displayblocks verwenden: serielles Datenbyte vom Controller
mittels Schiebregister/Latch in 8 parallele Zuleitungen zur LED-Matrix
wandeln (angenommen, das Display besteht aus 16 8×8-Blöcken). Wie
funktioniert das genau im Falle der Datenübermittlung von Master zu
Slave? Damit auf ein einziges Signal hin alle Controller die Pixeldaten
für ihren Block bekommen können, müßten die doch auch zeitgleich an den
Eingängen des Controllers anliegen. Oder reden wir gerade aneinander
vorbei?
Auf welche Weise erreiche ich nun eigentlich, daß alle Controller ihren
Teil des Displays jeweils zeitgleich aktualisieren (beispielsweise mit
100 Bildern/Sekunde)? In meinem ersten Beitrag hatte ich ja von einem
externen Interrupt gesprochen, der als eine Art zentraler Takt von
Master ausgelöst wird. Gibt es noch bessere Möglichkeiten? Ist es
überhaupt nötig, die Slaves so zu synchronisieren? Ich könnte mir
vorstellen, daß es mit fortlaufender Zeit immer größere Differenzen im
Timing gibt, wenn jeder Controller seinen Block nur auf Basis des
eigenen Taktgebers zeichnet ...
> Für jeden Controller einen eigenen ChipSelect Anschluss wird schnell> ziemlich aufwendig: Bei 32x32 Pixel sind es schon 4x4 also 16> Chipselects.
Mit Cipselect meinst Du, daß der Master der Reihe nach jeden Slave über
eine eigene Leitung die Daten übermittelt?
Gruß,
Alex
Hi Matthias!
> Du solltest dir allerdings überlegen, ob es sinnvoll ist einen µC für> jeden Block zu nehmen. Bei den dafür notwendigen Taktraten hast du> schnell Latenzprobleme im µC. Vielleicht sind fertige ICs dafür> sinnvoller.
Ich würde liebend gerne fertige ICs verwenden. Allerdings habe ich
bisher keine gefunden, die für ausreichend hohe Ströme ausgelegt sind.
Durch das 8-fach-Multiplexen müßte ich jeder LED etwa den achtfachen
Pulsstrom verabreichen, damit sie ähnlich hell leuchtet, wie im normalen
Betrieb. Damit käme ich pro Zeile mit 8 LEDs auf rund 1,3 A. Was ich
bisher an prominenten Treibern von Maxim und TI gesehen habe (MAX 7219,
TLC 5940), machte schon bei unter 200 mA Schluß. Oder ist mit diesen
Maximum Ratings doch etwas anderes gemeint?
Gruß,
Alex
Alex wrote:
> Wenn ich nun ein Paket von 1 kByte zu Beginn eines neuen Frames am Stück> senden (und empfangen) möchte, können sich die Controller für diesen> Zeitraum nicht mit dem Darstellen der Bilddaten befassen. Richtig?
Falsch.
Die Ausgabe der Daten machst du im Interrupt. Im Hauptprogramm kommt das
Nachladen. Einziges Problem dabei: Die Interruptroutine darf nicht
länger dauern als der Empfang eines Bytes, ansonsten läuft der Puffer
über. Abhilfe: Interrupts im Interrupt wieder freigeben (allerdings
sollte man sich dann ein paar Gedanken machen, denn sowas kann böse
enden, wenn man was falsch macht.)
>> Auf welche Weise erreiche ich nun eigentlich, daß alle Controller ihren> Teil des Displays jeweils zeitgleich aktualisieren (beispielsweise mit> 100 Bildern/Sekunde)?
Indem du ein Signal anlegst, das z.B. einen Interrupt auslöst in dem die
Daten in den Displaybuffer kopiert werden.
> Mit Cipselect meinst Du, daß der Master der Reihe nach jeden Slave über> eine eigene Leitung die Daten übermittelt?
Ja, so in etwa.
> Ich würde liebend gerne fertige ICs verwenden. Allerdings habe ich> bisher keine gefunden, die für ausreichend hohe Ströme ausgelegt sind.> Durch das 8-fach-Multiplexen müßte ich jeder LED etwa den achtfachen> Pulsstrom verabreichen, damit sie ähnlich hell leuchtet, wie im normalen> Betrieb. Damit käme ich pro Zeile mit 8 LEDs auf rund 1,3 A.
Pro LED reichen 10mA Mittelwert, also 80mA Spitzenstrom. Ich habe bei
mir TLC594x verwendet. Die machen einen einstellbaren Konstantstrom und
eine 12bit PWM.
Für die Zeilen dann einfach ein Logiklevel Mosfet. Der kommt mit ein
paar Ampere Spitzenstrom gut zurecht.
Wie ich in einem anderen Thread geschrieben habe:
Bei guten LEDs reichen wenige 10mA Spitzenstrom bei weitem aus.
Beitrag "Re: LowCurrent LED braucht 20mA."
Darum verwenden Profis vielleicht auch LEDs, die nicht wie vor 30 Jahren
mit 20mA angesteuert werden.
Sieh Dir mal Ultra-Bright oder High-Efficency oder so LEDs an und nutzt
hier mal die Suchfunktion, ist schon mehrfach durchgekaut worden.
Hallo Benedikt!
> Die Ausgabe der Daten machst du im Interrupt. Im Hauptprogramm kommt das> Nachladen. Einziges Problem dabei: Die Interruptroutine darf nicht> länger dauern als der Empfang eines Bytes, ansonsten läuft der Puffer> über.
Ja, das mit der Interruptansteuerung ist mir klar. Deswegen meinte ich,
daß das Entgegennehmen der Daten etliche Male vom Zeichnen der Zeilen
unterbrochen wird. Der Empfangspuffer am Slave sollte also zwischen
diesen Interrupts häufig genug geleert werden, dann kann der Controller
auch "während des Empfangens" die momentan noch aktuellen Zeilendaten
zeichnen, anstatt dies für den Empfang kurzzeitig komplett zu
unterbrechen. Ok.
> Abhilfe: Interrupts im Interrupt wieder freigeben (allerdings> sollte man sich dann ein paar Gedanken machen, denn sowas kann böse> enden, wenn man was falsch macht.)
Ja, im AVR-Tutorial und anderen Artikeln auf dieser Seite wird
gelegentlich darauf hingewiesen. :-)
> > Auf welche Weise erreiche ich nun eigentlich, daß alle Controller ihren> > Teil des Displays jeweils zeitgleich aktualisieren (beispielsweise mit> > 100 Bildern/Sekunde)?>> Indem du ein Signal anlegst, das z.B. einen Interrupt auslöst in dem die> Daten in den Displaybuffer kopiert werden.
Gut, dann war diese Idee schonmal nicht verkehrt ...
> Pro LED reichen 10mA Mittelwert, also 80mA Spitzenstrom. Ich habe bei> mir TLC594x verwendet. Die machen einen einstellbaren Konstantstrom und> eine 12bit PWM.
Hmm, ich habe schon eine Menge unterschiedlicher LEDs von Reichelt
ausprobiert (auch einige Ultra Brights und HE mit dabei). Die waren alle
deutlich dunkler, wenn ich sie solch geringeren Pulsströmen aussetzte.
Werd wohl noch etwas weitersuchen müssen ...
Gruß,
Alex