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...
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/Gammakorrekturhttp://de.wikipedia.org/wiki/Stevenssche_Potenzfunktionhttp://de.wikipedia.org/wiki/Helligkeithttp://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