Liste oder Array auf Inhalt prüfen

Guten Morgen,

mein Sternenhimmelprojekt hat begonnen.
Abgesehen davon, dass das meiste Handwerklich gemacht werden muss, fehlt leider noch zum Teil die Programmierung.

Ich habe einige LEDs (ca. 150) die "unkontrolliert" funkeln.

Jetzt würde ich gerne bestimmte LEDs so steuern, dass sie anders funkeln als andere (z.B. blau statt weiß).
Dies wird allerdings nicht immer so sein, sondern es sollen ganz bestimmte wechsel stattfinden.

Beispiel:

  1. Alle LEDs sind aus
  2. Bei bestimmten Ereignis fangen alle LEDs an weiß zu funkeln.
  3. Bei bestimmten Ereignis, sollen LED 0,2,5,8,11,14,23,32,47,132,147 blau funkeln und LED 7,13,72,81,85,92,103,146 sollen gelb funkeln.
  4. Bei bestimmten Ereignis sollen alle wieder normal weiß funkeln.

Mein Problem ist, dass die LEDs die das "besondere Verhalten" haben sollen nicht direkt aufeinander folgen und ich nicht einfach eine for-Schleife nehmen kann.

Ich müsste also die besonderen LEDs in eine Liste (list) oder array schreiben (je eins pro besonderes Verhalten) und dann beim Durchlauf aller LEDs von 0-149 prüfen ob die aktuelle LED Teil der Menge "Normale", "Blaue" oder "Gelbe" LEDs ist.
(bzw. reicht es zu prüfen ob die LED in der Teilmenge BlaueLEDs oder GelbeLEDs enthalten sind -> der Rest ist ja dann weiß).
Ich kenne listen aus Java, bin mir aber nicht sicher ob das bei C geschweige denn in der Arduino IDE so geht, daher hoffe ich auf Rat wie ich mein Vorhaben am besten umsetzen kann.
Vielleicht gibt es ja noch etwas wesentlich einfacheres und unkomplizierteres...
Ich danke euch!

Ich habe mich bisher nicht all zu sehr mit den Möglichkeiten des Arduinos beschäftigt, aber:
Kannst Du das nicht einfach in C++ programmieren? Dann könntest Du ein Array von LED-Objekten durchrattern und entsprechende Events triggern. Die Objekte könnten dann auch ihren aktuellen Status speichern, evtl. selbstständig flackern, etc...

Wenn Dir das zu viel Aufwand ist, schau Dir mal das hier an:

Damit solltest Du, wenn Du Arrays von Farben definiert hast, in Deiner for-Schleife recht simpel herausfinden können, ob die Farbe gewechselt werden muss.

VG

Leon333:
Mein Problem ist, dass die LEDs die das “besondere Verhalten” haben sollen nicht direkt aufeinander folgen und ich nicht einfach eine for-Schleife nehmen kann.

byte blauLED[]={0,2,5,8,11,14,23,32,47,132,147};
byte gelbLED[]={7,13,72,81,85,92,103,146};

...

  for (int i=0;i<sizeof(blauLED);i++)
  {
    // setze RGB-Werte für blauLED[i]
  }
  for (int i=0;i<sizeof(gelbLED);i++)
  {
    // setze RGB-Werte für gelbLED[i]
  }

... oder so :smiley:

Die Syntax für Arrays ist in C/C++ auch nicht anders als in Java. Java hat schließlich seine grundlegende Syntax von C/C++ übernommen.

Der Unterschied ist was ein Array ist. In Java ist alles ein Objekt. In C sind Arrays ganz primitiv. Das ist lediglich eine durchgehende Anzahl von Speicherzellen und die Array Variable ist ein Zeiger auf das erste Element.

Collections wie Listen und Vektoren gibt es in C nicht. Die gibt es in C++ in der sogenannten Standard Template Library, aber die gibt es standardmäßig auf dem Arduino nicht. Einfach weil Mikrocontroller nicht viel Speicher haben und viele Collections relativ speicherintensiv sind. Das fängt schon mit einer Liste an, da man zusätzlich zu den eigentlichen Daten pro Element ein oder zwei Zeiger braucht (je nachdem ob sie einfach oder doppelt verkettet ist).
Es gibt eine Implementierung der STL für den Arduino (und einfache Collections wie Vector haben da auch kaum Overhead), aber wenn du nicht weißt was du machst, lass es. Sowas kann man auch einfach mit normalen Arrays erschlagen.

die Möglichkeit von jurs ist ja auf jedenfall schonmal funktional (ungetestet, aber das geht natürlich so).

Die LEDs werden aber ständig neu gesteuert (also sie ändern quasi immer ihre Helligkeit).
Somit muss ich eh immer alle 150 LEDs in einer for schleife ändern lassen.

Elegant wäre es dann, wenn man etwas machen könnte wie

for (int i=0;i<150;i++)
{
    if(i==inBlaueLedMengeEnthalten)
    {
       // lasse LED[i] blaufunkeln
    }
    elseif(i==inGelbeLedMengeEnthalten)
    {
       // lasse LED[i] gelb funkeln
    }
    else
    {
      // lasse LED[i] normal/weiß funkeln
   }
}

ich muss dann halt irgendwie testen ob i in der Menge blaueLEDs oder gelbeLEDs vorkommt…
gibts da noch einen anderen Weg?

Leon333:
ich muss dann halt irgendwie testen ob i in der Menge blaueLEDs oder gelbeLEDs vorkommt…

Sowas:

bool containsElement(byte* array, byte element, int length)
{
    for(int i = 0; i < length; i++)
    {
          if(array[i] == element)
               return true;
    }

    return false;
}

Oder lasse dir i zurückgeben. Das ist willst du hier wohl eher. Und -1 wenn das Element nicht gefunden wurde:

