Forum: Mikrocontroller und Digitale Elektronik ATTINY85 o.ä. als I2C zu WS2812 Bridge


von rgbled-bastler (Gast)


Lesenswert?

Hallo zusammen,

ich habe mich in den letzten Monaten stärker mit dem Micropython-Board 
und ein paar anderen Boards beschäftigt. Dies als Erweiterung, um 8-12 
Jährige, die zuvor über Scratch und Python erste Programmiererfahrungen 
am PC gemacht haben, an die Programmierung von "Hardware" heranzuführen.
Hier soll einfach im Vordergrund stehen, dass mit wenigen Zeilen 
Programmcode Lämpchen leuchten, Servos sich bewegen, ....

Bitte hier keine Diskussion über das Für und Wider solcher Boards, der 
Programmiersprachen etc.  Dies diente nur der Einführung in das Thema 
meiner Frage.

Eine erste Sache, die günstig ist und viel Effekte ermöglicht, ist die 
Ansteuerung von WS2812LED. Die derzeitige Implementation auf dem PyBoard 
(STM32F405) sieht allerdings heftig aus: Hier wird SPI verwendet, das 
jedoch nicht auf die entsprechende Frequenz der WS2812 Strips 
heruntergeregelt werden kann.  Daher werden die Byte-Werte für die 
Farben dreifach hintereinandergesetzt, um die einzelnen Bits zu 
verdreifachen.

Statt 3Byte pro LED sind so nun 9 Byte im Puffer.  Wenn nun länger 
LED-Streifen mit vorbereiteten Mustern angesteuert werden sollen, ist 
dies ein erheblicher Speicherverbrauch.

Nun kam ich auf die Idee, ob hier nicht ein Attiny85 mit ins Spiel 
kommen kann, der das Umsetzen auf das WS2812-Protokoll übernimmt.

Dieser müsste (vermutlich per Bit-banging) per I2C vom PyBoard (oder 
auch Raspberry PI etc...) per I2C die RGB-Bitwerte gesendet bekommen und 
würde diese im korrekten Takt auf die WS2812-Kette schicken.
Per Clock-Stretching sollte er in der Lage sein, den Sender auf die 
korrekte Geschwindigkeit einzubremsen.

Stellt sich nun die Frage, ob der attiny85 bei 16MHz genügend Taktzyklen 
dafür freihat.  Bei 8MHz ist der ja komplett beschäftigt, ein in seinem 
Speicher vorliegendes Bit-Muster mit 800kHz auf den WS2812 String zu 
schicken.

Bei 16MHz stünden somit 10 weitere Zyklen pro bit zur Verfügung.

Kann die Idee hinhauen oder braucht man weitaus mehr Code für den 
I2C/TWI SlaveBetrieb?

Meiner gegenwärtigen Idee nach, wäre der Attiny (oder ein anderer 
günstiger µC) dann einfach so eine Art Treiber, der am Beginn der WS2812 
Kette sitzt, und vom Programmierer der Applikation dahinter als Blackbox 
wahrgenommen wird.

Damit könnten dan zahlreiche andere µC oder Kleincomputer, die kein 
entsprechendes BitBanging beherrschen (Interrupts, ..) dann doch ohne 
großen Aufwand und ohne große Verrenkungen WS2812 Ketten ansteuern.

Und ja:  Ich weiss, dass auch APA102 im Kommen sind, die sind aber 
derzeit noch etwa doppelt so teuer, wie die 2812er Ketten....

Danke schon mal für Weiterführende Tips

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Das mit einem Tiny85 als Umsetzer machen wir bei unserem WS2812 HAT [1] 
für den Raspberry Pi. Aufgrund der geringen RAM-Größe kann man aber 
nicht sehr viele LEDs ansteuern...
Bei einer neuen Revision werden wir auch auf einen Tiny841 [2] wechseln, 
da dieser eine Hardware I2C-Slave Schnittstelle hat.

