Logikfrage zu LED und Array code

Moin,
ich habe eine logikfrage zu meinem Code, die mich gerade in den Wahnsinn treibt, vielleicht kann mit ja jemand von euch meinen Denkfehler aufzeigen.
Ich habe ein LED-Band auf dem Lichter blinken sollen.
Die LEDs adressiere ich mit der Adafruit pixel Lib und einem Array:

int TrafoArray[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

Jetzt sollen alle 15 LEDs nacheinander grün blinken:

void trafo()
{
static byte trafoledpos =0;
  static unsigned long lastmillis5 = 0;
if(szenario3 ==1){
 if(millis() - lastmillis5 >= 400){
  lastmillis5 = millis();
  pixels.setPixelColor(TrafoArray[trafoledpos], pixels.Color(72, 212, 5));
  if(trafoledpos < 14){
    trafoledpos++; 
  }
  if(trafoledpos ==14){
trafoledpos =0;
  }
 }
 if(millis() - lastmillis5 >= 200){
for(int i=0; i <15; i++){
    pixels.setPixelColor(TrafoArray[i], pixels.Color(0, 0, 0));
      }
}
}
if(szenario1 ==1|| szenario2 ==1){
for(int i=0; i <15; i++){
    pixels.setPixelColor(TrafoArray[i], pixels.Color(0, 0, 0));
}
}
}

Jetzt die Frage: Warum geht die letzte LED nur an, wenn ich

if(trafoledpos < 15){
    trafoledpos++; 
  }
  if(trafoledpos ==15){
trafoledpos =0;

schreibe? Arrays sind doch 0 indiziert? Wenn trafoledpos ==13 ist, sollte der code doch mit 14, also der letzten LEDposition im Array noch durchlaufen und die letzte anschalten?

Ja.

Ne eben nicht.

Du hast 15 Einträge:

Um in der FOR-Schleife das erste ELEMENT anzusprechen, muss der Zähler mindestens 1 aufrufen. Wenn Du TO auf < prüfst, :

ELEMENT *INDEX*  TO <  Ergebnis
   1       0       1       0
   2       1       2       1
   3       2       3       2
   4       3       4       3
   .       .       .
   .       .       .
  10       9      10       9
  11      10      11      10
  12      11      12      11
  13      12      13      12
  14      13      14      13
  15      14      15      14  << Letzer Eintrag in Deinem Array

füllst Du ein Array mit 5 ELEMENTEN:
int TrafoArray[]={'A','B','C','D','E'};

ELEMENT *INDEX*   TO   Ergebnis
   1       0   <   1       A
   2       1   <   2       B
   3       2   <   3       C
   4       3   <   4       D
   5       4   <   5       E
1 Like

Danke für deine Antwort, allerdings verstehe ich sie nicht ganz.
Allerdings habe ich verstanden, warum ich bis 15 zählen muss, damit 14 durchläuft. Beide if-schleifen sind hintereinander, wenn die erste Schleife bei 13 trafoledpos auf 14 setzt, setzt die zweite Schleife trafoledpos auf null, ohne das die Schleife die Chance hat durchzulaufen. Damit läuft dann auch die 15 Arrayposition nicht, obwohl ich kurzzeitig (zwischen den if Schleifen) bis zur nicht definierten Arrayposition zähle.

Nein hintereinander.

Und formatiere deinen Code einmal mit Strg-T in der IDE

Seine eigene Antwort als Lösung zu markieren ist auch nicht die feine Art.

2 Likes

Ich bin Kummer gewohnt.

Ich finde die psychosozialen Aspekte interessant.
Aber sonst ist mir das egal.

Und doch finde ich den Hinweis, das so nicht zu tun, schon korrekt. Da es wirklich am beabsichtigten Sinn vorbei geht.

Du willst prüfen ob du über das Ziel hinausgeschossen bist und mit dem Reset das wieder einfangen. Daher würde ich diesen Vergleich an den Anfang der Funktion nehmen und auf >= prüfen.

das Konstrukt schaut eigenartig aus. Warum zwei ifs, warum zwei mal eine Magic Number? Du hast die Frage bereits als gelöst gekennzeichnet. Solltest du dennoch an Alternativen interessiert sein dann poste einen compilierbaren Sketch.

int TrafoArray[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

Wenn die LED hintereinander liegen braucht es kein Array sondern nur den Index. Solche Umrechnungsarrays braucht es nur wenn die Zahlen wild zufällig gewürfelt sind.

Grüße Uwe

1 Like

Danke euch für alle Hinweise, ich versuche nicht unfreundlich zu sein. Tatsächlich ist meine Antwort für mich die Lösung des Problems, genauso wie der Hinweis von Rintin.
Im Grunde genommen ist das ganze auch nur eine "manuelle" for-Schleife, ich war mir nicht sicher, wie ich die Konditionen mit der Schleife und globaler LED Position anders verbinde. Da gibt es garantiert jede Menge eleganterer Lösungen.
Der Hinweis mit Strg-T ist super! Dankeschön!
@Uwe, das ist leider das einzige Array, bei dem das funktioniert hätte, aber danke für den Hinweis.

wird ein Einzeiler:
trafoledpos < 14 ? trafoledpos++ : trafoledpos = 0;

Das ist alles.
Und damit entfällt auch die (für Dich misteriöse) 15.

1 Like

trafoledpos++

Sowas führt gerne (immer?) zu "Sequence Point" Problemen, in Verbindung mit dem ternären Operator.

Manche kann der Compiler melden, aber längst nicht alle.
.

trafoledpos = 0

Der ternäre Operator ist keine Programmflusssteuerung!
Er ist für Daten zuständig, kein if Ersatz.

1 Like

Das nehme ich, Danke! :smiling_face_with_three_hearts:

Nachdem @combie festgestellt hat daß das ganz komische Effekte erzeugen kann?

Niemand muss mir glauben!
Was niemanden davon abhalten sollte Dokus zu lesen und Experimente zu machen.

Wobei man/ich aber anmerken muss, dass bei einem "undefined Behavior" durchaus auch mal das dabei rauskommt, was man sich wünscht. Nur eben nicht reproduzierbar.

trafoledpos = trafoledpos < 14 ? trafoledpos+1 : 0;

So ist es problemlos. Und wer in Programmflüssen denkt, sieht auch ein if :slight_smile:

sieht auch ein if

Wer einmal verstanden hat wie ein Hammer funktioniert, für den sieht die ganze Welt wie ein Nagel aus.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.