int containsElement(byte* array, byte element, int length)
{
    for(int i = 0; i < length; i++)
    {
          if(array[i] == element)
               return i;
    }

    return -1;
}

Leon333:
gibts da noch einen anderen Weg?

Ich sehe nichts, was gegen den von mir oben geposteten Vorschlag spricht.
Hier nochmal etwas detaillierter ausgearbeitet:

  for (int i=0;i<150;i++)
  {
    // erstmal so tun als wenn alle LEDs immer normal funkeln, setze RGB-Werte für jede LED
  }
  if (Bedingung für blaues Funkeln)  // Wenn diese Bedingung erfüllt ist, andere Werte setzen
  {
   for (int i=0;i<sizeof(blauLED);i++)
    {
      // setze RGB-Werte für blauLED[i]
    }
  }
  if (Bedingung für gelbes Funkeln)  // Wenn diese Bedingung erfüllt ist, andere Werte setzen
  {
    for (int i=0;i<sizeof(gelbLED);i++)
    {
      // setze RGB-Werte für gelbLED[i]
    }
  }
  leds.show(); // Jetzt die gesetzten Werte anzeigen

danke ihr beiden.. daraus bekomme ich bestimmt was hin.
und an jurs: dagegen sprechen nur kleinigkeiten....
ich hatte vorher nicht im kopf, dass du erstmal alle LED normal behandelst und dann die Farbe sozusagen überschreibst...

Problem ist halt, dass ich zum Teil die LEDs dann auch runter dimmen will... also z.B. nur die blauen leuchten lassen will und weiß z.B. runter regeln..
klar geht das alles auch mit deinem Vorschlag, aber ich würde mir ganz gerne das eintippen aller LEDs in ein array ersparen, wenn ich es Beispielsweise bei ca. 15 blauen und 10 gelben belassen könnte.

Mit der kurzen abfrage "ist die LED Teil der BlauenLEDs", kann man direkt entscheiden ob ein farbwechsel oder eine andere Helligkeit eingestellt werden soll.
Es gibt immer mehrere Wege - vor allem beim Programmieren, aber den anderen Weg verstehe ich besser, bzw. kann ich für meine Anwendung besser gebrauchen.

Nochmals vielen Dank euch beiden!
ich hoffe ich werde die nächsten Tage dazu kommen es auch zu programieren und nicht am bau scheitern...

irgendwie klappt das mit dem

int containsElement(byte* array, byte element, int length)
{
    for(int i = 0; i < length; i++)
    {
          if(array[i] == element)
               return i;
    }

    return -1;
}

bei mir nicht.

Ich habe es so implementiert:

#define NUM_LEDS 150
int ledArray[]={2,3,4,5,11,12,13};
int anzahlLedArray= 7;

int containsElement(byte* array, byte element)
{
    for(int j = 0; j < anzahlLedArray; j++)
    {
          if(array[j] == element)
               return j;
    }

    return -1;
}


im loopTeil bei einer bestimmen startbedingung:

 for(int i=0; i < NUM_LEDS ; i++)
      {  
    
        if (containsElement(ledArray,i))
        {    
           Serial.print("Die LED: "); 
           Serial.print(i); 
           Serial.println(" gehört dazu!");     
        }
        else
        { 
           Serial.print("Die LED: "); 
           Serial.print(i); 
           Serial.println(" gehört NICHT dazu!");     
        }

Es heißt bloß immer “Die LED 2 gehört NICHT dazu!” (der Rest gehört angeblich dazu)…
Was mache ich falsch?

Deine Abfrage ist falsch. Du gibt -1 zurück, wenn das Element nicht enthalten ist. -1 ist aber true! Alles ungleich ist 0 ist true.

Entweder du lässt die Methode einen bool(ean) zurückgeben wie in der anderen Version. Dann hast du aber nicht den Index außerhalb der Funktion. Oder du fragst ab ob der Rückgabewert >0 ist

Danke für die schnelle Antwort!

Ich habe mal auf die schnelle die >0 variante probiert.
Also:

        if (containsElement(ledArray,i)>0)

Das klappt auch "einigermaßen", denn es heißt jetzt, dass 3,4,5,11,12,13 dazu gehören.
Die 2 gehört nun NICHT dazu (sollte aber).

Die boolean variante funktioniert dagegen wunderbar.
Etwas seltsam. Ich verstehe soweiso dir ganzen Typen nicht.

Gibt es eigentlich einen bestimmten Grund, warum du das ledArray als byte initialisierst und nicht als int?

Da die Anzahl der LEDs ja statisch ist, gibt es einen eleganten weg die Anzahl der Elemente in ledArray zählen zu lassen?

int size = sizeof(ledArray) / sizeof(int);

funktioniert leider nicht (warum auch immer... )

Leon333:
Gibt es eigentlich einen bestimmten Grund, warum du das ledArray als byte initialisierst und nicht als int?

Dachte du hättest ein Byte Array. Du solltest dann die Parameter auf int ändern. Das macht vielleicht an der Stelle auch Probleme.

Aber wieso int wenn die Werte <= 255 sind? Verschwendet nur Speicher wenn es nicht gebraucht wird.

also mein array wird auch als byte initialisiert:

byte ledArray[]={2,3,4,5,11,12,13};

bloß sind da halt eigentlich zahlen drin.

Das Argument als Typ "byte" zu wählen zwecks Speicher leuchtet ein!

Ich hab übrigends geschaut ob der Fehler mit der "2" behoben ist, wenn ich alles auf int umstelle.
Ist er aber nicht.

Egal.
Mit boolean funktioniert es.

Edit: um die Elemente in ledArray zu zählen funktionierte folgendes (Hirn einschalten):

byte size = sizeof(ledArray) / sizeof(byte);