Array ohne Anfang und Ende

Mir wird der Code für folgendes Szenario etwas zu lang. 4 LEDs laufen bei insgesamt 8 LEDs im Kreis.

Gibt es eine Möglichkeit, ein Array ohne Anfang und Ende zu erstellen? Würde wie folgt aussehen...

myArray[] = {0,1,2,3};

Nun wird in einer for-Schleife bspw. der Wert myArray gewählt. Nun möchte ich den Ausgang vor und nach dem i mit schalten. Wenn i = 2 wäre, würde das klappen. i-1 = 1 i = 2 i = 3 Gehe ich aber nun von i = 0 aus, wäre das erste Problem da, welches ich mit Abfragen abfangen müsste, denn i-1 = ??? i = 0 i+1 = 1 An dieser Stelle wäre es gut, wenn i-1 den letzen Index-Eintrag im Array entsprechen würde, somit i-1 = 3 ``` *void lauflicht4(unsigned long i) {  unsigned long aktuelleZeit = millis();  static unsigned long vorherigeZeit;  unsigned long pause = i;

 Serial.println(pause);  if(aktuelleZeit - vorherigeZeit > pause)  {    static int l;    ShiftPWM.SetAllRGB(0,0,0);    if(l > 3)    {      ShiftPWM.SetRGB(l, 0,0, 255);      ShiftPWM.SetRGB(l-1, 0,0, 255);      ShiftPWM.SetRGB(l-2, 0,0, 255);      ShiftPWM.SetRGB(l-3, 0,0, 255);    }    else if(l > 2)    {      ShiftPWM.SetRGB(l, 0,0, 255);      ShiftPWM.SetRGB(0, 0,0, 255);      ShiftPWM.SetRGB(1, 0,0, 255);      ShiftPWM.SetRGB(2, 0,0, 255);    }    else if(l > 1)    {      ShiftPWM.SetRGB(l, 0,0, 255);      ShiftPWM.SetRGB(7, 0,0, 255);      ShiftPWM.SetRGB(0, 0,0, 255);      ShiftPWM.SetRGB(1, 0,0, 255);    }    else if(l > 0)    {      ShiftPWM.SetRGB(l, 0,0, 255);      ShiftPWM.SetRGB(6, 0,0, 255);      ShiftPWM.SetRGB(7, 0,0, 255);      ShiftPWM.SetRGB(0, 0,0, 255);    }    else if(l == 0)     {      ShiftPWM.SetRGB(l, 0,0, 255);      ShiftPWM.SetRGB(5, 0,0, 255);      ShiftPWM.SetRGB(6, 0,0, 255);      ShiftPWM.SetRGB(7, 0,0, 255);    }            if(l > 6) l = 0;    else l++;

   vorherigeZeit = aktuelleZeit;  } }* ```

hi,

mach Dir ein array mit dem inhalt:
6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0
und in der for schleife zählst Du nicht von 1 bis 7, sondern von 2 bis 9.

bei i == 2:
led[i-2] = 6
led[i-1] = 7
led[i ] = 0
led[i+1] = 1

bei i == 9:
led[i-2] = 5
led[i-1] = 6
led[i ] = 7
led[i+1] = 0

byte ledarr[] = {6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0};

for(byte i=2, i<=9; i++) {
ShiftPWM.SetRGB(ledarr[i-2], 0, 0, 255);
ShiftPWM.SetRGB(ledarr[i-1], 0, 0, 255);
ShiftPWM.SetRGB(ledarr[i],   0, 0, 255);
ShiftPWM.SetRGB(ledarr[i+1], 0, 0, 255);
}

Du kannst natürlich verschieben, wieviele leds vor- und nachlaufen sollen.

wird das eine equinox?

gruß stefan

Wenn du mir sagst, was eine equinox ist! ;)

sowas:

http://www.youtube.com/watch?v=JNpjX5mobfI

Nein, so ein großes Projekt ist es nicht :wink:

Mir gehts gerade nur um die Lichteffekte innerhalb eines Plexiglas Zylinder der mit einem Ultraschnallnebler befeuert wird. Die Uhr hab ich hier schon gesehen. Die sieht super aus

ich hab' das wort zeit in Deinem code gesehen und gleich an die uhr gedacht. bei meiner fehlt noch das gehäuse...

ich hoffe, das war das, was 'Du brauchst.

gruß stefan

Ja, habe deinen Code-Gedankenanstoß soweit ausgearbeitet, damit die Zeit wieder passt mit dem umschalten.

