Forum: Mikrocontroller und Digitale Elektronik WS2811 mit SPI(atmega 2560)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dominic K. (domi1997)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von Horst (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von Dominic K. (domi1997)


Bewertung
0 lesenswert
nicht lesenswert
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.

von c-hater (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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...

von Tom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Horst (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von pitschu (Gast)


Bewertung
2 lesenswert
nicht lesenswert
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.

von Ben W. (ben_w)


Bewertung
0 lesenswert
nicht lesenswert
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

von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
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.

von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
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
von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
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
von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
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
von Ben W. (ben_w)


Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.