Steffen schrieb:
> Um es vielleicht doch etwas zu implizieren:
> Eine Funktion bei der ein Balken einer bestimmten Farbe durch den Stripe
> läuft wäre gut. Als Parameter-Übergae stelle ich mir vor: Länge des
> Balkens, Länge des Abstands zum nächsten Balken, Shift-Delay und
> natürlich die gewünschte Farbe.
Und was genau hindert dich jetzt daran, so etwas zu implementieren?
generell:
was mir an deinem Code etwas fehlt, dass ist eine Zwischenschicht
zwischen den Low-Level WS Funktionen und den High-Level Muster Routinen.
Es gibt einige Funktionalitäten, die man immer wieder zum Aufbau von
Mustern brauchen kann.
So zum Beispiel kommt in deiner ersten Funktion die Sequenz vor
1 | NewLED.R=l;
|
2 | NewLED.G=255-l;
|
3 | for(LEDCount=NumberOfLEDs;LEDCount>0;LEDCount--){
|
4 | LEDs[LEDCount]=LEDs[LEDCount-1];
|
5 | }
|
6 | LEDs[0]=NewLED;
|
und das mehrmals mit unterschiedlichen Farbwerten. Aber das grundlegende
Prinzip ist in allen Fällen dasselbe: nämlich alle Farbwerte um 1
POsition zu verschieben und an die Position 0 eine neue Farbe
einschreiben.
Das könnte man als eine Art 'Grundfunktionalität' ansehen und sich dafür
eine eigene Funktion schreiben
1 | void WS2812_ShiftLeft( RGB LEDs[], RGB NewColor )
|
2 | {
|
3 | int i;
|
4 |
|
5 | for( i = NumberOfLEDs; i > 0; i-- ) {
|
6 | LEDs[i] = LEDs[i-1];
|
7 | }
|
8 |
|
9 | LEDs[0] = NewColor;
|
10 | }
|
mit dieser kleinen Hilfsfunktion vereinfacht sich dein Rainbow Effekt zu
1 | void WS2812_Rainbow( RGB LEDs[], uint16_t Delay, uint8_t Step)
|
2 | {
|
3 | int l=0;
|
4 | int k=0;
|
5 | int LEDCount=0;
|
6 | RGB NewLED;
|
7 |
|
8 | for( l = 0; l <= 255; l += Step ) {
|
9 |
|
10 | NewLED.R = l;
|
11 | NewLED.G = 255-l;
|
12 |
|
13 | WS2812_ShiftLeft( LEDs, NewLED );
|
14 | WS2812_Send_All(LEDs);
|
15 | WS2812_Update();
|
16 |
|
17 | for( k = 0; k < Delay; k++ )
|
18 | NOP500
|
19 | }
|
20 |
|
21 | for( l = 0; l <= 255; l += Step ) {
|
22 |
|
23 | NewLED.R = 255-l;
|
24 | NewLED.B = l;
|
25 |
|
26 | WS2812_ShiftLeft( LEDs, NewLED );
|
27 | WS2812_Send_All(LEDs);
|
28 | WS2812_Update();
|
29 |
|
30 | for( k = 0; k < Delay; k++)
|
31 | NOP500
|
32 | }
|
33 |
|
34 | for( l = 0; l <= 255; l += Step ) {
|
35 | NewLED.B=255-l;
|
36 | NewLED.G=l;
|
37 |
|
38 | WS2812_ShiftLeft( LEDs, NewLED );
|
39 | WS2812_Send_All(LEDs);
|
40 | WS2812_Update();
|
41 |
|
42 | for( k = 0; k < Delay; k++ )
|
43 | NOP500
|
44 | }
|
45 | }
|
Ist schon ein bischen einfacher und überschaubarer.
Um bei der von dir angedachten Funktion zu bleiben:
Eine derartige Basiseinheit wäre es zum Beispiel, wenn es eine Funktion
gäbe, die eine Anzahl von Leds, beginnend mit einer bestimmten Led
Nummer auf eine bestimmte Farbe setzen könnte.
Also sowas
1 | void WS2812_SetBlock( RGB LEDs[], int StartLed, int NrLeds, RGB BlockColor )
|
2 | {
|
3 | ...
|
4 | }
|
die Funktion muss ich dir sicher nicht schreiben. Die ist einfach genug,
dass du das sicher alleine kannst.
Aber. Mit dieser Funktion in der Hinterhand vereinfacht sich zum
Beispiel die Funktion WS2812_Single_Color zu
1 | void WS2812_Single_Color( RGB LEDs[], RGB Color ) {
|
2 | WS2812_SetBlock( LEDs, 0, NumberOfLEDs, Color );
|
3 | WS2812_Send_All(LEDs);
|
4 | }
|
und auch für die von dir angedachte Funktion, die einen Block einer
Farbe durch die Leds durchschiebt, ist die Funktion zu gebrauchen.
1 | void WS2812_ScrollBlock( RGB Leds[], RGB Color, int BlockSize, int delay ) {
|
2 |
|
3 | int i;
|
4 | RGB Black;
|
5 |
|
6 | for( i = 0; i <= NumberOfLEDs; i++ ) {
|
7 | // den Stripe in 3 Teile aufteilen
|
8 | // ein Teil vor dem Farbblock
|
9 | // dann den Farbblock
|
10 | // dann den Teil nach dem Farbblock
|
11 |
|
12 | WS2812_SetBlock( LEDs, 0, i, Black );
|
13 | WS2812_SetBlock( LEDs, i, BlockSize, Color );
|
14 | WS2812_SetBlock( LEDs, i + BlockSize, NumberOfLEDs - BlockSize - i, Black );
|
15 |
|
16 | WS2812_Send_All(LEDs);
|
17 |
|
18 | ... delay ....
|
19 | }
|
20 | }
|
diese Zwischenebene mit verwendbaren Basisfunktioalitäten fehlt mir bei
dir komplett. Je bessere derartige Grundfunktionalitäten du dir hier
zurecht legst, desto einfacher kannst du neue Muster implementieren.
Und achte ein wenig auf dein Codeform! Dein Code ist ziemlich schwer zu
lesen. Inkonsistente Einrückung und die Nichtverwendung von Leerzeichen
bzw. Leerzeilen um den Code zu strukturieren, machen einem das Leben nur
unnötig schwer. Jede Sekunde, die du beim Code tippen vermeintlich
einsparst, schlägt sich in weiterer Folge mit Minuten nieder, die du zum
Lesen und Verstehen des Codes benötigst - es ist also ein
Verlustgeschäft wenn man sagt "mach ich später". Machs gleich - und freu
dich über eine bessere Lesbar- und Verstehbarkeit, die dir beim Debuggen
unendlich viel mehr hilft als die 20 Sekunden, die du beim Hinrotzen des
Codes einsparst.