[1] https://github.com/watterott/RPi-WS2812-HAT
[2] https://github.com/watterott/wattuino#wattuino-nanite-841

Gruß
Andreas

von rgbled-bastler (Gast)


Lesenswert?

Hallo,

das sollte doch von der RAM-Größe unabhängig sein.  Meiner Idee nach 
würden die Bits einfach durchlaufen:  per TWI rein, und per bitbanging 
wieder raus.
Per Clock Stretching wird der Master auf die korrekte Geschwindigkeit 
gedrosselt.

Wenn ich das jeweils erst in den Speicher des Attiny (oder was auch 
immer) lade und dann ausgebe, bremse ich die Ausgabe insbesondere für 
lange LED-Strings enorm ab.

Gruß


rgbled-bastler

von Frank K. (fchk)


Lesenswert?

Schau Dir mal diese AppNote an:

http://ww1.microchip.com/downloads/en/AppNotes/00001606A.pdf

Hier wird ein PIC16F1509 verwendet. Der hat konfigurierbare Logikblöcke 
(CLB), und damit und mit der SPI-Schnittstelle wird das Timing quasi 
hardwaremäßig erzeugt, was keine Rechenleistung braucht. Eine ziemlich 
geniale Lösung also. Es gibt noch andere PIC16 mit CLB - such Dir den 
passenden aus.

fchk

von rgbled-bastler (Gast)


Lesenswert?

Frank K. schrieb:
> Schau Dir mal diese AppNote an:
>
> http://ww1.microchip.com/downloads/en/AppNotes/00001606A.pdf
>
> Hier wird ein PIC16F1509 verwendet. Der hat konfigurierbare Logikblöcke
> (CLB), und damit und mit der SPI-Schnittstelle wird das Timing quasi
> hardwaremäßig erzeugt, was keine Rechenleistung braucht. Eine ziemlich
> geniale Lösung also. Es gibt noch andere PIC16 mit CLB - such Dir den
> passenden aus.
>
> fchk

OK, dies sieht nach einer netten Sache aus, wie der PIC nativ WS2812 
spricht. Also mit wenig CPU-Leistung den WS2812 füttert.
Jetzt brauche ich immer noch den Uplink und die Synchronisation.

D.h. ich will ja ein bestimmtes Bytemuster synchron auf die WS2812 
bringen, ohne dass dies zuvor komplett auf dem Treiber gespeichert wird.

Ich habe bislang leider noch gar nichts mit den PICs gemacht, auch wenn 
ich gelesen habe, dass diese sehr einfach zu programmieren seien.

Liese sich in Kombination mit der CLB-Ausgabe ein Ringpuffer für die zu 
sendenden Daten implementieren, der von einem Uplink I2C gefüttert wird?

D. h. der I2C Slave würde den Ringpuffer füllen, sobald dieser gefüllt 
ist, per Clock-Stretching den Sender bremsen.
Der Pic würde den Inhalt des Ringpuffers per CLB-maskiertem SPI auf den 
WS2812 schicken, dadurch im Ringpuffer Plaz schaffen, den der I2C-Client 
wirder füllt.

Sobald der Rinpuffer leer ist, hört das CLB_SPI Senden auf, und die 
Kette leuchtet.

???

von Peter D. (peda)


Lesenswert?

rgbled-bastler schrieb:
> Stellt sich nun die Frage, ob der attiny85 bei 16MHz genügend Taktzyklen
> dafür freihat.

Soweit ich das sehe, kann man beim WS2812 beliebig lange Pausen zwischen 
den Paketen lassen. Der ATtiny kann also sein I2C bequem nach einem 
Paket machen.
Überträgt er gerade ein Paket an den WS, kann er entweder SCL strecken 
oder mit NACK antworten.

von Joachim B. (jar)


Lesenswert?

rgbled-bastler schrieb:
> Bei 16MHz stünden somit 10 weitere Zyklen pro bit zur Verfügung.
>
> Kann die Idee hinhauen oder braucht man weitaus mehr Code für den
> I2C/TWI SlaveBetrieb?

