'Ausrollen' beduetet, dass deine Delay Zeiten nach und nach größer
werden. D.h. du überlegst dir eine Abhängigkeit, wie du das von der
Anzahl der Durchgänge durch die Schleifen abhängig machst.
Zudem ist die ganze Sache mit den ineinander geschachtelten Schleifen
nicht so prickelnd, wenn du erst mal ca 5 Sekunden 'rollen' lassen will.
D.h. vereinfache die Sache erst mal soweit, dass du dir sowas wie einen
'Durchgang' definierst. Ein Durchgang ist nichts anderes als das
weiterschalten auf die Nächste Farben/LED Kombination. D.h. mit jedem
Durchgang wird auf die nächste Kombination weitergeschaltet. Ziel ist
es, die hier eher unhandlichen ineinander geschachtelten Schleifen
loszuwerden.
Wie geht das?
Zb. so (Achtung: das ist nicht die endgültige Version, sondern erst mal
nur ein Ansatz, der weiter ausgebaut wird)
1 | ledNr = 0;
|
2 | farbe = 0;
|
3 |
|
4 | while( 1 )
|
5 | {
|
6 | ledNr++;
|
7 | if( ledNr == 8 )
|
8 | {
|
9 | ledNr = 0;
|
10 | farbe++;
|
11 | if( farbe == 4 )
|
12 | farbe = 0;
|
13 | }
|
14 |
|
15 | leds_set_status(farbe, ledNr);
|
16 | delay(150);
|
17 | }
|
Die Weiterschaltungslogik von LED und Farben funktioniert genau gleich,
wie zum Beispiel die Weiterschaltung von Sekunden und Minuten bei einer
Uhr. Genau das gleiche System. Der springende Punkt ist, dass du den
Vorgang 'weiterschalten zum nächsten Zustand' dir als eine Operation
machst. Bei einer Uhr ist das eben 1 Sekunde mehr, woraus sich eine neue
Sekunde und Minute ergibt und bei dir ist es eben 1 Led mehr, woraus
sich eine neue Led/Farbe Kombination ergibt.
Gut. Damit hast du jetzt erst mal eine einzige Schleife, die alles
steuert. Und genau das willst du ja auch. Denn jetzt geht es darum, dass
diese Schleife nach ca. 5 Sekunden aufhören soll. 5 Sekunden, das sind
bei ca. 150 Millisekunden pro Schleifendurchlauf daher 5000 / 150 gleich
33 Wiederholungen. Also baust du die Endlosschleife erst mal auf eine
Schleife um, die 33 Wiederholungen macht
1 | ledNr = 0;
|
2 | farbe = 0;
|
3 |
|
4 | for( durchgang = 0; durchgang < 33; durchgang++ )
|
5 | {
|
6 | ledNr++;
|
7 | if( ledNr == 8 )
|
8 | {
|
9 | ledNr = 0;
|
10 | farbe++;
|
11 | if( farbe == 4 )
|
12 | farbe = 0;
|
13 | }
|
14 |
|
15 | leds_set_status(farbe, ledNr);
|
16 | delay(150);
|
17 | }
|
Das sollte sich jetzt um die ca. 5 Sekunden kümmern. Erst mal. Die Frage
ist, ob man das universeller machen kann?
Kommt drauf an. Wenn mir die 5 Sekunden wichtig sind, und ich nicht viel
rechnen will und vor allen Dingen weil ich weiß, dass ich die delay
Zeiten in weiterer Folge variieren möchte (wegen dem Ausrollen), zieh
ich mir die ominösen 5 Sekunden direkt in den Code hinein. Zb so
1 | ledNr = 0;
|
2 | farbe = 0;
|
3 |
|
4 | laufZeit = 0;
|
5 |
|
6 | while( laufZeit < 5000 )
|
7 | {
|
8 | ledNr++;
|
9 | if( ledNr == 8 )
|
10 | {
|
11 | ledNr = 0;
|
12 | farbe++;
|
13 | if( farbe == 4 )
|
14 | farbe = 0;
|
15 | }
|
16 |
|
17 | leds_set_status(farbe, ledNr);
|
18 |
|
19 | delay(150);
|
20 | laufZeit += 150;
|
21 | }
|
Auch das ergibt wieder die ca. 5 Sekunden. Aber diesmal indem die
verstrichene Zeit seit Beginn mitgezählt wird. Ich brauch immer nur
sicher stellen, dass die delay Zeit auch auf ledZeit aufgeschlagen wird
und irgendwann lande ich dann bei einem Wert der größer als die ominösen
5 Sekunden (5000 Millisekunden) wird und damit ist dann alles zu Ende.
So weit so gut.
Jetzt möchtest du aber auslaufen lassen. Auslaufen bedeutet nichts
anderes, als das die delay Zeiten größer werden. D.h. du brauchst eine
Abhängigkeit. Sagen wir einfach mal nach 2 Sekunden sollen die delay
Zeiten doppelt so lange sein
1 | ledNr = 0;
|
2 | farbe = 0;
|
3 |
|
4 | laufZeit = 0;
|
5 |
|
6 | while( laufZeit < 5000 )
|
7 | {
|
8 | ledNr++;
|
9 | if( ledNr == 8 )
|
10 | {
|
11 | ledNr = 0;
|
12 | farbe++;
|
13 | if( farbe == 4 )
|
14 | farbe = 0;
|
15 | }
|
16 |
|
17 | leds_set_status(farbe, ledNr);
|
18 |
|
19 | if( laufZeit < 2000 )
|
20 | {
|
21 | delay(150);
|
22 | laufZeit += 150;
|
23 | }
|
24 | else
|
25 | {
|
26 | delay(300);
|
27 | laufZeit += 300;
|
28 | }
|
29 | }
|
Da die Schleifensteuerung über das mitsummieren der Delay Zeiten gemacht
wird, ergibt das wieder die 5 Sekunden, ohne dass ich groß was tun muss.
Ich muss nur drauf achten, dass ich auch wirklich die jeweilige Delay
Zeit auch zur Variablen laufZeit dazuzähle.
Jetzt kenn ich deine delay Funktion nicht, ob die so gestaltet ist, dass
man der eine Variable übergeben darf. Ich nehme mal, dass dem so ist.
D.h. ich kann das vereinfachen und mich erst mal von diesem Zusammenhang
DelayZeit und Laufzeit summieren befreien, bzw. das so machen, dass ich
es nicht vergessen kann.
1 | ledNr = 0;
|
2 | farbe = 0;
|
3 |
|
4 | laufZeit = 0;
|
5 |
|
6 | while( laufZeit < 5000 )
|
7 | {
|
8 | ledNr++;
|
9 | if( ledNr == 8 )
|
10 | {
|
11 | ledNr = 0;
|
12 | farbe++;
|
13 | if( farbe == 4 )
|
14 | farbe = 0;
|
15 | }
|
16 |
|
17 | leds_set_status(farbe, ledNr);
|
18 |
|
19 | if( laufZeit < 2000 )
|
20 | delayZeit = 150;
|
21 | else
|
22 | delayZeit = 300;
|
23 |
|
24 | delay( delayZeit );
|
25 | laufZeit += delayZeit;
|
26 | }
|
Was habe ich jetzt erreicht?
Was ich erreicht habe ist, dass ich mir irgendwas ausdenken kann, wie
ich die Delay Zeit von der bereits verstrichenen Laufzeit abhängig
mache. Zb könnte ich sagen: bis 2 Sekunden läuft alles mit 150
Millisekunden. Ab 2 Sekunden wird zum Beispiel die DelayZeit mit jedem
Durchgang um 10 Millisekunden länger. Da gibt es jetzt mehrere
Möglichkeiten. Man könnte das direkt ausrechnen, man kann aber auch
einfach die delayZeit einfach immer nur um ca. 10 Millisekunden länger
machen.
1 | ...
|
2 |
|
3 | if( laufZeit < 2000 )
|
4 | delayZeit = 150;
|
5 | else
|
6 | delayZeit += 10;
|
7 |
|
8 | ...
|
Der Rest des Programms ist so umgeformt worden, dass ich hier an dieser
Stelle mit dieser Delay Zeit machen kann was ich will, die Led und die
Farben laufen trotzdem weiter und die 5 Sekunden werden auch (so
einigermassen) eingehalten.
D.h. du kannst hier an dieser Stelle kreativ werden und dir Verfahren
und Algorithmen ausdenken, aufgrund welcher Zusammenhänge du die Delay
Zeit länger machen willst. Zum Beispieil indem die Delay Zeit nicht um
10 Millisekunden länger wird, sondern sich von Durchgang zu Durchgang
verdoppelt (aufpassen, das das nicht überläuft!)
1 | ...
|
2 |
|
3 | if( laufZeit < 2000 )
|
4 | delayZeit = 150;
|
5 | else if( delayZeit < 16383 )
|
6 | delayZeit *= 2;
|
7 |
|
8 | ...
|
Oder nicht verdoppeln, sondern zb nur mal 2/3 rechnen, damit es nicht
gar so schnell wächst. Oder ....
Hier ist dir jetzt Tür und Tor geöffnet, und du kannst verschiedene
Dinge ausprobieren.