Guten Tag zusammen. Ich habe zwar Erfahrungen mit dem Programmieren von Atmel Prozessoren, jedoch habe ich nie mit spi gearbeitet. Da ich jedoch eine Aufgabe habe, welche sehr Zeit Relevant ist dachte ich daran den WS2811 per SPI anzusteuern um den Rest nicht auszubremsen. Nun meine Recherche hat mich an viele Orte gebracht wo ich zum beispiel die FastLed librarie fand. Doch scheint dies nur für Arduino zu sein. Bzw habe ich weder herausgefunden wie ich den IC wähle und vorallem gab es fehler beim Kompilieren, dass dateien Fehlen.
Dominic K. schrieb: > Ich habe zwar Erfahrungen mit dem Programmieren von Atmel Prozessoren, > jedoch habe ich nie mit spi gearbeitet Warum nimmst Du dann nicht eine echte Anwendung mit SPI? Der WS2811-Bus hat wenig mit SPI zu tun (ok, er ist auch seriell ...) und Du mußt das Hardware-SPI im AVR ganz schön verbiegen, damit das irgendwie paßt. Ist meiner Meinung nach der falsche Weg SPI kennen zu lernen.
Gäbe es den eine andere Hardware serielle Schnittstelle in der Atmegaserie welche besser passt? Mit einem PWM wäre wohl eher aufwändig. Und der ws2811 ist hauptbestandteil des ganzen also kann ich ihn nicht einfach weglasen.
Dominic K. schrieb: > Gäbe es den eine andere Hardware serielle Schnittstelle in der > Atmegaserie welche besser passt? Ja, die UART im SPI-Modus (sofern man eine solche hat). Damit hat man die höchstmögliche Toleranz gegen Latenzprobleme, wegen des Double-Buffer der UART. Leider verfügen die älteren ATMegas oft zwar über eine oder gar mehrere UARTs, die haben aber noch keinen SPI-Modus...
habe mich zwar noch nie mit WS2811 beschäftigt, aber soweit ich die Datenübertragung des WS2811 verstanden habe wird ein HIGH mit einem Langen HIGH und kurzem LOW und ein LOW mit einem kurzen HIGH und einem langen LOW auf dem BUS des WS2811 dargestellt. Wenn das nicht so sein sollte und ich mich geirrt habe, dann vergiss das folgende... Wenn man SPI nimmt, könnte man "vielleicht" das so gestalten: Jedes benötigte WS-BUS Bit wird aus 3 SPI Bits gebildet. Dann hat man eben für zu sendende 24Bit 72Bit im Speicher, die über die SPI gesendet werden. Wird ein HIGH auf dem WS-BUS benötigt sendet SPI 1,1,0 und Wenn ein LOW auf dem WS-BUS benötigt wird, dann sendet SPI 1,0,0 solange bis alle 72 Bits (also für den WS-BUS dann nur 24Bit!) übertragen sind. Das bedeutet nach 9 Bytes sind die 24Bit WS-BUS übertragen. Es muss dann nur noch das Timing, also die Zeitspanne der 3 SPI Bits für den WS-BUS passen. Ob man die SPI allerdings so genau auf das Timing des WS-BUS dann einstellen kann müsste man halt mal ausprobieren. Wäre vielleicht eine Möglichkeit. Ansonsten könnte man das ganze natürlich auch per PWM machen. Eine Spezielle Schnittstelle an einem ATmega, die das Format des WS-Bus hat, kenne ich nicht.
Tom schrieb: > Wäre vielleicht eine Möglichkeit. So in der Art machen das die SPI-Implementationen für die WS2811. Das Timing ist bei denen auch nicht ganz so kritisch wie bei den integrierten ws2812, warscheinlich weil die 400 und 800kHz können.
Ich beutze für die WS2811/12 immer eine UART im 7N1 Modus mt negiertem Pin. Da das WS2811 Protokoll immer mit einem HIGH startet und einem LOW endet sind das Startbit und das Stopbit schonmal korrekt. Die 7 Datenbits bilden dann 3 zu übertragende Bits (Startbit +2, 3 Datenbits, 2 Daten + Stopbit). Das ganze mit 2.4Mbaud ergibt 800kHz Bitrate für die LEDs. Funktioniert perfekt bei minimalem Softwareaufwand.
hab für die WS2812B auch ein SPI verwendet, aber mit einem STM32 nicht atmel. War ein wenig verbiegung notwendig, ein WS2812B bit enstrpicht 4 SPI bits, dafür kann ich aber bequem DMA verwenden
Ben W. schrieb: > hab für die WS2812B auch ein SPI verwendet, aber mit einem STM32 nicht > atmel. > War ein wenig verbiegung notwendig, ein WS2812B bit enstrpicht 4 SPI > bits, dafür kann ich aber bequem DMA verwenden Ja, mache ich genau so. Nachteil : Pro LED werden 15 Byt RAM gebraucht. Vorteile : Es ist viel einfacher zu kodieren als 3-bit Blödsinn. Es ist Fire-and-forget - CPU merkt nichts von der Ausgabe. Es läuft ohne Probleme mit 8MHz SPI, also 1MHz für WS2812. 170 LEDs werden in etwa 4ms rausgefeuert, entspricht fast 250Hz. Und die dafür nötigen 2,5KB RAM kann ich sogar bei einfachsten Blue Pill ganz leicht verschmerzen - bei mindestens 20KB RAM... Ohne DMA lohnt sich der ganze Zirkus mit SPI bzw. UART kaum - da ist Bitbanging ganz einfach schneller und braucht zudem nur 3 Byt pro LED.
Marc V. schrieb: > Pro LED werden 15 Byt RAM gebraucht. Es geht auch sparsamer auf dem STM32. Man nehme: - einen Timer - zyklischen DMA-Transfer für jeweils 2 LEDs - ISR, welche den DMA-Buffer nach dem halben Transfer (also nach Datenübertragung für 1 LED) nachfüllt. RAM-Bedarf: 48 Bytes - unabhängig von der Anzahl der LEDs.
Frank M. schrieb: > - ISR, welche den DMA-Buffer nach dem halben Transfer (also nach > Datenübertragung für 1 LED) nachfüllt. Der Sinn (DMA) ist aber gerade in dem Fire-and-forget Prinzip. Wenn ich alle paar us irgendeine ISR anspringen muss, wird das Ganze ziemlich ineffizient, oder ? > RAM-Bedarf: 48 Bytes - unabhängig von der Anzahl der LEDs. Pro LED braucht man auf jeden Fall 3 Bytes, ob mit oder ohne DMA. RAM ist bei STM32 genügend vorhanden, aber Zeit (wie bei allen anderen uC) ist (fast) nie ausreichend vorhanden. Wenn man mit 1:4 bit SPI arbeitet, wird der SPI-Array zuerst in einem Rutsch (auch per DMA) mit Nullen (0x88) aufgefüllt, danach werden nur die entsprechenden log.1 bits (bzw. Nibbles in konkretem Fall) gesetzt. Das geht unheimlich schnell, mindestens 2 Mal so schnell wie mit 3-bit Quälerei. Danach wird DMA abgefeuert - und vergessen. Natürlich kann das jeder machen wie es ihm beliebt und so lange es richtig funktioniert ist es auch in Ordnung, nur kommen die Probleme meistens wenn man das Ganze nachträglich noch mit irgendeiner Funktion ergänzen will, welche womöglich auch mit ISR arbeitet und da bei STM32 die Interrupts Prioritäten haben...
:
Bearbeitet durch User
Marc V. schrieb: > Der Sinn (DMA) ist aber gerade in dem Fire-and-forget Prinzip. Wenn > ich alle paar us irgendeine ISR anspringen muss, wird das Ganze > ziemlich ineffizient, oder ? Kommt darauf an, was die ISR dafür noch veranstalten muss, um die DMA-Werte zu berechnen. Im Projekt WordClock mit WS2812 hatte ich zunächste alle 388 LEDs (288 fürs Display, 100 für das Ambilight) mit einem Riesen-DMA-Buffer gefüttert - so wie von Dir präferiert. Das war bei RGBW-LEDs (hier hast Du sogar 4 Farben) eine ziemliche Speicherverschwendung, so dass dann inkl. Animationen und anderen Spielereien plötzlich die 20KB RAM eines STM32F103C8T6 fast aufgebraucht waren. In diesem Falle hat der Wechsel auf einen zirkularen DMA-Buffer jedenfalls eine Menge gebracht. Die Zeit, welche die ISR da verbraucht, um den DMA-Buffer kontinuierlich zu füttern, kann man dabei wirklich vernachlässigen. Von "ineffizient" kann da keine Rede sein. Im Gegenteil: Durch das nun mögliche Double-Buffering wurde das ganze wesentlich effizienter: Während die DMA den alten Ringbuffer noch abarbeitet, kann das Hauptprogramm schon den nächsten Frame für alle 388 LEDs berechnen, z.B. für Animationen und Fading. Das Double-Buffering wäre mit einer Verdopplung des Riesen-DMA-Buffers nicht mehr möglich gewesen. Manchmal kann man mehr durch geschickte Programmierung rausholen als durch brachialen Einsatz von RAM. Natürlich nicht generell, in diesem speziellen Fall aber schon. ;-)
:
Bearbeitet durch Moderator
Frank M. schrieb: > Manchmal kann man mehr durch geschickte > Programmierung rausholen als durch brachialen Einsatz von RAM. Natürlich > nicht generell, in diesem speziellen Fall aber schon. ;-) Wenn du von der WordClock redest, ja, stimme ich zu. Wir machen z.Zt. ein Projekt mit 512 LEds und verwenden immer noch DMA mit 1:4 SPI. Es braucht zwar 512 * 15 + 1536 = 9KB, aber es sind immer noch 11KB RAM übrig und 70Hz Refresh Rate ist locker zu schaffen. LED-Array ist double-buffered - deswegen die zusätzlichen 1,5KB RAM, SPI-Array aber nicht. LED-Arrays werden abwechselnd von der SD-CARD per DMA eingelesen und danach nach SPI-Array ausgerollt. Selbst das wäre nicht nötig, aber SD-Cards sind manchmal zickig - deswegen. STM32 merkt aber kaum etwas davon - von den 14,3ms pro Frame ist die CPU höchstens 1-2% der Zeit damit beschäftigt. Und 98% der Zeit für andere Aufgaben frei zu haben ist meistens viel wichtiger als 50% des RAMs frei zu haben, zumal es für nicht benutzten RAM keinen Bonus gibt. Irgendwo ist da natürlich eine Grenze, aber solange die nicht erreicht ist, werde ich versuchen, den ganzen Zirkus so einfach wie nur irgend möglich zu halten...
:
Bearbeitet durch User
Frank M. schrieb: > > Kommt darauf an, was die ISR dafür noch veranstalten muss, um die > DMA-Werte zu berechnen. > klingt interessant, muss ich mir mal genauer anschauen
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.