verstehe ich nicht, warum nicht bit banging direkt aus dem

rgbled-bastler schrieb:
> (STM32F405)

benötigt nur 3 Byte pro LED

im Atmel brauchst du doch buffer entsprechend der LED Tiefe x 3
also 900 Byte bei 300 LEDs, da bietet sich eher ein atmega an mit mehr 
RAM, z.B. atmega1284p mit 16kB Ram für vieles mehr.

von rgbled-bastler (Gast)


Lesenswert?

Peter D. schrieb:
> Soweit ich das sehe, kann man beim WS2812 beliebig lange Pausen zwischen
> den Paketen lassen. Der ATtiny kann also sein I2C bequem nach einem
> Paket machen.
> Überträgt er gerade ein Paket an den WS, kann er entweder SCL strecken
> oder mit NACK antworten.

Hmm, nach allem, was ich ausprobiert habe, und was auch hier steht:
http://www.mikrocontroller.net/articles/WS2812_Ansteuerung
wird eine Pause länger als 50µs als Reset erkannt, und führt dazu, dass 
die LED den gegenwärtigen Speicherinhalt anzeigen.

Wenn es hier einen Trick gäbe, eine Pause zu machen, die nicht als Reset 
interpretiert wird, wären alle Probleme gelöst.

von Peter D. (peda)


Lesenswert?

rgbled-bastler schrieb:
> wird eine Pause länger als 50µs als Reset erkannt, und führt dazu, dass
> die LED den gegenwärtigen Speicherinhalt anzeigen.

Ich dachte, das sollen sie auch.
Warum sonst schickt man was an den WS?

von rgbled-bastler (Gast)


Lesenswert?

Joachim B. schrieb:
> verstehe ich nicht, warum nicht bit banging direkt aus dem STM32F405
>
> benötigt nur 3 Byte pro LED
>

Weil ich z.B. auf dem pyBoard keinen direkten Zugriff auf Bitbanging 
habe.
Es gibt zwar rudimentäre Inline-Assembler-Möglichkeiten, ich müsste aber 
z.B. Interrupts abschalten, was andere Bibliotheken für so lange Zeit 
gar nicht gerne sehen.

Die Lösung wäre zudem auch wieder nicht so universell, wie das, was ich 
mir vorstelle. Ich mag ja wegen meiner geringen Erfahrung im µC Bereich 
hier zu naiv sein, aber ich stelle mir halt immer noch ein Modul vor, 
dass per I2C mit einer Geschwindigkeit > 800kHz angesprochen wird, und 
das per Clock-Stretching auf 800kHz eingepegelt wird.

> im Atmel brauchst du doch buffer entsprechend der LED Tiefe x 3
> also 900 Byte bei 300 LEDs, da bietet sich eher ein atmega an mit mehr
> RAM, z.B. atmega1284p mit 16kB Ram für vieles mehr.

Dann brauche ich eben auch keinen Puffer im Atmel, den ich auch nicht 
haben will. Sondern die bytes laufen einfach durch, per I2C rein und per 
WS2812 raus.  Der Baustein in  der Mitte (ob nun Atmel oder Pic oder 
...) sorgt einfach durch Clock-Stretching dafür, dass die WS2812 nicht 
überfahren werden.

Somit brauche ich auf dem eigentlichen Device nur eine Standard 
I2C-master Implementierung, die in der Lage ist mit mehr als 800kHz zu 
senden und die auf Clock-Stretchung reagiert.

Die LED Daten sind dann nur auf diesem Gerät im Puffer, der µC 
dazwischen ist nur ein Synchronisationsglied.

von rgbled-bastler (Gast)


Lesenswert?

Peter D. schrieb:
> Ich dachte, das sollen sie auch.
> Warum sonst schickt man was an den WS?

Ja natürlich, aber ich will ja nicht nur eine LED sondern 100 oder 200 
LED zum Leuchten bringen.

