testbericht zum WS2812

Eisebaer:
hi, uwe,

ich wußte nicht, ob's Dich interessiert, und ich muß da noch was dazu erklären.
erstmal:
Driving the WS2811 at 800 kHz with an 8 MHz AVR - Just in Time
hab die ws2811_8.h-datei in die libraries gelegt und in einem leeren sketch includiert.
fehlermeldung: no _delay_us declared in this scope oder so ähnlich. diese funktion hab ich in einer delay.h im arduino-verzeichnis gefunden (gibt 2). die delay.h ins sketch-verzeichnis gelegt und auch includiert (mit " -zeichen). jetzt läßt es sich kompilieren, aber wie gesagt, kein chip zur hand. außerdem muß ich mir noch ansehen, ob dieses struct CRGB dort genauso funkt wie in der fast_SPI.

gruß stefan

Heute (Nacht) interssiert es mich nicht mehr; nach dem Wochenende geren.
Grüße Uwe

Eisebaer:
jetzt wo ich's nochmal lese, uwe. ich meinte einen 8MHz chip verwenden, die ansteuerung muß natürlich gleich schnell bleiben.

gruß stefan

Da habe ich Dich wirklich falsch verstanden.

Ich weiß nicht wie kritisch der WS2811/12 auf Timingungenaugikeiten reagiert. Ein interner RC-Taktgenerator ist viel ungenauer als ein Resonator oder ein Quarz.

Grüße Uwe

uwe, Du treibst gerade Deine (natürlich immer noch lächerlich geringe) fehlerquote hoch. die 2812er laufen mit 800.

ich hab' mir jetzt 20 attiny85 bestellt, schlimmstenfalls nehm' ich sie als streusel für kekse.
bestenfalls verwende ich einen für meinen arbeitskollegen, dann bleiben mir immer noch 19 für die kekse. ich kann einfach nicht einen um 2€ kaufen, wenn ich 20 um 22€ krieg'. Ihr solltet mich mal im puff erleben...

gruß stefan

Eisebaer:
uwe, Du treibst gerade Deine (natürlich immer noch lächerlich geringe) fehlerquote hoch. die 2812er laufen mit 800.

auch wenn ichs so unbestimmt formuliere?

Ich glaube mich zu erinnern daß es 400kBaud sind.

Kann man den ATtiny85 wenns sein muß nicht auch mit externen 16 Mega Quarz betreiben?

Gute Nacht nach Wien.

Ist ganz klar mein Fehler, nicht Uwes!
Ich hätte ja dazuschreiben können, dass ich dein vage formulierten Einwand 800kbaud aus dem Datenblatt entnommen habe und mir daher eigentlich ziemlich sicher war ...

Liebe Grüße

Dirk

Hallo zusammen,

erstmal vorweg, vielen Dank für diesen hilfreichen Thread.
Habe mir ebenfalls 2m WS2812 Strips bestellt also 120 LEDs.

Will diese mit dem Arduino Due verbinden. Hab dazu schon extrem viele Seiten gelesen, Interesannt ist für mich das Thema ob ich nicht mehrere Pins für verschiedene Strips verwenden kann.
Für mein Projekt "Wohnzimmerbeleuchtung" brauch ich über 40m Strips. Was dann folglich über 2400 LEDs sind.
Diese an einem Pin zu betreiben erscheint mir ein Ding der Unmöglichkeit. Da ich mit dem Due eine höhere Taktrate habe, müsste ich die Strips doch bei 800kHz auf mehreren Pins parallel betreiben können, oder sehe ich das falsch?

Ich bin ein absoluter Anfänger in Sachen Mircocontroller. Und würde mich echt freuen, wenn Ihr mir bei dem Projekt unter die Arme greift.

Lieben Gruß

Til

hi,

kein problem, du mußt dann nur das:

         LD __tmp_reg__, %a[dataptr]+"	"\n" 
"            LSL __tmp_reg__"	"\n"
"            LDI %[bits], 4"    "\n"
"            BRCC L13"	"\n"
"            RJMP L5"	"\n"
"    H1:     NOP"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            NOP"	"\n"
"            RJMP END"	"\n"
"    L1:     SUBI %[bits], 1"	"\n"
"            BREQ M2"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            LSL __tmp_reg__"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            BRCC L8"	"\n"
"            NOP"	"\n"
"    L15:    NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            RJMP L9"	"\n"
"    M4:     LDI %[bits], 4"	"\n"
"            LD __tmp_reg__, %a[dataptr]+"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            SUBI %[bytes], 1"	"\n"
"            BREQ H1"	"\n"
"            LSL __tmp_reg__"	"\n"
"            BRCS L9"	"\n"
"            NOP"	"\n"
"    L16:    OUT %[portout], %[downreg]"	"\n"
"            NOP"	"\n"
"    L13:    OUT %[portout], %[upreg]"	"\n"
"            LSL __tmp_reg__"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            BRCC L10"	"\n"
"            SUBI %[bits], 1"	"\n"
"            BREQ M4"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            LSL __tmp_reg__"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            BRCS L15"	"\n"
"            NOP"	"\n"
"    L8:     NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            RJMP L16"	"\n"
"    M2:     LDI %[bits], 4"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            LD __tmp_reg__, %a[dataptr]+"	"\n"
"            SUBI %[bytes], 1"	"\n"
"            BREQ H1"	"\n"
"            LSL __tmp_reg__"	"\n"
"            BRCC L16"	"\n"
"            NOP"	"\n"
"    L9:     OUT %[portout], %[downreg]"	"\n"
"            NOP"	"\n"
"    L5:     OUT %[portout], %[upreg]"	"\n"
"            LSL __tmp_reg__"	"\n"
"            BRCS L1"	"\n"
"            SUBI %[bits], 1"	"\n"
"            BREQ M1"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            LSL __tmp_reg__"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            BRCC L4"	"\n"
"            NOP"	"\n"
"    L12:    NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            RJMP L5"	"\n"
"    M3:     LD __tmp_reg__, %a[dataptr]+"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            LDI %[bits], 4"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            SUBI %[bytes], 1"	"\n"
"            BREQ H2"	"\n"
"            LSL __tmp_reg__"	"\n"
"            BRCC L16"	"\n"
"            NOP"	"\n"
"            RJMP L5"	"\n"
"    L10:    SUBI %[bits], 1"	"\n"
"            BREQ M3"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            LSL __tmp_reg__"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            BRCS L12"	"\n"
"            NOP"	"\n"
"    L4:     NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            RJMP L13"	"\n"
"    M1:     LD __tmp_reg__, %a[dataptr]+"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            LDI %[bits], 4"	"\n"
"            OUT %[portout], %[upreg]"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"
"            SUBI %[bytes], 1"	"\n"
"            BREQ H2"	"\n"
"            LSL __tmp_reg__"	"\n"
"            BRCS L9"	"\n"
"            NOP"	"\n"
"            RJMP L13"	"\n"
"    H2:     NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"            NOP"	"\n"
"    END:    NOP"	"\n"

so umschreiben, daß es zur taktfrequenz des DUE paßt, und dann natürlich auch noch an die anzahl der verwendeten strips anpassen.
was ich damit sagen will:
das ist KEINE sache, die Du mit einem sketch lösen kannst, und Du wirst hier im (deutschsprachigen) forum niemanden finden, der das kann. nimm Dir zwei UNOs, lass die beiden miteinander reden und zwei streifen steuern. einer davon ist der "master". dann nimm den anderen, den "slave", aus dem UNO raus, steckst ihn auf ein breadboard, und einen neuen ATMega328 mit bootloader um 3€ in den sockel des uno. dann kannst Du drei miteinander reden lassen. wenn Du dann, sagen wir mal, fünf hast, bist Du fertig. fünf chips, die zusammen 2400 rgbLEDs steuern können. anders wirst Du das nicht lösen können.

gruß stefan

AgentTil:
Hallo zusammen,

erstmal vorweg, vielen Dank für diesen hilfreichen Thread.
Habe mir ebenfalls 2m WS2812 Strips bestellt also 120 LEDs.

Will diese mit dem Arduino Due verbinden. Hab dazu schon extrem viele Seiten gelesen, Interesannt ist für mich das Thema ob ich nicht mehrere Pins für verschiedene Strips verwenden kann.
Für mein Projekt "Wohnzimmerbeleuchtung" brauch ich über 40m Strips. Was dann folglich über 2400 LEDs sind.
Diese an einem Pin zu betreiben erscheint mir ein Ding der Unmöglichkeit. Da ich mit dem Due eine höhere Taktrate habe, müsste ich die Strips doch bei 800kHz auf mehreren Pins parallel betreiben können, oder sehe ich das falsch?

Ich bin ein absoluter Anfänger in Sachen Mircocontroller. Und würde mich echt freuen, wenn Ihr mir bei dem Projekt unter die Arme greift.

Lieben Gruß

Til

Ich glaube nicht, daß die Bibliothek zur Ansteuerung des WS2812 mit dem Arduino DUE funktioniert.
Du mußt Dir wahrscheinlich eine Ansteuerung selbst schreiben. Auf alle Fälle mußt Du den 3,3V Ausgang des DUE auf 5V bringen.

Die Max mögliche Länge des Strips hängt einzig von der gewollten Wiederholrate ab. Bei 30 neuen Daten pro Sekunde sind ca 1000 LEDs möglich. Wenn Du 2400 in einem Strang verwendest dann kannst Du ca alle 80mSec neue Daten auf die Strips schreiben. Bei einer Wohnzimmerbeleuchtung ist ein dynamische Lichtgestaltung mit schnellen Wechseln eigentlich nicht erforderlich.

Du weißt schon, daß 2400 Stück WS2812 144A brauchen und das bei 5V 720W sind wenn alle LED weiß leuchten. Es sind natürlich weniger wenn nur ein Teil oder nur bestimmte Farben leuchten.
Dir ist schon bewußt, das das eine Stadion-Tageslicht-Beleuchtung in Deinem Wohnzimmer wird?

Grüße Uwe

hi,

naja, til hat geschrieben, daß er schon viel zu dem thema gelesen hat, also ist ihm hoffentlich klar, daß er auch 10.000 WS2812 mit einem uno steuern kann. wenn er also meint, 2400 nicht mit einem zu schaffen, will er wohl verläufe regeln, und das wird mit nur einem uno nicht flüssig laufen.
til, ich hab' hier eine biblothek, die bis zu acht pins ansteuern kann, aber Du machst einen denkfehler: das timing bein WS2811 ist so eng, daß das rausschicken der befehle "in einem rutsch" erfolgen muß. also erst alles, was dieser braucht, an den ersten pin, dann wird der zweite pin abgearbeitet usw..
also der gleiche effekt, als ob Du gleich alles in einem rausschreibst.
der DUE ist etwa fünfmal so schnell, also schickt er die daten fünfmal so schnell, und das versteht der WS2811 nicht, der muß die daten fast mikrosekundengenau kriegen. also eine library für einen DUE suchen, oder eine für den raspberry.

gruß stefan

Hi,

hat von Euch jemand schonmal mehr als 1m eine Weile weiß leuchten lassen?
Wieviele Meter lassen sich ohne Spannungseinspeisung "unterwegs" am Stück betreiben?

hi,

hab ich noch nicht probiert, und momentan keinen uno zur hand. um das berechnen zu können, müßte man die stärke der leiterbahn kennen.

gruß stefan

Hi,

Danke für die Tipps. Arduino Due hab ich schon lange bestellt.

Irgendwo hab ich auch gelesen, dass die Signalspannung beim ersten LED auch 3.3V betragen kann, die Strecke zwischen den DUE und dem ersten LED darf wohl nur nicht zu lang sein. Ansonsten kommt halt n Pegelwandler rein.

Hab euch mal n Bild von dem Wohnzimmer angehangen.

Ist warscheinlich nicht nötig alle LEDs gleichzeitig mit weiss zu beschalten. Sondern dann halt nur jedes zweite oder dritte.
Allerdings strahlen die LEDs nach oben. Und das Licht kommt nur aus einem 4-6cm großem Spalt.

Die Bildrate für Farbübergänge sind nicht sooo wichtig, natürlich will ich einen flüssigen farbverlauf sehen.

Meint ihr es könnte klappen die 40m an einen Strang zu bauen?

Ein typisches Anwendungsbeispiel in meinem Wohnzimmer wäre abends zum Beispiel:

  • Leinwand unten, Licht in Abschnitt III wird nicht gebraucht
  • Abschnitt II leuchtet weiß (jede 5. LED)
  • Abschnitt I leuchtet weiß (jede 3. LED)

Meine Frau will dann was lesen, dann muss Abschnitt I heller werden, da hier die Couch steht. also Leuchtet jede 2. LED.

Beispiel 2:
ein Farbwechsel soll von Abschnitt I über die Mitte in Abschnitt II bis in Abschnitt III laufen. Also von Links nach Rechts.

Lichtprogramm technisch mach ich mir dazu weniger gedanken, das bekomm ich hin. Nur die Ansteuerung der LEDs, wie am sinnigsten, das macht mir gedanken.

Die Ansteuerung über 3 unterschiedliche PINs würde mir hier am logischsten erscheinen.

Gruß

Til

hi,

Die Bildrate für Farbübergänge sind nicht sooo wichtig, natürlich will ich einen flüssigen farbverlauf sehen.

diese beiden aussagen widersprechen sich. mit 2400 WS2812 kannst Du die werte nur 12mal in einer sekunde ändern. wenn Du jetzt also zb fließend von rot auf blau ändern willst, wird das deutlich "ruckeln".

flüssig wird das erst ab drei UNOS, aber ist dann unter umständen nicht trivial. ein lauflicht, das von einem bereich in den nächsten übergeht, muß überlegt programmiert werden. wenn so etwas nicht nötig ist, ist es leicht.

gruß stefan

hi,

was sind wir doch für deppen.
keiner denkt an den speicherbedarf. pro LED 3 byte. das wird ein uno nicht schaffen, auch drei nicht.
ein ATmega1284 müßte gehen. 5€.

gruß stefan

es scheint als habe ich das Loesungsproblem gefunden.
schaut mal hier:
http://www.pjrc.com/teensy/td_libs_OctoWS2811.html

bis zu 8 Strips an einem Teensy 3.0. Der Due hat ebenfalls DMA. Könnte ich das evtl. portieren?

Gruß

Til

ja, das hab' ich auch gefunden, wie ich ws2811 und raspberry gesucht habe. eine schöne lösung, und mit der arduino IDE zu programmieren. am günstigsten hab' ich's hier gefunden:

http://www.ebay.de/itm/Teensy-3-0-USB-Entwicklungs-Board-32bit-ARM-Cortex-M4-MK20DX128VLH-Original-PJRC-/261116450779?pt=Wissenschaftliche_Geräte&hash=item3ccbc0d7db

auf dem DUE kann diese library nicht laufen.

gruß stefan

Ich hab noch immer keine WS bestellt :frowning:

Aber: die Bibliothek kann doch Ports initialisieren, hat das jetzt schon mal jemand getestet?

  FastSPI_LED.setPin(PIN);
    FastSPI_LED.init();
  FastSPI_LED.start();

initialisiert das Ganze, also kann der PIN übergeben werden
Was passiert, wenn man im Sketch mit

FatsSPI_LED.stop();

das ganze beendet und auf einem anderen Port neu initialisiert??

Eventuell noch mit verschiedenen Längen diese anpassen (FastSPI_LED.setLeds).

Das einzige Problem könnte die Verzögerung sein, die dann zwischen den Strängen entsteht, aber ist das ein Problem?

Und @Til: Wenn du deine Beleuchtung zonenabhängig machst, willst du dann die LED einzeln ansprechen können? Ansonsten könnte man ja auch Stränge parallel betreiben?

Dirk

Hi, das ist glaub ich auch ne Idee.
Kannst du abschätzen wie lange die Umschaltzeit ist?
Die LEDs sollen natürlich einzeln steuerbar sein.
parallel wird wohl nicht klappen, wie soll denn dann ein farbwechsel laufen?

Aber nochmal ne Frage, warum soll man OctoWS2811 nicht auf den DUE portieren können? der DUE kann doch ebenfalls DMA.

Til

Eisebaer:
diese beiden aussagen widersprechen sich. mit 2400 WS2812 kannst Du die werte nur 12mal in einer sekunde ändern. wenn Du jetzt also zb fließend von rot auf blau ändern willst, wird das deutlich "ruckeln".

Wieso sollte das denn Ruckeln? Am Ende ist doch die Zeit für den Farbverlauf entscheidend. Der größte "Abstand" bei einer Grundfarbe sind 256 Schritte (von 0 auf 255), das wäre dann in 21,3 Sekunden zu machen. Bei einer immer noch vertretbaren Schrittweite von 2 kommt man schon auf knapp 10 Sekunden.
Problematisch wird es also erst bei sehr schnellen Farbwechseln, die nicht "springen" sollen.

Der Hinweis mit dem Speicher ist allerdings gut.

hi,

Du hast noch nicht verstanden, wie die WS2811 arbeiten.

man schickt bits an die chips, und zwar in dieser form:
entweder
0,25 mikrosekunden strom ein,
1 mikrosekunde strom aus, das heißt 0.
oder
0,6 mikrosekunden strom ein,
0,65 mikrosekunden strom aus, das heißt 1 (toleranz 150 nanosekunden).

und das muß in Deinem fall ohne pause in einem rutsch für alle 24003 leds passieren. daher auch die berechnung der zeit, die man braucht, um einen streifen mit 2400 rbgLEDs zu beschreiben:
2400
3 * 8Bit * 1,25 mikrosekunden = 72.000 mikrosekunden, also 13,8mal pro sekunde
der arduino läuft mit 16 millionen takten pro sekunde, er muß also alle paar takte den strom ein- oder ausschalten. und mittendrin auch noch die richtigen bits an die richtige stelle weiterschieben. das geht nur, wenn man direkt mit diesen takten arbeitet, und das ist der code, den ich oben reingeschrieben hab.

"            LDI %[bits], 4"    "\n"
"            BRCC L13"	"\n"
"            RJMP L5"	"\n"
"    H1:   NOP"	"\n"
"            NOP"	"\n"
"            OUT %[portout], %[downreg]"	"\n"

manche dieser assemblerbefehle brauchen einen takt, manche mehrere. NOP heißt, daß er einen takt nichts machen soll (sind also reserven da :P).
BRCC und RJMP sind sprungbefehle, mit OUT schreibt er wohl den inhalt eines prozessorregisters in einen bestimmten port(pin).
alleine wegen der unterschiedlichen taktgeschwindigkeit der beiden prozessoren kann man nicht einfach umschreiben. außerdem sind es zwar beides ARM-prozessoren, aber ob der assembler-befehlssatz gleich ist, ist auch nicht sicher.

gruß stefan