void lauflicht4(unsigned long i) {
  unsigned long pause = i;

  int ledArray[] = {
    6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0 };

  for(int l = 2; l <= 9; )
  {
    unsigned long aktuelleZeit = millis();
    static unsigned long vorherigeZeit;
    Serial.println(l);
    if(aktuelleZeit - vorherigeZeit > pause) 
    {
      ShiftPWM.SetAllRGB(0,0,0);        
      ShiftPWM.SetRGB(ledArray[l - 2], 0, 0, 255);
      ShiftPWM.SetRGB(ledArray[l - 1], 0, 0, 255);
      ShiftPWM.SetRGB(ledArray[l], 0, 0, 255);
      ShiftPWM.SetRGB(ledArray[l + 1], 0, 0, 255);

      l++;  
      vorherigeZeit = aktuelleZeit;
    }
  }
}

So eine Uhr zu bastel wäre sicher interessant, nur müsste ich dafür einiges an Material wieder heranholen. Bevor nicht renoviert wird, macht es kein Sinn, das Ding so an die Wand zu hängen. Mich würde das Netzkabel stören :wink: Evtl. vllt mal eine Tischuhr.

hi,

so wird das nicht hinhauen. Du zählst andauern von 2 bis 9 und irgendwann, wenn zufällig die zeitüberschritten wird, schaltest Du weiter.

richtig wäre ein zähler i, der jedesmal, wenn die zeit erreicht ist, um 1 weiterzählt, dann werden die leds geschaltet, und wenn i gleich 10 ist, wird i wieder auf 2 gesetzt.

gruß stefan

und ja, natürlich kommt das kabel in die wand. 8)

void lauflicht4(unsigned long i, unsigned int r, unsigned int g, unsigned int b) {
  unsigned long pause = i;

  int ledArray[] = {
    0, 1, 2, 3, 4, 5, 6, 7, 0 , 1, 2       };

  for(int l = 0; l <= 7; )
  {
    unsigned long aktuelleZeit = millis();
    static unsigned long vorherigeZeit;

    if(aktuelleZeit - vorherigeZeit > pause) 
    {
      ShiftPWM.SetAllRGB(0,0,0);        
      ShiftPWM.SetRGB(ledArray[l], r, g, b);
      ShiftPWM.SetRGB(ledArray[l + 1], r, g, b);
      ShiftPWM.SetRGB(ledArray[l + 2], r, g, b);
      ShiftPWM.SetRGB(ledArray[l + 3], r, g, b);

      l++;  
      vorherigeZeit = aktuelleZeit;
    }
  }
}

Lasse nun mit 0 bei jedem Modus starten. Ist einfacher die zu duplizieren. Hab lauflicht1 bis lauflicht7. Verstehe aber nicht, wo genau das Problen sein soll.

Ich schalte letzten Endes l nur weiter, wenn die Zeit erreicht ist, was auch Sinn ist. Die for-Schleife hat im Header keine Anweisung mehr, das l++ erhöht werden soll.

Nebenbei eine Frage, kann es sein, das in der Arduino IDE das formatieren etwas verbuggt ist? Bei jedem formatieren rückt er das ende eines Arrays ‘}’ immer weiter nach rechts (auch weit über den Bildschirmrand hinaus, wenn häufig genug betätigt).

"Unendliche" Arrays kannst Du mit einem Modulo realisieren. :)

"Unendliche" Arrays kannst Du mit einem Modulo realisieren.

Wenn es so glatte Größen wie 16, 8, 4 ( wie bei sschultewolter sind ), reicht auch eine Bitmaske ( & 0x03 in deinem Fall )

    static int l;  // ein byte reicht auch
    unsigned long aktuelleZeit = millis();
    static unsigned long vorherigeZeit;

    if(aktuelleZeit - vorherigeZeit > pause)  {
      vorherigeZeit = aktuelleZeit;
      byte pos = l & 0x03;        //   0, 1, 2, 3, 0 ...
      byte vor = (l-1) & 0x03;   //  3, 0, 1,  2, 3 ...
      byte nach = (l+1) & 0x03; // 1, 2, 3, 0,  1 ...

      ShiftPWM.SetAllRGB(0,0,0);        
      ShiftPWM.SetRGB(pos,   r, g, b);
      ShiftPWM.SetRGB(vor,   r, g, b);
      ShiftPWM.SetRGB(nach, r, g, b);
      l++;  // l darf auch überlaufen !
     }

hi,

ich habe nicht gesehen, daß Du die laufvariable im "for" nicht weiterzählst (auf die idee bin ich noch nie gekommen). :)

gruß stefan