D.h. ich muss die Bytes für alle LEDs innerhalb der erlaubten 
Spezifikation ohne Pause raushauen. Sobald ich eine Pause mache, wird 
das angezeigt, was aktuell in den Puffern ist.

D.h. während ich der ersten LED die ersten drei Byte reintakte, sendet 
diese drei Null-Bytes an die Zweite, diese sendet drei Null-bytes an die 
Dritte usw.

Beim nächsten Triple sendet die erste LED die zuvor erhaltenen Daten an 
die Zweite, diese jedoch die zuvor erhaltenen Nullbytes an die 
Dritte....

Sobald nun eine Pause eintritt, wird angezeigt, was in den Puffern ist.

Wenn die Pause nach zwei bytes erfolgen würde, gibt es sogar ganz 
falsche Farben....

von Peter D. (peda)


Lesenswert?

rgbled-bastler schrieb:
> Sobald nun eine Pause eintritt, wird angezeigt, was in den Puffern ist.

Dann entlastet der ATtiny ja nicht sonderlich den Master, der muß dann 
weiterhin in Echtzeit senden.

Besser, der ATtiny puffert die I2C-Daten und schiebt sie komplett raus.
Bei 512Byte SRAM sind ~150 LEDs möglich.
Insbesondere kann dann der Master nur die Daten senden, die sich 
wirklich ändern.

von Joachim B. (jar)


Lesenswert?

Peter D. schrieb:
> Soweit ich das sehe, kann man beim WS2812 beliebig lange Pausen zwischen
> den Paketen lassen.

wo hast du das denn her?

rgbled-bastler schrieb:
> Sobald nun eine Pause eintritt, wird angezeigt, was in den Puffern ist.

Pause von 50µs

rgbled-bastler schrieb:
> Kann die Idee hinhauen oder braucht man weitaus mehr Code für den
> I2C/TWI SlaveBetrieb?

nö, I2C clock 100 bis 400 kHz, aber nicht als Avr Slave? und ein WS hat 
800kHz bremst schon mal aus und 3 Byte pro LED muss man am Atmel 
buffern, -> RAM

von rgbled-bastler (Gast)


Lesenswert?

Peter D. schrieb:
> rgbled-bastler schrieb:
>> Sobald nun eine Pause eintritt, wird angezeigt, was in den Puffern ist.
>
> Dann entlastet der ATtiny ja nicht sonderlich den Master, der muß dann
> weiterhin in Echtzeit senden.
>
> Besser, der ATtiny puffert die I2C-Daten und schiebt sie komplett raus.
> Bei 512Byte SRAM sind ~150 LEDs möglich.
> Insbesondere kann dann der Master nur die Daten senden, die sich
> wirklich ändern.

Der Attiny soll ja in erster Linie nicht den Master entlasten, sondern 
nur dafür sorgen, dass ich auf dem Master keine Klimmzüge machen muss.

Wenn der Attiny puffert, verdoppelt sich im besten Fall die 
Ausgabegeschwindigkeit, was für Spiele etc. schon nicht mehr so toll 
ist.

Das Ausgangsproblem ist, dass auf etlichen schnelleren Minicomputern und 
µC je nach Implementierung des dort laufenden Systems, ein einfaches 
Bitbanging etc. nicht mehr möglich ist.

Ich will hier nun von der Implementierung weg, dass ich das dreifache an 
RGB-Daten auf dem Master allozieren muss, da ich dort den Takt nicht 
langsam genug bekomme, um di eeinfach Datenmane rauszuschieben.

Das alleine dürfte schon eine Entlastung des Master sein.  Je nach dem, 
wie der Master sein I2C implementiert, läuft das vermutlich ohnehin dann 
parallel zu den anderen dort laufenden Tasks.

von rgbled-bastler (Gast)


Lesenswert?

Joachim B. schrieb:
> nö, I2C clock 100 bis 400 kHz, aber nicht als Avr Slave? und ein WS hat
> 800kHz bremst schon mal aus und 3 Byte pro LED muss man am Atmel
> buffern, -> RAM

