Hallo, ich versuche aktuell ein System auszuarbeiten für das drahtlose Ansteuern von WS2812b RGB Stripes auf Basis eines nRF24L01. Die Idee dahinter ist mit Hilfe eines potenten Masters (Raspi & Co.) mehrere Slaves innerhalb eines Raums über eine auf den nRFs basierenden Funkstrecke mit einem RGB Datenstrom zu versorgen. Aus Kostengründen steht den Slaves max. eine Cortex-M0 MCU zur verfügung ala. STM32F1 (~1€) oder wenn nötig eine M3 ala LPC1343 (~2€). Dabei würde es sich ja anbieten gleich ein Datenkompression zu implementieren. Die Komprimierung darf auch gerne etwas CPU-Zeit auf dem Master beanspruchen. Die Dekompression dürfte jedoch nicht all zu viele CPU-Cycles beanspruchen um aus den komprimierten Daten ein Byte-Array aufzubauen welches dann zur Generierung des Ws2812 Signals genutzt werden soll. Hinzu kommt noch die Beschränkung der MCUs auf 8KB Ram wovon ein großer Teil für das Byte-Array zur Verfügung stehen sollte um möglichst viele LEDs über einen Slave ansteuern zu können. Nun stell sich die Frage wie solch eine Kompression aussehen sollte um stets so wenig Bytes übertragen zu müssen wie es nur geht und ohne dabei die Slave MCUs mit der Dekompression zu überfordern. Jemand eine Idee?
Es kommt auf die zu übertragenden Daten an, ob sich Kompression überhaupt lohnt. Wenn sie eher zufällig bzw. gleichverteilt sind, wird die Kompressionsrate gegen null gehen und man spart rein gar nichts. Wenn hingegen einzelne Zeichen sehr häufig auftreten und andere sehr selten, dann bringt es möglicherweise etwas. Eine Huffman-Kodierung wäre ein recht einfaches Verfahren, das auch nicht schwer zu implementieren ist. Dabei werden für oft vorkommende Zeichen weniger Bits verwendet, dafür braucht man für seltenere Zeichen mehr. Programmierbeispiele gibts mit Sicherheit im Netz irgendwo...
Ansonsten RLE oder LZW (was auch in zB GIF verwendet wird). Der letzter komprimiert besser, braucht aber etwas mehr Rechenleistung und RAM beim Dekomprimieren. http://en.wikipedia.org/wiki/Run-length_encoding http://en.wikipedia.org/wiki/Lempel-Ziv-Welch
Danke euch beiden für den Input. Bin selber noch auf miniLZO gestoßen was sich uU. auch eignen könnte. Ich merke schon - das ist nicht so einfach einen passenden Kompressionsalgo zu finden um den Anforderungen gerecht zu werden bzw. es stellt sich die Frage, wie Pedro schon angemerkt hat, ob eine Kompression überhaupt Sinn macht. Man stelle sich einen RGB Stripe vor mit 1000 LEDs von denen jede in einem anderen Farbton leuchtet. Die bisher genannten Kompressionsverfahren würden idF. versagen. Für einfache Muster und Lauflichter wären diese zwar bestens geeignet, für komplexe/zufällige Farbverläufe jedoch wieder unbrauchbar. Was jetzt die Slave MCU angeht, so habe ich bei aliexpress für ~1,50€ den STM32F103C8T6 gefunden. Mit bis zu 72MHz, 64KB Flash und satten 20KB SRAM wäre da einiges drin. Trotzdem muss ich nun mein Vorhaben nochmal überdenken. Ziel des Projekts ist es mit möglichst günstiger Hardware (idF. nRF24L01 + Cortex M0/M3 MCU) ein Alternative zu DMX und Co. zu entwickel zur drahtlosen Ansteuerung von RGB Lichtquellen und zwar möglichst vielen gleichzeitig (WS281x Stripes) mit einer Framerate von min. 25 o. 30 fps. Dabei gibt es zwei Möglichkeiten: 1. RGB Stream Das dürfte die unkompliziertere Implementierung sein und zugleich leicht erweiterbar da nur der Master sich um die Erzeugung des RGB Musters kümmern muss. Die Daten lassen sich wie bereits festgestell nur bedingt komprimieren. Hier wäre sogar eine adaptive Kompression angebracht die je nach Effekt/Muster Huffman, RLE oder LZW/LZO nutzt. Bei komplexeren Effekten/Mustern müsste man die Kompression deaktiviert lassen wodurch sich die mögliche Anzahl der anzusteuernden LEDs nicht erhöht und dieser Umstand die Kompression idF. damit generell in Frage stellt. Ich habe ausgerechnet, dass mit der nRF lib von TMRh20 ohne ACK es theoretisch möglich wäre bei 30fps ~2000 RGB LEDs anzusteuern. Das wäre schon mal mehr als das 10fache was mit einem DMX Universe möglich wäre und ohne der vergleichweise teuren Hardware und Kabelage. 2. Effekt-Lib auf jeder Slave-MCU vom Master aus getriggert Dabei ensteht aber gleich das Problem, dass die Slaves untereinander Synchronisiert sein müssten. Das sollte aber mit einer Genauigkeit von <5mS möglich sein was auch schon ausreichend wäre. Das System wäre schwiriger zu Pflegen da mit jeder Erweiterung auch die Slaves neu geflasht werden müssten. Zudem beschränk das System prinzipbedingt die gestalterischen Möglichkeiten was nur teilweise mit einem vergleichsweise hohen Programmieraufwand zu kompensieren wäre. Was aber wiederum ein großer Vorteil wäre, wäre die fast belibig hohe Anzahl an ansteuerbaren LEDs. Schätze beides zu implementieren und stattdessen beim Stream auf die Kompression zu verzichten wäre wohl am besten. Eine OTA Updatefunktion für die Effekte würde das ganze auch etwas pflegeleichter machen. Glaube das mutiert langsam zu einem Mammutprojekt. Hat evtl. jeman noch Input zu dem Vorhaben, auch wenn es jetzt OT wird? Gruss tec
Wie sehen denn die übertragenden Werte aus? sind die rohen PWM-Werte? Ansonsten spart es schon enorm, die Umrechnung Farbwert->PWM-Wert (wegen Linearisierung Helligkeit) auf dem Controller zu machen und die kleineren Werte zu übertragen.
@Vlad Tepesch Die WS281X RGB Controller werden mit RGB Daten gefüttert (3x8Bit). Die PWM wird auch von diesen Controllern übernommen. Siehe dazu https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/ Um die zu übertragene Datenmenge zu reduzieren ohne die Slave MCU zu überfordern, hatte ich jetzt eine weitere Idee. Dazu bräuchte man nur ein simples Übertragungsprotokoll mit möglichst geringem Overhead und 4 verschiedene Modi für die Notation/Kompression der RGB Daten. Ausgehend davon, dass beim nRF24L01 eine Frame (Brutto-Payload) max 32 Byte lang sein darf und die Länge zur Laufzeit nicht verändert wird, also fix und nicht variabel ist, stehen abzüglich 2 byte für den Header 30 Byte für Instruktionen und Daten zur Verfügung. Aufbau des Headers: 8 bit - CRC8 1 bit - Frame-Type (1=preceding frame [PF]; 0=attendant frame [AF]) 7 bit - n Frames (PF) / x Frame (AF) - (0-127) Macht unterm Strich 2 Byte und damit theoretisch bis zu 1280 (128 Frames * 30 Byte payload / 3 Byte) ansteuerbare RGB-LEDs pro Slave bei im schlimmsten Fall nicht anwendbarer Kompression bzw. der initial Bild-Frame. Das zweite Byte des Headers ist immer >0 wenn RGB Daten übertragen werden. Auf 0x0 gesetzt kann das Frame auch für andere Zwecke genutzt werden um z.B. Konfigurationsparameter vom Master aus zu übertragen, Resets auszulösen etc. Kompressionsmodi: 1. RLE 2. 3 byte corresponding bitmask 3. 1 byte corresponding bitmask 4. plain RGB Bei der "bitmask Kompression" (2. und 3.) geht es darum mit nur einem Bit zu indizieren ob sich für die jeweilige RGB-LED (2.) oder den jeweiligen Farbkanal (3.) zu den Werten der vorangegangen Bild-Frame etwas geändert hat. Der bitmask folgen dann dementsprechend nur die geänderten Werte und der Rest wird eingespart. Wie die Notation der einzelnen Modi auszusehen hat muss ich mir noch überlegen. Auf jeden Fall soll immer stets der ganze Payload genutzt werden und die Instruktionsblöcke dann auf dem Slave aus einem kleinen Buffer heraus zusammengesetzt und anschließend gleich ausgeführt werden. Damit würde die Dekodierung/Dekompression praktisch on-the-fly vonstatten gehen sodass kurz nach dem Eintreffen des letzten Frame das RGB-Array vollständig wäre und die MCU gleich das Erzeugen des WS281x Signals anstoßen könnte. Was haltet ihr von diesem Ansatz?
tecfreak schrieb: > @Vlad Tepesch > Die WS281X RGB Controller werden mit RGB Daten gefüttert (3x8Bit). Die > PWM wird auch von diesen Controllern übernommen. Siehe dazu > https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/ das heißt aber nicht, dass diese 8bit eine Kennlinie abbilden, die unser Auge als Linear wahrnehmen würde. sind diese 8bit einfach das PWM-Tastverhältnis würde es wahrscheinlich reichen pro Kanal 5bit zu übertragen
Hast Du es nicht allzu eilig, so könnte man nur die Differenzen übertragen. Schau' Dir die 3 Werte (RGB) an, stelle die jeweiligen Differenzen fest und pack' sie in ein Byte (z.B. sRRsGGsB). Sollte eine Farbe eine größere Abweichung als z.B. 1 oder 3 aufweisen, so muss der Master den Rest, in den nächsten Bytes, nachliefern. Spart 2/3 bei 8/8/8. Sind die Änderungen größer, so gäbe es noch die Möglichkeit die Differenz in ein Wort zu packen z.B. -sRRRRsGGGGsBBBB. Dann ist die Ersparnis aber nur noch 1/3. Die meisten Kompressionsalgorithmen benötigen Tabellen oder Baumstrukturen für die Kompression. Das ist nur nutzbar, wenn Du "Bilder" übertragen willst. Die kannst Du vorher nach Häufigkeiten durchforsten, eine Tabelle erstellen und dann nur noch die Kompressionswerte übertragen. Viele Kompressionsalgorithmen "leben" aber davon, dass der nächste Wert z.B. in 4 Bit dargestellt werden kann. Ich kenne aber kein Übertragungsverfahen, das mit variabler Datenlänge klarkommt. Auch müssen gelegentlich 9 oder 10 Bit übertragen werden. Ist, wie gesagt, eine Frage der Geschwindigkeit. Oder so.
man kann auch eine dynamische Huffmankodierung probieren (vorrausgesetzt der RAM reicht für die Tabelle und der Prozessor schafft die Bit-Fummelei). Man geht von einem vorgegebenen Baum aus und passt den Baum auf beiden Seiten nach jedem übertragendem Symbol an. Aber alle entropie-basierten Kompressionsalgorithmen haben das Problem, dass die Daten im Worstcase eben nicht komprimiert werden können und damit die Übertragungsbandbreite sprengen. Deswegen würde ich auf sowas verzichten und mir eine Variante aussuchen, die Unabhängig von den darzustellenden Daten die verfügbare Bandbreite auf jeden Fall nicht überschreitet.
Vlad Tepesch schrieb: > > das heißt aber nicht, dass diese 8bit eine Kennlinie abbilden, die unser > Auge als Linear wahrnehmen würde. > > sind diese 8bit einfach das PWM-Tastverhältnis würde es wahrscheinlich > reichen pro Kanal 5bit zu übertragen Hab jetzt wegen der Darstellung der Farben etwas recherchiert und bin auf das fastLED Projekt gestoßen: https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors Dort wird eine reduzierte HSV Farbpalette (rainbow) verwendet die weit aus besser geeignet ist als plain-RGB für die Effekt- und Ambientebeleuchtung. Dabei stehen 256 Farbtöne, 256 Sättigungsstufen und 256 Helligkeitsstufen zur Verfügung, was auch mehr als ausreichend ist. Bei dem genannten HSV Modell kann man jetzt eigentlich davon ausgehen, dass sich schon mal die Helligkeit eher selten ändern wird und nicht übertragen werden muss und wenn doch, dann in den allermeisten Fällen für alle LEDs den gleichen Wert einnimmt (-> RLE). Ähnlich dürfte sich das auch beim Farbton und bei der Sättigung verhalten. Viele Effekte dürften meist immer nur mit einem dieser bedien Werte arbeiten. Amateur schrieb: > Hast Du es nicht allzu eilig, so könnte man nur die Differenzen > übertragen. > > Schau' Dir die 3 Werte (RGB) an, stelle die jeweiligen Differenzen fest > und pack' sie in ein Byte (z.B. sRRsGGsB). Sollte eine Farbe eine > größere Abweichung als z.B. 1 oder 3 aufweisen, so muss der Master den > Rest, in den nächsten Bytes, nachliefern. > Spart 2/3 bei 8/8/8. > > Sind die Änderungen größer, so gäbe es noch die Möglichkeit die > Differenz in ein Wort zu packen z.B. -sRRRRsGGGGsBBBB. Dann ist die > Ersparnis aber nur noch 1/3. > > Die meisten Kompressionsalgorithmen benötigen Tabellen oder > Baumstrukturen für die Kompression. Das ist nur nutzbar, wenn Du > "Bilder" übertragen willst. Die kannst Du vorher nach Häufigkeiten > durchforsten, eine Tabelle erstellen und dann nur noch die > Kompressionswerte übertragen. > > Viele Kompressionsalgorithmen "leben" aber davon, dass der nächste Wert > z.B. in 4 Bit dargestellt werden kann. > Ich kenne aber kein Übertragungsverfahen, das mit variabler Datenlänge > klarkommt. Auch müssen gelegentlich 9 oder 10 Bit übertragen werden. > > Ist, wie gesagt, eine Frage der Geschwindigkeit. > > Oder so. Wäre auch ein sehr guter Ansatz und Rechenleistung sollte auf nem Cortex M0/M3 auch ausreichend da sein. Ob das in dieser Form bei dem o.g. HSV Farbmodell noch gut anwendbar ist muss man schauen. Würde jetzt aber sagen, dass Plain-RGB einfach keinen Sinn macht wenn man sich die Vorteile von HSV-rainbow anschaut. Man fährt besser, wenn die HSV Daten übertragen werden und die Wandlung von HSV nach RGB auf der Slave-MCU stattfindet. Vlad Tepesch schrieb: > man kann auch eine dynamische Huffmankodierung probieren > (vorrausgesetzt > der RAM reicht für die Tabelle und der Prozessor schafft die > Bit-Fummelei). > Man geht von einem vorgegebenen Baum aus und passt den Baum auf beiden > Seiten nach jedem übertragendem Symbol an. > > Aber alle entropie-basierten Kompressionsalgorithmen haben das Problem, > dass die Daten im Worstcase eben nicht komprimiert werden können und > damit die Übertragungsbandbreite sprengen. Deswegen würde ich auf sowas > verzichten und mir eine Variante aussuchen, die Unabhängig von den > darzustellenden Daten die verfügbare Bandbreite auf jeden Fall nicht > überschreitet. Hast vollkommen recht und deswegen scheiden Huffman & Co. auch aus. Schon allein aus dem Grund, dass man bei der adaptiven Huffmankodierung aus zwangsläufig mit ACKs bei der Übertragung arbeiten müsste, da sich sonst jeder noch so kleine Übertragungsfehler fortpflanzen und den Quellsymbol-Baum zerstören würde. So, was aber auf jeden Fall mal sinnvol wäre ist RLE zu implementieren. Gerade bei dem HSV Farbmodell lässt sich damit auch bei komplexeren Farbverläufen/Effekten immer noch sehr viel einsparen im Vergleich zu RGB. Der Vorschlag von "Amateur" nur die jeweilige Differenz zu übertragen lässt sich auch auf HSV anwenden wobei ich hierbei wenn, dann auf eine leicht abgewandelte Form setzen würde. Habe jetzt auch etwas genauer das Datenblatt zum nRF24L01 studiert und mir den Aufbau der Datenpakete angeschaut und wie diese behandelt werden. So errechnet der nRF selbständig vor dem Versenden eine 1-2 Byte CRC und hängt sie and das Paket ran. Stimmt diese nach dem Empfang nicht, so wird das ganze Paket einfach verworfen und landet erst garnich im RX_FIFO Buffer. Für solche Fälle gibt es auch die Möglichkeit ACKs zu verschicken und im gegebenen Fall Retransmissions anzustoßen, aber das alles kostet sehr sehr viel Bandbreite. Verlorene Pakete müssen daher am besten auf Anwendungsebene behandelt werden. Die drei Kanäle/Werte H, S und V nacheinander anstatt kombiniert zu übertragen sollte das ganze auch etwas vereinfachen. Das bedeutet, dass der Master für jeden Kanal erstmal einen separaten, komprimierten Datenstrom erzeugt und diese dann der Größe nach und beim kürzesten angefangen nacheinander überträgt. Sobald am Slave das erste Frame für den 3. Kanal reinkommt, kann dieser anfangen zu dekomprimieren und nach RGB zu wandeln. Der Header Aufbau: 7bit - n frame (0-63) 7bit - x frames (0-63) 2bit - color value (0=H; 1=S; 2=V; 3=n/a) Kompressionsmodi: 0: uncompressed 1: RLE - 1 byte (0-255) Wert über eine definierte Länge 2: RLE-DIFF - 1 byte (0-255) Differenz zur vorangegangenen Bildframe über eine definierte Länge 3: 3bit DIFF - 1Byte 2x(+/- & 0-7) <50% Ersparnis sHHHsHHH sSSSsSSS sVVVsVVV 4: 4bit DIFF - 2Byte 3x(+/- & 0-15) <33% Ersparnis -sHHHHsHHHHsHHH -sSSSSsSSSSsSSSS -sVVVVsVVVVsVVVV Mode-Byte: 3bit - compression mode (0-7) 5bit - iteration count (0-31) Das Mode-Byte wird immer vorangestellt und beschreibt um welchen Kompressionsmodi es sich handelt und wie viele darauf folgenden Anweisungsblöcke/Werte dazu gehören. Im Falle von RLE dienen die 5bit des Mode-Byte zur Längenangabe. Bei Länge >=31 folgt dem Mode-Byte ein Length-Byte und dann erst das Value/Diff-Byte. Ich schätze, dass sich Dank HSV-rainbow und den Kompressionsmodi mindestens 50% der zu übertragenen Datenmenge einsparen lässt. Einziger Nachteil dürfte der hohe Speicherverbrauch auf der Slave-MCU sein, denn man benötigt sowohl Speicher für die RGB Daten als auch für die HSV Daten. Für 1000 LEDs sind es ~6kB. Kritik, Anmerkungen, Ideen? Danke euch schon mal für den Input.
Kleine Korrektur, beim Header liegt der Wertebereich bei 7bit natürlich bei 0-127 und nicht bei 0-63. Das ergibt zwar maximal 11.136 LEDs (128*29*3) die sich so ansprechen ließen, aber dafür reicht weder die Bandbreite um eine gewisse Framerate zu halten noch reicht auf den meisten MCUs der RAM dafür.
tecfreak schrieb: > Dabei stehen 256 Farbtöne, 256 Sättigungsstufen und 256 > Helligkeitsstufen zur Verfügung, was auch mehr als ausreichend ist. Das gilt aber nur bei Maximalhelligkeit oder bei reinen R/G/B-Farben. Beim runterdimmen reduziert sich die Auflösung für Farbtöne und Sättigung.
Damit kann man aber denke ich mal immer noch leben. Sollte auf jeden Fall praktikabler sein für Raumbeleuchtung als reines RGB wo die Helligkeitsregelung nicht so einfach wäre und der Farbverlauf sehr ungleichmäßig ist im Vergleich zu HSV, besonders bei den Gelb- und Orangetönen.
Bei HSV kann man sehr gut in den Helligkeits-Pfad eine Korrekturkurve einbauen, die die logarithmische Wahrnehmung der Helligkeit kompensiert, und danach halt mit mehr als 8 Bit weiterrechnen, die Ausgaben (PWM) sollte dann mindestens 10 Bit auflösen, besser 11 oder 12. Bei HSV verfälscht eine solche Korrektur auch nicht die Farben. Mit einer solchen Korrektur sind 8 Bit für die Helligkeit gut ausreichend. Für Farbe, und Sättigung reichen 8 Bit auch aus. Mit freundlichen Grüßen - Martin
darf man noch fragen wie genau du die WS2812 dann mit dem Cortex-M0/M3 ansteuerst? wenn du die light lib verwendest, werden die ja per bitbanging angesteuert, was ordentlich CPU zeit kostet ... ich nutze ebenfalls den STM32F103C8T6 für die WS2812B allerdings mit SPI und DMA, die LEDs sind tolerant genug, dass es noch gut funktioniert. dafür wandle ich aber das RGB Array in ein "SPI freundlicheres" Array um, wobei 4 bits einem WS2812 bit entspricht. Evtl. liese sich die Umwandlung auch "on-the-fly" im SPI interrupt machen, was ne menge Speicher sparen würde aber etwas mehr die CPU belastet, sollte aber immer noch deutlich weniger sein als mit bit banging. ich habe leider noch keine Erfahrung mit den NRF24, allerdings frage ich mich hier die ganze zeit, was passiert bei Übertragungsfehlern? Wenn die frames einfach verworfen werden könnte es ja zum flackern kommen. Wäre es da nicht sinnvoll mit Redundanz zu arbeiten? evtl. reichen ja 32 verschiedene hellilgkeitstufen pro farbe schon aus. Somit würde jede farbe mit 5 bits codiert sein und 3 bits als Redundanz. Dann wäre die kompression zwar dahin aber 1 bit fehler würden sich korrigieren lassen und 2 bit fehler zumindest erkennen
Sollen nur einzelne Anweisungen oder ein kontinuierlicher Datenstrom gesendet werden? Für einzelne Anweisungen könntest du eine Art Farbtabelle erarbeiten. Ein 8Bit Index für 256 verschiedene Farben, eine zweite für Effekte.
@Martin Schlüter Hättest du dazu evtl. einen Link wo ich mich zu dem Thema etwas einlesen könnte? @benwilliam Also bitbanging kommt vermutlich nicht in Frage. Dachte eher an diesen Ansatz: http://eliaselectronics.com/driving-a-ws2812-rgb-led-with-an-stm32/ Kombiniert mit einem Ringbuffer sollte auch der limitierende RAM kein Problem sein: https://github.com/tiltit/ws2812_dma Hoffe nur, dass die CPU schnell genug ist den buffer fortlaufend zu befüllen. Was die Übertragungsfehler angeht. Beim nRF ist das so, dass wenn z.B. ein Bit gekippt ist der nRF das anhand der CRC feststellen kann und idF. das ganze Frame verwirft. Dieses Verhalten lässt sich auch nicht beeinflussen. Alternativ wäre es möglich mit ACKs zu arbeiten wodurch jedoch die Bandbreite von ~200Kbyte/s auf 60-70KByte/s sinkt, denn jedes empfangene Frame muss ja erst quittiert werden bevor ein neues gesendet werden kann. Daher habe ich mir überlegt mit einem Framecounter zu arbeiten wie weiter oben bei dem Protokoll-Entwurf beschrieben. Kommen eine oder mehrere Frames nicht an muss sich die Slave MCU nur die fehlenden Frame-Nummern merken und diese mit nur einem Request zum Ende jeder Sequenz am Master erfragen und die Requests dann im Falle von weiteren Übertragungsfehlern so lange wiederholen bis alle Frames empfangen wurden und dies dem Master dann anschließend mitgeteilt werden kann der dann mit der neuen Sequenz loslegen kann. Zu der Fehlerrate habe ich mal einen Blogeintrag gelesen (hab den Link leider nicht mehr), dass ~7 von 10.000 Frames verloren gehen. Also könnte man davon ausgehen, dass bei idealen Bedingungen ca. 1 von 1000 Frames erneut gesendet werden muss was die max. Bandbreite theoretisch nicht nennenswert beeintrechtigen sollte. Der nRF24L01 soll mit einem RFX2401C PA/LNA Frontend und einer omnidirektionalen Fractalantenne ( FR05-S1-N-0-001 ) kombiniert werden. @Random Diese Überlegung hatte ich auch und evtl. kann man das dann zusätzlich noch implementieren, aber die Hauptidee war eigentlich jeden einzelne LED mehrere Slaves/Empfänger von einem Master aus "bespielen" zu können. Eine Effektbibliothek wäre aber auf jeden Fall ein großer Mehrwert. Bei 64KB Flash des STM32F103C8T6 (evtl. "nur" 56KB abzüglich 8KB für einen optionalen Bootloader) sollte noch genügend Platz für viele Effektroutinen bleiben. Die Parameter der einzelnen Effekte könnte man dann zentral vom Master aus zur Laufzeit ändern (Farbton, Geschwindigkeit usw.) oder diese als Profile in einem EEPROM ablegen.
Was man da so findet ist sehr theoretisch, ob das Dich einer praktischen Lösung näherbringt: http://de.wikipedia.org/wiki/Gammakorrektur http://de.wikipedia.org/wiki/Stevenssche_Potenzfunktion http://de.wikipedia.org/wiki/Helligkeit http://www.seebacher.de/ISYNET_MODULE/LED-Dimmer-LED-03E-PM-2200-DALI.html Hast Du schon mal ein Bisschen mit LEDs, und PWM 'gespielt', wenn nicht, solltest Du das vielleicht tun, bevor Du an solch ein Projekt rangehst. Ein paar LEDs (Einfarbig / RGB) ein kleiner Mikrocontroller / Eval-Board und Steckbrett genügen. Für Dein Projekt sind vorallem zwei Erkenntnisse wichtig: Wenn man z.B. 8 LEDs mit (zahlenmäßig) gleichmäßig steigender PWM ansteuert, merkt man schnell, daß die Abstufung bei den ersten 3 LEDs recht grob ist, während man bei den letzten 3 LEDs fast keinen Unterschied sieht. Die sichtbare Änderung (8 Bit PWM angenommen) von Stufe 1 zu 2 ist größer als von Stufe 245 zu 255. Konsequenz ist, 'unten' ist's imer zu grob / stufig und im oberen Bereich braucht man gar nicht alle möglichen Werte, da man den Unteschied eh kaum sieht. Das kann man sich zur Datenreduktion, oder zur Steigerung der Qualität zu nutze machen. Bei RGB muß man allerdings aufpassen, bei der Wahrnehmung von Farben entscheidet das physikalische Verhältnis der Anteile zueinander. Hat man also ein schönes Orange z.B. R: 100%, G: 30%, B: 0% und will das dunkler machen. muß man z.B. auf R: 50%, G: 15%, B: 0% gehen, damit der Farbton erhalten bleibt. Geht man mit den einzelnen Anteilen des RGB-Wertes nun über eine nichtlineare Umrechnung, verändert das den Farbton, und da kann HSV seine Stärke ausspielen, da es Farbton und Helligkeit voneinander trennt, da kann man mit dem Helligkeitswert über eine solche Kurve gehen, ohne daß sich der Farbton ändert. und dann kann man halt aus 3 8 Bit Werten für Farbe, Sättigung, und Helligkeit sinnvoll 12 Bit Werte für R, G, und B machen, und dabei die feinstufigkeit der 12 Bit ausnutzen (im unteren Bereich). Wenn einem, zum experimentieren, die Gamma-Kurve zu kompliziert ist, eine Exponential-Funktion, bei der man den untersten Wert auf Null setzt funktioniert auch recht gut. Zur Berechnung solcher Tabellen benutze ich immer Open Office Calc, da kann man schön mit den Parametern spielen. Es ist auf jeden Fall sinnvoll, da selbst ein Bisschen zu 'spielen'. Ein eigenes 'Gefühl' für solche Licht-Spielereien ist nicht durchs lesen von Wiki-Artikeln zu ersetzen. Mit freundlichen Grüßen - Martin
Hallo Martin, also selber habe ich mit LEDs noch nicht rumprobiert. Habe nur die üblichen 0815 Controller daheim die ich unbedingt gegen etwas qualitativ besseres austauschen möchte mit der Möglichkeit zur drahtlosen Vernetzung. Dabei soll das ganze möglichst günstig zu realisieren sein wodurch DMX und artNET schon mal wegfallen. Bei den WS281X LEDs kann ich keinen Einfluss drauf nehmen wie und mit welcher Genauigkeit die PWM generiert wird. Jedoch kommen diese Stripes nur an wenigen Stellen zum Einsatz, sodass ein weiterer Controller nötig wird um auch normale RGB Stripes ansteuern zu können. Ein kleinerer STM32 oder ein ATMEGA8a mit drei FETs sollten es tun. Werde dann erstmal die Wiki Einträge studieren und meinen Arduino mit drei FETs als Experimentierplattform benutzen. Evtl. kann ich auch meinen Colorimeter (Spyder3) benutzen um Farbwerte & Co. auch verifizieren zu können. Danke dir vielmals für die Infos. Das bringt für mich schon mal etwas Licht ins Dunkel :) Gruss Bart
Ich habe mir mal dieses Datenblatt angesehen: http://www.parallax.com/downloads/ws2812b-rgb-led-datasheet http://auschristmaslighting.com/wiki_source/images/b/ba/WS2811.pdf Da ist nur die Rede von 8 Bit / Farbe, über die Art der Umsetzung wird da nichts gesagt, ich vermute aber daß sie linear ist. Im Datenblatt zum WS2811 (Der Ansteuer Chip ohne LED) ist immerhin von PWM die Rede. Mit freundlichen Grüßen - Martin
Hallo, schon mal über ESP8266 nachgedacht? Da gibt es schon code um ArtNet zu empfangen: https://github.com/cnlohr/ws2812esp8266
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.