mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik WS2812 LED-Streifen mit Raspberry Pi 3 ansteuern?


Autor: Flo (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo Forum,

ich hab versucht einen WS2812 RGB LED Ring mit dem Raspberry Pi 3 
anzusteuern. Klappte leider nicht :(

Mit meinem Arduino ging es problemlos, die LEDs sind also in Ordnung.

Für den Raspberry Pi 3 benutzte ich die Library von jgarff 
(https://github.com/jgarff/rpi_ws281x.git) die auch im Adafruit Tutorial 
beschrieben wird 
(https://learn.adafruit.com/neopixels-on-raspberry-...). Leider 
bekomme ich damit nur Flackern. Kann gut sein, dass es mit älteren 
Raspberry Pis funktioniert, mit dem 3er wohl nicht.

Hat es von euch jemand geschafft WS2812 mit dem Pi 3 anzusteuern?

Viele Grüße,
Flo

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es soll wohl gehen, ich bleibe skeptisch weil der PI kein Echtzeitsystem 
ist und das Timing eben nicht eingehalten werden kann.

Vielleicht findest du ja andere LIBs für den PI die das besser können.

Autor: Mikro 77 (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Für den Raspberry Pi 3 benutzte ich die Library von jgarff ... Leider
> bekomme ich damit nur Flackern. Kann gut sein, dass es mit älteren
> Raspberry Pis funktioniert, mit dem 3er wohl nicht.

Hast du die Build Instructions gelesen? Welches Timing benutzt du?

Grundsätzlich sollte das mit jedem Pi gehen, ob Bit Banging, native SPI 
oder über die Pi's PWM/DMA Schnittstelle des o.g. Autors.

Joachim B. schrieb:
> es soll wohl gehen, ich bleibe skeptisch weil der PI kein
> Echtzeitsystem
> ist und das Timing eben nicht eingehalten werden kann.

Gerade SPI "Timings" mit niedrigen Durchsatz, die idR sehr flexibel 
sind, bekommt man auf einem Single Core Pi mit Bit Banging hin. Sollte 
tatsächlich mal Suspended worden sein, setzt man einfach neu auf. Bei 
einem Multi Core seized man einen Core im RT Modus. Unabhängig davon 
gibt es noch die dedizierten SPI und PWM/DMA Schnittstellen oder einfach 
GPIO/DMA, die man auch aus Userland ansprechen kann. [Raspbian]

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> Gerade SPI "Timings" mit niedrigen Durchsatz, die idR sehr flexibel
> sind, bekommt man auf einem Single Core Pi mit Bit Banging hin.

Es gibt aber bei WS2812b LEDs keinen Clock, nach einer langen 
Bitschieberei muss das Timing für die Übernahme stimmen.

Ich wüsste im Moment nicht ob man das im SPI hinbekommt weil dazu auch 
immer SCK gehört, oder darf man den dann ignorieren?

: Bearbeitet durch User
Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

: Bearbeitet durch User
Autor: yesitsme (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist der Soundtreiber geladen? (Nicht das der umbenannt wurde oder sows)
Mach mal ein "lsmod" auf der Shell.

Hast du einen Levelshifter verbaut?

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yesitsme schrieb:
> Hast du einen Levelshifter verbaut?

wichtiger Hinweis, der PI bringt keine 5V signale!

http://www.js-home.org/hausautomat/index.php/BSTAR...

Autor: Mikro 77 (mikro77)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Joachim B. schrieb:
> Es gibt aber bei WS2812b LEDs keinen Clock, nach einer langen
> Bitschieberei muss das Timing für die Übernahme stimmen.

Ah, ok, habe gerade mal das Datenblatt angeschaut. Kein Clock. Die 
Timings sind auch schon so, dass man beim Bit Banging etwas mehr 
aufpassen muss. Ungepactes DMA/GPIO könnte evtl daneben gehen.

Über PWM/FIFO/DMA (gepaced) wie vom Autor oben sollte das problemlos 
sein. SPI sollte imho auch gehen, Clock liegt dann halt frei.

> Ich wüsste im Moment nicht ob man das im SPI hinbekommt weil dazu auch
> immer SCK gehört, oder darf man den dann ignorieren?

Ich hatte bisher noch keinen WS2812b. Werd' ich mir mal bestellen und 
angucken. :-)

Autor: Horst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> Ich hatte bisher noch keinen WS2812b. Werd' ich mir mal bestellen und
> angucken. :-)

und wieder jemand der hier auf etwas Antwortet von dem er keine Ahnung 
hat und nur Unsinn schreibt.

Und nein, die WS2812 haben mit SPI nichts zu tun und auf einem normalen 
Pi geht das auch nicht per SPI. Das Timing ist nicht stabil genug und 
läuft weg, die Folge ist Farbflackern.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Levelshifter ist verbaut. 5V wird von extern bezogen (nicht vom PI). GND 
vom PI und von der Stromquelle sind verbunden. Nutzt aber alles nichts.

Bisher hab ich im Netzt noch nichts gefunden was beschreibt wie WS2812 
mit einem PI 3 funktioniert.

Mal noch ne ganz andere Frage: Wenn ich mir einen ATMEGA328 dazwischen 
schalte (mit den (angepassten) Neopixel Libs von Adafruit), würde das 
funktionieren? Ich meine wegen der internen Clock. Wäre die fürs Timing 
genau genug?

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Flo schrieb:
> Bisher hab ich im Netzt noch nichts gefunden was beschreibt wie WS2812
> mit einem PI 3 funktioniert.

https://hyperion-project.org/wiki/3-Wire-PWM

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Mal noch ne ganz andere Frage: Wenn ich mir einen ATMEGA328 dazwischen
> schalte (mit den (angepassten) Neopixel Libs von Adafruit), würde das
> funktionieren? Ich meine wegen der internen Clock. Wäre die fürs Timing
> genau genug?

 LOL.
 Sicher, WS2812 kann man von 400KHz bis (fast) 1MHz ansteuern.
 Nur die Pause zwischen 2 Bytes soll nicht länger als etwa 20us sein,
 ansonsten werden die Daten gelatcht und angezeigt - auch wenn 50us
 angegeben sind - WS2812 sind in der Beziehung ein bisschen zickig.

Horst schrieb:
> Und nein, die WS2812 haben mit SPI nichts zu tun und auf einem normalen
> Pi geht das auch nicht per SPI. Das Timing ist nicht stabil genug und
> läuft weg, die Folge ist Farbflackern.

 Und ja, mit SPI kann man die Dinger auch ansteuern, nur braucht das
 wesentlich mehr RAM und bringt keine Vorteile, ausser man macht das
 per DMA.

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> Und ja, mit SPI kann man die Dinger auch ansteuern, nur braucht das
>  wesentlich mehr RAM

wieso?

leuchtet mir grad nicht ein,

bis jetzt hatte ich immer RGB Arrays a 3 Byte für jede LED

ob die nun so rumliegen 100 LEDs -> 300 Byte und egal wie auch per SPI 
müssen die rausgeschoben werden, wo kommt also dein genannter 
Mehrverbrauch her?

Autor: Johannes S. (jojos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich steuere die WS2812b auch über SPI an. Dabei wird ein WS Bit durch 3 
SPI Bits erzeugt. Mit einem SPI Takt von 2,4 MHz bekommt man Bitzeiten 
von 416 ns, mit 1-0-0 oder 1-1-0 passt die 800 kHz Ansteuerung also. 
Wichtig ist das man den SPI Takt genau einstellen kann, mit Cortex-M von 
NXP klappt das gut, mit dem STM32F103 habe ich das nicht hingebkommen 
weil der nur eine 2^n Teilerstufe für den Takt hat.
Wenn man ein die 1-auf-3 Expandierung in der SPI Ausgabe macht braucht 
man nicht mehr Speicher. Die SPI Implementierung beim RaspPi kenne ich 
nicht, wenn die blockweise arbeitet muss man eventuell den Framebuffer 
vor der Ausgabe enkodieren und braucht damit mehr RAM. Was auf dem RPi 
aber nicht wirklich stört...
Das ist aber ein SPI 'Missbrauch' und man hat keine Garantie das diese 
Methode auf eweig funktioniert. Auch bei den LPC habe ich verschiedene 
SPI Hardware Implementierungen gefunden die Unterschiedliche Behandlung 
in der SW nötig machte.
PS:
ein LPC812 wäre ein günstiger Treiber: Slave SPI um die RGB-Frames über 
'echtes' SPI zu empfangen, und eine zweite SPI um die LED Kette zu 
steuern. Der LPC braucht keine aufwändige HW, nur einen 
Abblockkondensator wenn man will. Programmierung über Bootloader im ROM 
per RS232-TTL Adapter.

: Bearbeitet durch User
Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Joachim B. schrieb:
> ob die nun so rumliegen 100 LEDs -> 300 Byte und egal wie auch per SPI
> müssen die rausgeschoben werden, wo kommt also dein genannter
> Mehrverbrauch her?

 Weil die bits nicht 1:1 rausgetaktet werden.
 Entweder man enkodiert es vorher, dann braucht es mehr RAM, geht
 aber schneller oder man enkodiert es in Echtzeit bei der Ausgabe,
 dann bringt das aber keine Vorteile gegenuber Bitbanging.

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> Weil die bits nicht 1:1 rausgetaktet werden.

das erklärt es

Johannes S. schrieb:
> ich steuere die WS2812b auch über SPI an. Dabei wird ein WS Bit durch 3
> SPI Bits erzeugt.

und leuchtet (mir auch ein)

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> oder man enkodiert es in Echtzeit bei der Ausgabe,
>  dann bringt das aber keine Vorteile gegenuber Bitbanging.

Doch. Denn das Encodieren des nächsten Bytes kann erfolgen während das 
vorherige noch herausgrtaktet wird.

Mit dem UART müsste es übrigens auch gehen, selbes Prinzip.

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd K. schrieb:
> Doch. Denn das Encodieren des nächsten Bytes kann erfolgen während das
> vorherige noch herausgrtaktet wird.

 Bringt keine nennenswerten Vorteile.
 Bei Bitbanging ist die CPU Auslastung 100% aber mit 800KHz geht das
 Ganze relativ flott heraus.
 Bei SPI und Encodierung in Echtzeit geht das raussenden zwar ohne das
 die CPU belastet wird, aber die Encodierung und das ständige hin- und
 herspringen von main zu ISR machen das wieder zunichte.
 Einzig sinnvolles Verfahren mit SPI ist vorheriges vorbereiten und
 Ausgabe mit DMA.

> Mit dem UART müsste es übrigens auch gehen, selbes Prinzip.

 Das macht erst recht keinen Sinn - bei welcher Geschwindigkeit soll
 das von sich gehen ?

: Bearbeitet durch User
Autor: Johannes S. (jojos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim SPI sehe ich noch den Vorteil das man gegenüber BB unabhängiger vom 
CPU Takt ist. Die SPI Implementierung funktioniert auf einer ganzen 
Reihe von µCs ohne mühsehlig Takte zählen zu müssen.

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
>> Mit dem UART müsste es übrigens auch gehen, selbes Prinzip.
>
>  Das macht erst recht keinen Sinn - bei welcher Geschwindigkeit soll
>  das von sich gehen ?

Der kann angeblich bis zu 4MBaud, da lässt sich evtl schon ein Bitmuster 
im passenden Timing erzeugen das der ws2812 schluckt.

Autor: c-hater (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Marc V. schrieb:

>> Mit dem UART müsste es übrigens auch gehen, selbes Prinzip.
>
>  Das macht erst recht keinen Sinn - bei welcher Geschwindigkeit soll
>  das von sich gehen ?

Oh mein Gott, einfach mal rechnen?

Fakt ist, dass es selbst mit einem AVR@20MHz relativ problemlos möglich 
ist, per SPI (bzw. hier: UART im SPI-Modus) die Daten ohne Jitter und 
mit Vmax rauszuschicken. Ein fertige, voll funktionsfähige 
Implementierung dafür habe ich schonmal hier geposted.

Und an diesem kann man auch sehr schön sehen, dass die Sache selbst bei 
so einem AVR enorme Vorteile bringt: Statt nämlich die MCU zu 100% mit 
überwiegend dümmlicher Vernichtung von Rechenzeit auszulasten, benötigt 
man nur ca. 45% der Rechenzeit für die Aufbereitung und Ausgabe des 
auszugebenden Bitstreams. Das läßt dann genug Rechenzeit über, dass man 
sehr viele Effekte sogar in Echtzeit berechnen kann, dann also überhaupt 
keinen "display buffer" im RAM benötigt.

Und wo es entweder nicht mehr in Echtzeit berechenbar ist, weil es zu 
komplex wird oder weil das Gewünschte mathematisch überhaupt nicht 
abbildbar ist, dann braucht man exakt so viel RAM als Displaybuffer wie 
in jeder anderen Lösung auch. Nämlich Anzahl der LEDs * 3 Farben.

Bloß, dass man dann trotzdem halt immer noch dauerhaft 45% der 
Rechenzeit über hat, um diesen Buffer auch permanent mit den Daten zu 
füllen, die ausgegeben werden sollen. Mit Vmax wohlgemerkt, also mit 
voller Ausnutzung der Fähigkeiten der WS28xx bezüglich der erzielbaren 
Framerate...

Vielleicht lernst du endlich mal programmieren?

Übrigens: Wenn man die UART tatsächlich als UART (und nicht im 
SPI-Modus) verwendet, geht es nochmal ein wenig besser, dann kommt man 
sogar auf knapp über 60% freier Rechenzeit. Leider ist beim AVR dafür 
ein kleiner Trick nötig, weil Atmel keine Möglichkeit spendiert hat, die 
Polarität der Ausgabe am TX-Pin in Hardware zu invertieren. Beim Raspi 
ginge das hingegen schon...

@Flo:

Beim Raspi ware das Prinzip (egal ob SPI oder UART) leider deutlich 
komplizierter umzusetzen als beim AVR. Jedenfalls wenn Linux als OS die 
Basis sein soll...

Dazu würde nämlich der Kern meiner AVR-Lösung als Treiber umgesetzt 
werden müssen, sonst grätscht das nicht echzeitfähige System für den 
userspace immer mal wieder in die Ausgabe des Bitstreams 
ein->unbrauchbar.
Und das Schreiben so eines Treibers ist nicht ganz trivial, das wäre 
auch für mich richtig Arbeit.

Da werfe ich lieber Linux ganz weg und programmiere den Raspi bare 
metal. Erst dann wird wirklich klar, wieviel schneller als ein AVR so 
ein Teil wirklich ist...

Und nebenbei: wie ungeeignet Linux eigentlich für die Aufgaben ist, die 
ein µC üblicherweise zu erledigen hat...

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Beim SPI sehe ich noch den Vorteil das man gegenüber BB unabhängiger vom
> CPU Takt ist. Die SPI Implementierung funktioniert auf einer ganzen
> Reihe von µCs ohne mühsehlig Takte zählen zu müssen.

Bernd K. schrieb:
> Der kann angeblich bis zu 4MBaud, da lässt sich evtl schon ein Bitmuster
> im passenden Timing erzeugen das der ws2812 schluckt.

 Mag sein, ich bleibe trotzdem bei Bitbanging - 170 LEDs in weniger als
 5ms bei etwas gestrafftem Timing reicht für mich (und Systimer)
 vollkommen.
 Bei 50Hz Refreshrate ergibt das 25% CPU Auslastung.

c-hater schrieb:
> Und wo es entweder nicht mehr in Echtzeit berechenbar ist, weil es zu
> komplex wird oder weil das Gewünschte mathematisch überhaupt nicht
> abbildbar ist, dann braucht man exakt so viel RAM als Displaybuffer wie
> in jeder anderen Lösung auch. Nämlich Anzahl der LEDs * 3 Farben.

 Sicher.
 Aber nur in deinem Kopf und in deiner (Wunsch)Anwendung.
 WS2812 braucht 10us pro Byte. Die SPI rumschieberei dauert auch nicht
 viel weniger, da geht deine geniale Lösung schon flöten. Und die
 ständige rumhopserei zur ISR und wieder zurück lassen wir mal vorerst
 beiseite.

c-hater schrieb:
> Vielleicht lernst du endlich mal programmieren?

 Tja, genau dasselbe wollte ich dir vorschlagen...

: Bearbeitet durch User
Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c-hater schrieb:
> Und das Schreiben so eines Treibers ist nicht ganz trivial, das wäre
> auch für mich richtig Arbeit.
 Ja, ohne Ende.

 Du willst es nicht kapieren oder bist nicht dazu imstande ?
 Man kann nicht mehr als 2 bits für WS2812 in einen SPI-Byte
 packen, es sind also 4 SPI-Bytes pro RGB-Byt notwendig.
 Mal angenommen, dein Byte wird mit 4 SPI-Aufrüfen gesendet.
 Ohne DMA gibt es nur 1 Möglichkeit:

ISR wird nach jedem Byte angesprungen:
==============================
 ISR Aufruf             =  3Cy
 8 Register PUSH        =  8Cy  //* Laden der Indexregister sei dir geschenkt
 Schieberei und send    =  9Cy  //* Ungefähr (dec, cp, branch, ld, shift, out...)
 8 Register POP         =  8Cy  //* Selbst mit nur 4 Registern sind es 14us
 ISR reti               =  4Cy
==============================
 Gesamt                 = 32Cy
 32Cy * 4 Aufrufe       = 128Cy = 16us bei 8MHz.
 Anstatt 9-10us bei Bitbanging.

 Dann gibt es noch die Möglichkeit, dass du alle RGB-Bytes
 vorher schon als SPI-Bytes vorbereitet hast, dafür braucht man
 aber 4 Mal so viel RAM (alle LEDs) - oder für jede LED bzw. für
 RGB-Byt wird eine Berechnung durchgeführt, was aber wiederum keinerlei
 Vorteile bezüglich der Zeit bringt.
 Nehmen wir aber an, dass du trotzdem irgendwie den ganzen Kram ohne
 das vierfache an RAM zu brauchen, in einem Stück rausschickst.

 ISR muss aber nach jedem Byte angesprungen werden:
==============================
 ISR Aufruf             =  3Cy  //* Übernahme (Portzustand) sei dir geschenkt
 8 Register PUSH        =  8Cy  //* Laden der Indexregister sei dir auch geschenkt
 Send                   =  2Cy  //* deswegen nur ld und out SPDR
 8 Register POP         =  8Cy
 ISR reti               =  4Cy
==============================
 Gesamt                 = 25Cy
 25Cy * 4 Aufrufe       = 100Cy = 12,5us bei 8MHz.
 Anstatt 9-10us bei Bitbanging.
 Und die Vorbereitung aller Bytes im ersten Fall oder die
 Vorbereitung der 4 Bytes in zweitem Fall sei dir wieder
 geschenkt.

 Und wie du auf 45% der CPU-Zeit kommst, ist mir wirklich nicht klar,
 dir höchstwahrscheinlich auch nicht.

Autor: Mw En (Firma: fritzler-avr.de) (fritzler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warim gibts hier mimimi zum RAM Verbauch?
Davon hat der RasPI3 nun wirklich genug.

Also SPI per DMA ausm RAM und gut is.

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Es macht Sinn, mit dem Raspi die Bilddaten zu generieren und dann an ein 
kleines uC Board zu schicken, welches dann die WS2812 mit genauem Timing 
ansteuert.

Oder man kann ein LattePanda Board nehmen, das hat für solche Zwecke 
nebst der Fetten CPU noch einen Mikrocontroller integriert (ATMega32u4).
Ich meine irgendwo gelesen zu haben, dass man Ubuntu auf dem LattePanda 
zum laufen bekommt.
http://www.lattepanda.com/

: Bearbeitet durch User
Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Mw E. schrieb:
> Also SPI per DMA ausm RAM und gut is.

 Sage ich doch die ganze Zeit.
 Ohne DMA und genügend RAM ist das in jedem Fall absoluter Blödsinn.

 Mit DMA dagegen ist es wie mit den Missiles - "Fire-and-forget" -
 macht also durchaus Sinn...

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:
> Mw E. schrieb:
>> Also SPI per DMA ausm RAM und gut is.
>
>  Sage ich doch die ganze Zeit.
>  Ohne DMA und genügend RAM ist das in jedem Fall absoluter Blödsinn.
>
>  Mit DMA dagegen ist es wie mit den Missiles - "Fire-and-forget" -
>  macht also durchaus Sinn...

Ist es denn beim Raspi mit Raspbian garantiert, dass bei DMA-Betrieb 
absolut nie eine Wartezeit zwischen zwei Bytes auftreten kann?

Denn bei WS2812 ist das wirklich wirklich essentiell, dass das Timing 
über das gesamte "Datenpacket" stimmig ist. Ansonsten flackern dann 
einzelne oder mehrere LED's, was ziemlich schlimm aussieht.

Autor: Mw En (Firma: fritzler-avr.de) (fritzler)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Dafür hat das Teil eine 16Word FIFO und FIFO Triggerlevel ab dem ein DMA 
Request ausgelöst wird.
Sogar ein Panik Signal gibts.

Autor: Markus M. (adrock)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:

>  Du willst es nicht kapieren oder bist nicht dazu imstande ?
>  Man kann nicht mehr als 2 bits für WS2812 in einen SPI-Byte
>  packen, es sind also 4 SPI-Bytes pro RGB-Byt notwendig.

Das ist falsch. Bei geeignetem Takt benötigt man genau 3 SPI Bits für 
ein WS2812 Bit, also 1:3 Verhältnis.

Deine ganzen Berechnungen beziehen sich auf 8MHz Takt. Nehmen wir doch 
mal 16MHz oder 20MHz an. Dann schluckt Bit Banging immer noch 100% CPU, 
die ISR Version kann dann aber ihren Charme ausspielen, dass nämlich 
zwischendurch doch noch etwas im Hauptprogramm erledigt werden kann.

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus M. schrieb:
> Das ist falsch. Bei geeignetem Takt benötigt man genau 3 SPI Bits für
> ein WS2812 Bit, also 1:3 Verhältnis.

 Kann sein, nur muss man dann bei der Vorbereitung mit 2 Bytes
 gleichzeitig arbeiten, die ganze Schieberei braucht ganz schön Zeit.
 Die ISR braucht immer noch mindestens 32Cy * 3 Aufrüfe, ergibt 96Cy.

> Deine ganzen Berechnungen beziehen sich auf 8MHz Takt. Nehmen wir doch
> mal 16MHz oder 20MHz an. Dann schluckt Bit Banging immer noch 100% CPU,
> die ISR Version kann dann aber ihren Charme ausspielen, dass nämlich

 Ich war schon grosszügig bei der ISR berechnung, entweder übernahme
 des Portzustands oder ein ganzes Port wird für 1 bit gebraucht.
 Laden der Indexregister braucht auch eine gewisse Zeit, oder ?
 Und nur 8 Register zu retten genügt bestimmt nicht, dann ist da auch
 noch SREG...

 Also, um fair zu sein, müsste dein uC viel mehr Zeit in der ISR
 verbrauchen als von mir angegeben, vielleicht sogar das doppelte.

 10us (1 RGB-Byt oder 3 SPI-Bytes) sind bei 20MHz genau 200Cy.
 Wenn aber 150-190Cy in der ISR verbraucht werden, für die Vorbereitung
 noch mindestens 40-60Cy gebraucht werden, bleibt nicht mehr viel
 von angeblichem Charme übrig...

 Das ist und bleibt eine Milchmädchenrechnung von Leuten die keine
 Ahnung haben.

 Entweder SPI+DMA oder Bitbanging - alles andere ist Blödsinn.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:

>  Du willst es nicht kapieren oder bist nicht dazu imstande ?
>  Man kann nicht mehr als 2 bits für WS2812 in einen SPI-Byte
>  packen

Meine hier bereits gepostete (und wie gesagt: voll funktionsfähige) 
Lösung beweist schon bei dieser Behauptung das Gegenteil. Sie kommt 
nämlich mit drei SPI-Bits pro WS28xx-Datenbit aus. Wenn du mein Programm 
verstehen würdest, wäre dir das klar geworden, das ist ja schließlich 
für meine Verhältnisse ungewöhnlich ausführlich kommentiert.

Im übrigen ist auch der Rechenzeitverbrauch bereits im Quelltext voll 
dokumentiert, für jeden einsehbar und im Simulator Takt für Takt 
nachvollziehbar. Du kannst dich also im Kreise drehen, bis du rotglühend 
wirst, diese Fakten wirst du nicht wegdiskutieren können...

>  Und wie du auf 45% der CPU-Zeit kommst, ist mir wirklich nicht klar,
>  dir höchstwahrscheinlich auch nicht.

Doch, natürlich. Wie schon gesagt: das Zeitverhalten ist taktgenau im 
Quelltext dokumentiert. ICH weiss ganz genau, was ich tue.

> Und die
> ständige rumhopserei zur ISR und wieder zurück lassen wir mal vorerst
> beiseite.

Die gerade ist aber der eigentlich Trick meiner Lösung, das hast du wohl 
auch nicht verstanden. Nur das erlaubt es nämlich, den Bitstream in 
Echtzeit zu encodieren und somit ohne den riesigen Mehrverbrauch an 
RAM auszukommen, den du zu apostrophieren beliebtest...

Der Trick ist einfach, dass durch die Interruptnutzung der relative 
zeitaufwendige Encodierungsprozess für den Bitstream in die rein zur 
Ausgabe benötigten Instanzen der ISR sozusagen reingeschachelt werden 
kann. Das geht durch eine sich selbst unterbrechende und hochoptimierte 
ISP-ISR.

Ich würde dir empfehlen, das Demo einfach mal so lange im Simulator 
laufen zu lassen, bis du das Prinzip verstanden hast. Zusätzlich darfst 
du auch gerne in main() (wo sonst eigentlich garnix passiert) eine 
kleine Routine einbauen, die einfach nur die dort verfügbaren Takte 
kumuliert und dich so von meinen Angaben überzeugen lassen, wenn du 
schon die Kommentare bezüglich des Rechenzeitverbrauchs nicht zu 
verstehen vermagst...

Natürlich wäre es dafür sinnvoll, in ws28xx_user nicht gerade den 
Democode zu verwenden, der ja einen (zumindest auf einem Tiny) 
erheblichen Teil der von der eigentlichen WS28xx-Ausgabe freigesetzten 
Rechenzeit gleich wieder für die Berechnung des Effektes in Echtzeit 
verwendet. Da gehört dann natürlich ein sehr viel simplerer Code hin, 
der z.B. ein einfaches Farbbalken-Testbild ausgibt oder aber noch 
einfacher: schlicht die RGB-Daten aus dem RAM liest. Damit kommt man 
dann wohl vielleicht in die Bereiche, die du zu begreifen und 
nachzuvollziehen vermagst...

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c-hater schrieb:
> Meine hier bereits gepostete (und wie gesagt: voll funktionsfähige)
> Lösung beweist schon bei dieser Behauptung das Gegenteil. Sie kommt
> nämlich mit drei SPI-Bits pro WS28xx-Datenbit aus. Wenn du mein Programm
> verstehen würdest, wäre dir das klar geworden, das ist ja schließlich
> für meine Verhältnisse ungewöhnlich ausführlich kommentiert.

 Wenn du irgendein Link posten kannst, werde ich wirklich versuchen
 deine Lösung zu verstehen.
 Vielleicht lerne ich etwas neues, wer weiss...

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc V. schrieb:

>  Wenn du irgendein Link posten kannst, werde ich wirklich versuchen
>  deine Lösung zu verstehen.

Das hast du ja offensichtlich schon damals nicht, denn in dem Thread 
hast du mitdiskutiert, wie ich gerade festgestellt habe.

>  Vielleicht lerne ich etwas neues, wer weiss...

Meiner Einschätzung nach: Eher nicht.

Aber für die, die wirklich was lernen wollen darüber, wie man aus 
kleinen µC das Optimum herausholt, hier doch noch der Link zum Artikel 
mit Originalcode und Video als Funktionsbeleg:

Beitrag "The secret of WS2812B"

Natürlich ist nur der mit FunctionDemo benannte Kram aus den Anhängen 
hier in diesem Zusammenhang relevant.

Was das eigentliche Thema des damaligen Threads betrifft, bin ich 
übrigens effektiv immer noch keinen Schritt weiter...

Autor: Marc Vesely (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
c-hater schrieb:
> kleinen µC das Optimum herausholt, hier doch noch der Link zum Artikel
> mit Originalcode und Video als Funktionsbeleg:
>
> Beitrag "The secret of WS2812B"

 LOL.
 Und du hältst immer noch an diesem Blödsinn fest ?
 Beitrag "Re: The secret of WS2812B"
 Beitrag "Re: The secret of WS2812B"

 Was deinen Code betrifft:

 Ein "Programm" zu schreiben, welches die Farben der 60 LEDs von
 RED nach GREEN und dann nach BLUE schiebt und sonst nichts macht
 als die genialste Erfindung des 21 Jahrhunderts vorzustellen, kann
 auch nur dir in den Sinn kommen.
 Die Leute hier reden von einem normalen Programm, da werden bei
 Einsprung in die ISR mindestens 10 Register gerettet + SREG +
 IndexRegister aus RAM laden + Ausgabe + Indexregister wieder in den
 RAM schreiben + jmp + reti.
 Mindestens 40Cy.
 Mal 3 ergibt 120Cy.
 Plus Vorbereitung mit mindestens 40-60Cy, ergibt 160-180Cy.
 Ausgabe dauert 10us oder 200Cy bei 20MHz.
 Das sind für mich dauernd 80-90% Auslastung bei der Ausgabe.

 Und das ist ohne die RGB-Bytes (Farbe) zu verändern, das schenke ich
 dir wieder, weil es sonst vielleicht über 200Cy dauert...

 Anstatt das Ganze in 1,8ms mit Bitbanging rauszujagen und dann kann
 die CPU eine Pause von 18,2ms machen (Framerate 50Hz).
 Ergibt eine effektive Auslastung von 10% bei deinen 60 LEDs.

 Und sollte zufällig bei dir in der "freien Zeit" ein anderer Interrupt
 feuern, z.B. Timer1 mit in etwa nötigen 100Cy in der ISR, sieht die
 Sache ganz anders aus.

 Wann kapierst du endlich, dass die Ausgabe über SPI ohne DMA
 absolut  keine Vorteile bringt ?

 Und mit DMA auch nur bei 3-fachem RAM.
 Was bei ARM und Raspberry kein Problem darstellt, da ist leider deine
 Genialität nicht nötig.

Autor: Mikro 77 (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe nun mal so einen LED Streifen testen können (auf Pi-0 und Pi-2). 
:-)

Joachim B. schrieb:
> Es gibt aber bei WS2812b LEDs keinen Clock, nach einer langen
> Bitschieberei muss das Timing für die Übernahme stimmen.

Mit Bit-Banging aus C heraus ist das in der Tat nicht einfach. Wenn man 
vor und nach jeder Flanke die Zeit nimmt und damit die min/max Timings 
hält/prüft, dann stellt man sehr häufig fest, dass die max Werte 
überschritten wurden (und ich meine nicht das Prozess Scheduling). Mit 
genügend Retries läuft es dann "irgendwann". Die Quote bessert sich mit 
Überziehen der Timings (die scheinen recht gutmütig zu sein). Aber bei 
einer "überschaubaren" Anzahl von LEDs ist das Ende der Fahnenstange 
erreicht.

> Ich wüsste im Moment nicht ob man das im SPI hinbekommt weil dazu auch
> immer SCK gehört, oder darf man den dann ignorieren?

Ja, kann man. Braucht man nicht mal frei zu schalten. Der SPI Serializer 
(SPIO) ist die zweitbeste Wahl. "Einfacher" geht es mit einem der PWM 
Serializer. SPI0 und PWM haben verhältnismäßig lange Queues und auch DMA 
Support.

Spannend, zum Ausprobieren, wären dann noch direkt DMA auf GPIO, SPI1 
Serializer (ohne DMA,kleine Queue) und BSC Slave Serializer (ohne 
DMA,kleine Queue,ext. Clock-Pulse).

Autor: Marco H. (damarco)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei der Ausgabe über PWM wird der Ballast noch größer.  Die Ausgabe per 
DMA über den GPIO funktioniert wenn der DMA die Möglichkeit besitzt 
diesen zu Takten.  Sonst müssen weitete zwischen bits gesetzt werden um 
die 800khz zu erreichen.  Beim Atmel geht das nicht bei ST offenbar 
schon.

Autor: Mikro 77 (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:
> Bei der Ausgabe über PWM wird der Ballast noch größer.

Größer als was? Im günstigsten Fall die oben beschriebenen 3Bit/Bit wie 
bei SPI.

> Die Ausgabe per
> DMA über den GPIO funktioniert wenn der DMA die Möglichkeit besitzt
> diesen zu Takten.  Sonst müssen weitete zwischen bits gesetzt werden um
> die 800khz zu erreichen.

Speicher ist genug da. DMA kann bspw. aber auch über Wartezyklen oder 
separate Controlblöcke ausgebremst werden. Die Herausforderung ist das 
fehlende Pacing.

Autor: Marco H. (damarco)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als bei SPI oder GPIO.

Beim SPI braucht man 4 Bit minimal 3 du musst ja sicher über/unter 50% 
Tastverhältnis kommen.

Beim PWM werden aus jeden Bit -> 8Bit den du in den Counter laden musst 
um das Tastverhältnis zu erzeugen.  Bei Unglücklichen 
Teilerverhältnissen bzw Clocks werden da auch schon mal 16 oder 32Bit 
daraus.

Beim SAM3x ist das leider dann auch so das du die Values für den Counter 
für die Channels hintereinander setzen musst wenn du diese per DMA in 
PWM Modul schiebst. Bsp. Channel0->Channel1->Channel2-> usw.

Das heißt du musst einen kompletten Frame zwischen speichern. Oder eine 
Art Ring Buffer bauen in dem du rechtzeitig den next Pointer dran hängst 
bevor der Transfer zu ende ist.

Beim ST gibt es wohl die Möglichkeit den Transfer über den Timer zu 
takten. Das ist natürlich dann ideal da du die Bits dann zum richtigen 
Zeitpunkt ausgeben kannst.

Das über PWM oder auch GPIO zu lösen nimmt man dann in Betracht wenn man 
viele WS2812 Channels benötigt. Beim SAM3x sind über den PWM Controller 
8 möglich entgegen per USART SPI nur 4 , beim Arduino DUE nur 3 da die 
eine USART nicht nach außen geführt ist.

: Bearbeitet durch User
Autor: Mikro 77 (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:

> Beim PWM werden aus jeden Bit -> 8Bit den du in den Counter laden musst
> um das Tastverhältnis zu erzeugen....

Aso... Ich glaube hier gibt es ein Missverständnis: Beim Pi ist die PWM 
Schnittstelle u.a. auch als (frei definierbarer) Serialisierer 
implementiert. Mit 500 MHz Clock Source und Teiler 200 kann man also 
bspw. 3 Bit Sequenzen für den WS2812B erzeugen.

> Das über PWM oder auch GPIO zu lösen nimmt man dann in Betracht wenn man
> viele WS2812 Channels benötigt. Beim SAM3x sind über den PWM Controller
> 8 möglich entgegen per USART SPI nur 4 , beim Arduino DUE nur 3 da die
> eine USART nicht nach außen geführt ist.

Beim Pi gibt es lediglich zwei PWM Kanäle (die auch noch geshared sind) 
und einen (full) SPI. Wenn man mehr als 3 WS2812B Ketten hat würde man 
wohl einen Dummy SPI/PWM Kanal definieren der das DMA Pacing 
bereitstellt und dann über DMA die notwendige Anzahl GPIO Pins direkt 
ansteuern.

Autor: Marco H. (damarco)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Über DMA kommt man auch beim Pi schon recht weit.  Selbst DMX ist so 
schon erzeugt worden.  Allerdings muss man aufpassen das niemand 
dazwischen funkt. Da ist System Kenntnis gefragt. So gesehen ist die 
Lösung mit abgesetzten Board und eigenen µP schon einfacher.  Die Daten 
für den Streifen kann man dann per SPI vom Pi übertragen. Da denkt man 
sich eben ein eignendes Protokoll aus und die SPI Geschwindigkeit vom Pi 
reicht alle male aus viele Pixel mit hoher Framerate zu übertragen.

Die noch bessere Lösung ist die Daten über Ethernet aus dem Pi zu 
übertragen. z.Bsp per Artnet.

: Bearbeitet durch User
Autor: dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi, es ist definitiv machbar das mit dem Tutorial und dem flackern hatte 
ich auch. es gibt einen unterschied zwischen pin Nummer auf der Leiste 
und Ausgang in der Software. 18 ist nicht gleich 18. finde den richtigen 
Ausgang und es tut ohne Probleme. ich verwende einen Level converter für 
3,3 und 5v

Autor: jk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn das Thema bis auf die Bitebene herunter schon durchdiskutiert 
worden ist: probier einfach mal die Anleitung auf
https://tutorials-raspberrypi.de/raspberry-pi-ws28...
aus; das hat bei mir auch funktioniert (allerdings mit kurzem Strip); 
sowohl beim ws2812b wie auch ws2801.
Was allerdings anzumerken ist und auch oben schon beschrieben: allzu 
viel sollte man den raspi dann nicht mehr mit anderen Aufgaben 
beaufschlagen, sonst klappt das mit dem Timing nicht. Wichtig ist auf 
jeden Fall, dass die Audioausgabe deaktiviert werden muss.
Für einen einfachen Test reicht das auf jeden Fall aus

Autor: Icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hui, hier brennt die Luft ;-)


Also... ich steuere 256 WS 2812 LEDs über Raspberry Pi 3 an. Und zwar 
mit SPI (8 Mhz). Und das funktioniert tadellos.

Keine Ahnung warum hier so viele Posten das es nicht oder schlecht geht. 
ich habe kein flackern, keine Sprünge oder dergleichen.

Vielleicht haben die meisten Probleme damit, weil sie die falsche 
Frequenz einstellen, und somit mit den Bits irgendwas kryptisches 
ausrechnen müssen, um auf die 800 Khz zu kommen. Doch mit 8 Mhz SPI 
Clock passt die 252 und 224 (1/0) perfekt in 24 Bits auf 3 GRB Bytes.

Da muss man nichts krumm rechnen.

Das sind 30 Zeilen Code mit Android.

Autor: Icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens, es funktionieren auch 512 LEDs ohne Probleme und ohne 
Geschwindigkeitseinbrüche (FPS bleibt gleich).

CPU Last = 9%  (neun)

Autor: Icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CPU Temperatur (ohne Kühler): 39°C

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.