Klar, ich muss je nach Implementierung 1-3 Byte puffern. Aber immer nur 
die.
Weil ich ja das Senden weiterer Bytes per Clock-Stretching verhindere.

Das ich auf die 800kHz vom WS runtergehe, ist klar.  Das macht die 
derzeitige Implementation auch, allerdings dadurch, das das dreifache an 
Daten in einem dreifach höheren Takt gesendet wird ;-)

von Joachim B. (jar)


Lesenswert?

rgbled-bastler schrieb:
> Das ich auf die 800kHz vom WS runtergehe, ist klar.

offensichtlich nicht klar wenn du von I2C schreibst, ich kenne nur 
100kHz und 400kHz und selbst wenn I2C schneller gehen sollte, auf dem 
Atmel?

von Peter D. (peda)


Lesenswert?

15.3.6 Clock speed considerations
Maximum frequency for SCL and SCK is fCK / 2.

D.h. max 8MHz I2C.

von Frank K. (fchk)


Lesenswert?

rgbled-bastler schrieb:

> D. h. der I2C Slave würde den Ringpuffer füllen, sobald dieser gefüllt
> ist, per Clock-Stretching den Sender bremsen.
> Der Pic würde den Inhalt des Ringpuffers per CLB-maskiertem SPI auf den
> WS2812 schicken, dadurch im Ringpuffer Plaz schaffen, den der I2C-Client
> wirder füllt.

Dieser PIC hat nur eine MSSP-Einheit, die entweder SPI oder I2C machen 
kann. Diese wird bereits benutzt. Es bliebe der UART über. Wenn Du 
schnell genug bist und die Daten unter allen (!) möglichen 
Betriebszuständen schneller liefern kannst als der WS2812 sie braucht, 
dann ginge das. Du bräuchtest dann einen UART mit Hardware Handshake.

Wenn Du diese Echtzeitbedingung nicht garantieren kannst, brauchst Du 
einen Puffer am PIC. Ein 23K256 mit 32k RAM, vom PIC per Bit-Banging 
angesteuert, wäre die Lösung der Wahl.

Wenn Du die Kommunikation unbedingt per I2C machen musst, brauchst Du 
einen anderen PIC, mit zwei MSSP-Einheiten und CLB. Diese Bedingungen 
erfüllen die PIC16F18325/18345. Die CLBs sind hier ein wenig anders 
verschaltet, d.h. Du musst den Code anpassen und kannst ihn nicht 1:1 
übernehmen.

fchk

von Robin (Gast)


Lesenswert?

Ich würde 8 Bit Farben verwenden. Damit kann der i2c langsamer takten. 
-> 200 led buffer passt in den ram des tiny.

Und die Daten per spi an dir leds senden. Bei 3,2mhz spi Takt. Wären das 
"1000" für eine 0 und "1110" für eine 1. Und man hätte 0,3125:0,9375µs 
passt also.

Bleibt nützlich dir frage, wann gesendet wird. Und das hängt von der i2c 
Traktate ab. Den nur weil 8mhz möglich sind. Heißt das noch lange nicht, 
das es auch funktioniert.

von rgbled-bastler (Gast)


Lesenswert?

Robin schrieb:
> Und die Daten per spi an dir leds senden. Bei 3,2mhz spi Takt. Wären das
> "1000" für eine 0 und "1110" für eine 1. Und man hätte 0,3125:0,9375µs
> passt also.

Das ist ja gerade, was ich NICHT möchte, dass ich anstelle eines bits 
mehrere Bits senden muss, und so den Speicherverbrauch auf dem Master 
hochschraube.

Ich zitiere aus einer den Micropython Bibliotheken:
https://github.com/JanBednarik/micropython-ws2812/blob/master/ws2812.py
1
def update_buf(self, data, start=0):
2
        """
3
        Fill a part of the buffer with RGB data.
4
        Order of colors in buffer is changed from RGB to GRB because WS2812 LED
5
        has GRB order of colors. Each color is represented by 4 bytes in buffer
6
        (1 byte for each 2 bits).

Da wird genau das gemacht, und ich brauche noch dreimal mehr Speicher, 
als wenn ich nur die 8 bit pro Farbe verwende.

Hier werden nochmals 3 Byte pro Farbe, also 12 Byte pro LED zusätzlich 
im Puffer abgelegt, nur dass der Takt passt.

von rgbled-bastler (Gast)


Lesenswert?

Joachim B. schrieb:
> offensichtlich nicht klar wenn du von I2C schreibst, ich kenne nur
> 100kHz und 400kHz und selbst wenn I2C schneller gehen sollte, auf dem
> Atmel?

Der STM32 kann auch jeden Fall HighSpeed I2C, das ist 1MHz. Das wäre die 
gewählte Geschwindigkeit, die dann durch Clock-Stretching auf 800kHz 
gesenkt würde.

von Joachim B. (jar)


Lesenswert?

rgbled-bastler schrieb:
> Der STM32 kann auch jeden Fall HighSpeed I2C, das ist 1MHz. Das wäre die
> gewählte Geschwindigkeit,

hast du deine Frage vergessen?

rgbled-bastler schrieb:
> Nun kam ich auf die Idee, ob hier nicht ein Attiny85 mit ins Spiel
> kommen kann, der das Umsetzen auf das WS2812-Protokoll übernimmt.

der tiny kann der 800kHz I2C?

wenn nicht wozu dann Clock Stretching? ich denke da war auch was mit 
Clockstrechting was am AVR nicht klappte wenn ich mich recht erinnere.

von Lothar (Gast)


Lesenswert?

Das ist doch DER Fall für den LPC810 DIP-8 ARM:

https://github.com/cpldcpu/light_ws2812

Der eingebaute SCT (State Machine Timer) schlägt den ganzen STM32F405 
locker (trotz M0 vs M4)

von Robin (Gast)


Lesenswert?

rgbled-bastler schrieb:
> Robin schrieb:
>> Und die Daten per spi an dir leds senden. Bei 3,2mhz spi Takt. Wären das
>> "1000" für eine 0 und "1110" für eine 1. Und man hätte 0,3125:0,9375µs
>> passt also.
>
> Das ist ja gerade, was ich NICHT möchte, dass ich anstelle eines bits
> mehrere Bits senden muss, und so den Speicherverbrauch auf dem Master
> hochschraube.

Eben nicht. Du kannst das ganze erst beim laden ins Senderegister 
umwandeln. Und da musst du nur einen von 4 möglichen werten laden. 
Abhängig davon, wie die nächsten 2 Bits aussehen.

von rgbled-bastler (Gast)


Lesenswert?

Robin schrieb:
> Eben nicht. Du kannst das ganze erst beim laden ins Senderegister
> umwandeln. Und da musst du nur einen von 4 möglichen werten laden.
> Abhängig davon, wie die nächsten 2 Bits aussehen.

Bekomme ich da dann nicht Probleme, die 800kHz zu halten, ohne Pausen > 
50µs einzulegen?  Wenn ich vor dem Senden einer 2bit_gruppe festlegen 
muss, welches Byte ich schicke?

von Robin (Gast)


Lesenswert?

Du hast 40 Takte um den Wert zu laden. Das sollte locker ausreichen und 
zur not kannst du ja auch etwas länger brauchen. Im wiki steht etwas von 
maximal 5µs, also maximal 120 Takte. Da kannst du idr. auch noch das I2C 
abarbeiten.

von Frank K. (fchk)


Lesenswert?

rgbled-bastler schrieb:
> Robin schrieb:
>> Und die Daten per spi an dir leds senden. Bei 3,2mhz spi Takt. Wären das
>> "1000" für eine 0 und "1110" für eine 1. Und man hätte 0,3125:0,9375µs
>> passt also.
>
> Das ist ja gerade, was ich NICHT möchte, dass ich anstelle eines bits
> mehrere Bits senden muss, und so den Speicherverbrauch auf dem Master
> hochschraube.

Ich denke, Du hast Dich ein wenig verrannt. Du bist auf I2C fixiert, das 
bei den erforderlichen Geschwindigkeiten spezielle Rahmenbedingungen 
braucht (lies mal die Infos über FM+ auf den NXP-Seiten, da sind die 1.7 
MHz und 3.4 MHz I2C-Modi beschrieben; und ja es gibt sie, aber die 
meisten Bausteine können sie nicht), und Du bist auf AVR fixiert.

Vergiss das mal alles komplett.

Schau Dir mal die Microchip-Lösung nochmal an. Und zwar genau. Und 
versuche, sie zu verstehen. Wenn Du verstanden hast, warum das dort 
funktioniert, sollte es für Dich kein Problem sein, das ganze mit etwas 
externer Logik nachzubauen. Du brauchst von irgendwo her einen Takt, der 
ein ganzes Vielfaches der WS2812 Bitrate ist, Du musst Deine 
SPI-Schnittstelle als Slave betreiben, damit SCLK ein Eingang ist, und 
die Logik, die bei Microchip in den CLBs realisiert wird, musst Du 
entweder mit einzelnen Gattern diskret aufbauen oder ein kleines CPLD 
dafür verwenden.

Wenn Du zu dieser Transferleistung fähig bist, bekommst Du ein System, 
das keine weiteren Puffer und Latenzen hat und trotzdem die WS2812 mit 
minimalem CPU-Aufwand (oder sogar per DMA) ansteuern kann.

fchk

von holger (Gast)


Lesenswert?

>Statt 3Byte pro LED sind so nun 9 Byte im Puffer.

Na und? Das sind immer noch 12000 LEDs die du ansteuern kannst.
Für unbenutztes RAM gibt es kein Geld zurück;)

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Hi rgbled-bastler,

Variante 1:
die Sourcen für das MicroPython sind doch offen bei github.
Was spricht dagegen, einen eigenen Treiber zu schreiben, der die 
WS2812-Daten per TIMER, ISR und DMA direkt auf einen GPIO schreibt?
Keine Hardwarekosten, nur ein bisserl ISR-Last, die das Mikropython 
sicher wegstecken kann.

Variante 1a:
das Ganze mit einer SPI Schnittstelle auf dem F405.

Variante 2:
Viele Microcontroller können die diese Protokoll-Umsetzung machen, auf 
einem kleinen Atmel ist das ggf. eine Assemblerübung. Da Du aber schon 
bei den STM32 bist - für eine ähnliche Aufgabe und weil mein Kunde keine 
Last im RTOS haben wollte, haben wir einen Protokollumsetzer mit 
STM32F030 unter GCC gemacht. Kostet sogar bei Farnell nur einen Euro.

Grüße,
 Marcus

: Bearbeitet durch User
von Thomas E. (picalic)


Lesenswert?

Marcus H. schrieb:
> Viele Microcontroller können die diese Protokoll-Umsetzung machen

Servus,

ich habe damit auch schon mal experimentiert und es auf einem PIC12F1840 
implementiert: http://www.picalic.de/PIC2WS2812/
Der schafft mit seinen läppischen 256 Bytes RAM eine Umsetzung von UART 
(1MBit/s) auf WS2812 rechnerisch für ca. 1500 LEDs, bis u.U. der Puffer 
überlaufen kann.

von Gerd B. (bertr2d2) Benutzerseite


Lesenswert?

Hier noch eine interessante Umsetzung auf AVR:
http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
Sehr lesenswert ...

von Max D. (max_d)


Lesenswert?

Selbst USB->WS2812 geht. Beitrag "µ-wire - USB auf ATtiny10" 
(nicht von mir)

von Moesl0r (Gast)


Lesenswert?

Der xmega32e5 hat ebenso die integrierte Logik Blöcke wie der pic und 
zusätzlich noch einen DMA, was eine WS2812 Ansteuerung mit sehr wenig 
CPU Last ermöglicht. In den 4kb RAM kann man also einen großen 
Framebuffer erstellen (eventuell mit double Buffering) und hier die 
Daten zwischenspeichern. Dadurch müssen die Daten vom PC nicht in 
Echtzeit geliefert werden, was er sowieso nicht kann.

von Moesl0r (Gast)


Lesenswert?

Hier noch ein Link zu einer Beschreibung zur Umsetzung am xmega 32e5: 
http://www.ejberg.dk/portfolio/ws2812-xcl/

von rgbled-bastler (Gast)


Lesenswert?

Mal vieln Dank für all die Hinweise, die hier zusammengekommen sind.
Ich muss das erstmal alles sortieren, werde mich wieder melden!

Danke!

von c-hater (Gast)


Lesenswert?

Joachim B. schrieb:
> Peter D. schrieb:
>> Soweit ich das sehe, kann man beim WS2812 beliebig lange Pausen zwischen
>> den Paketen lassen.
>
> wo hast du das denn her?

Das ergibt sich aus der Logik der Sache. Ein "Paket" = ein Frame = 
einmal Werte für alle LEDs am Bus. Die Pause löst für alle LEDs am Bus 
die Übernahme der empfangenen Daten aus. Die Mindestlänge einer dazu 
führenden Pause ist definiert. Aber natürlich kann man die Pause auch um 
so viel länger machen, wie man will. Das ändert rein garnix an der 
Funktion, sondern senkt nur die mögliche Framerate.

> 3 Byte pro LED muss man am Atmel
> buffern, -> RAM

Das ist das einzige echte Problem. Alles andere ist nur der 
Hilfeschrei eines C-"C&P"-Programmierers...

Ja klar, wenn die Source wesentlich langsamer ist als der Sink, dann 
kommt man natürlich nicht drum herum, alle Daten zu buffern. Und die 
leider immer im Vergleich zum Rest des Systems überaus knappe 
Ausstattung der AVR-µC mit SRAM setzt hier die Grenzen für das, was 
geht.

Schließlich will Atmel lieber die großen teuren Geschosse verkaufen, 
daran verdienen sie doch schließlich auch viel mehr, dafür muß man doch 
Verständnis haben...

Also ist die primäre Größe für dieses Problem die Größe des verfügbaren 
SRAM. Näherungsweise braucht man dessen Größe nur durch drei teilen und 
etwas abrunden, um die Zahl der durch einen AVR8 autark ansteuerbaren 
WS2812-Teile herauszubekommen.

Die große Ausnahme von dieser Regel ist: Parametrisch generierte 
Inhalte. Also gerade nicht der stupide Ansatz, die Inhalte jeder 
einzelnen verschissenen LED speichern und strunzdumm rauszukloppen, 
sondern sie statt dessen in Echtzeit berechnen. Ausreichend Zeit dafür 
ist für sehr viele Muster. Jedenfalls für Asm-Programmierer...

von Mark & Pfennig (Gast)


Lesenswert?

Vielleicht kann c-hater den von piedpiper.com entwickelten Algorithmus 
in die Maschinensprache des 85ers portieren? Wäre doch mal ein würdiger 
Job für einen echten Programmierer wie ihn.

von Alfred S. (hood)


Lesenswert?

das müsste es sein, was du suchst:

"picopixel" <- basiert auf "light_ws2812".

https://github.com/usedbytes/neopixel_i2c
This is an AVR-based neopixel driver. It accepts commands over i2c to 
drive a a number of ws2812 LED pixels. Talks i2c on one side, and 
neopixel 1-wire on the other.

Optional/removable i2c level shifter, for 5V LED drive and 3v3 i2c bus.
The actual neopixel driving is done by a slightly modified copy of 
[cpldcpu]'s light_ws2812 library

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
Noch kein Account? Hier anmelden.