Arduino Loop Problem

Hallo liebe Community!

Ich habe ein Dekoelemnt mit WS2812b LEDs gebaut und möchte dies über ein Handy ansteuern.

Dies funktioniert grundsätzlich auch einwandfrei -> Wenn die zu durchlaufenden Programme nicht zu lange dauern bzw. zu komplex sind.

im folgenden Code wird eine ein Wert über ein Handy auf die Variable "Modus" gespeichert und dann wird der jeweile Fall ausgeführt.

#define REMOTEXY_MODE__ETHERNET_LIB
#include <Ethernet.h> 
#include <SPI.h> 
#include <RemoteXY.h> 
#include <Adafruit_NeoPixel.h>
#define LED_PIN    6
#define LED_COUNT 289
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
#define REMOTEXY_ETHERNET_MAC "DE:AD:BE:EF:EF:ED" 
#define REMOTEXY_SERVER_PORT 6377 


// RemoteXY configurate   
#pragma pack(push, 1) 
uint8_t RemoteXY_CONF[] = 
  { 255,5,0,0,0,159,0,8,93,0,
  3,8,2,2,8,60,2,26,6,0,
  52,3,41,41,2,26,129,0,12,4,
  18,6,242,65,117,115,0,129,0,12,
  11,36,6,242,82,71,66,32,103,101,
  115,97,109,116,0,129,0,12,40,18,
  6,242,82,101,103,101,110,98,111,103,
  101,110,0,129,0,12,47,34,6,242,
  83,116,114,111,98,111,115,107,111,112,
  0,129,0,12,18,33,6,242,82,71,
  66,32,97,117,195,159,101,110,0,129,
  0,12,25,34,6,242,82,71,66,32,
  83,111,110,110,101,0,129,0,12,33,
  31,6,242,82,71,66,32,105,110,110,
  101,110,0,129,0,12,55,18,6,242,
  84,104,101,97,116,101,114,0,4,192,
  49,45,45,11,2,26 }; 
   
// this structure defines all the variables of your control interface  
struct { 

    // input variable
  uint8_t Modus; // =0 if select position A, =1 if position B, =2 if position C, ... 
  uint8_t RGB_r; // =0..255 Red color value 
  uint8_t RGB_g; // =0..255 Green color value 
  uint8_t RGB_b; // =0..255 Blue color value 
  int8_t Slider; // =0..100 slider position 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY; 
#pragma pack(pop) 

///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 



void setup()  
{ 
  RemoteXY_Init ();  
  strip.begin();        
  strip.show();  
} 

void loop()  
{  
  RemoteXY_Handler (); 
   
switch(RemoteXY.Modus)

{
  case 0:
    for(int i=0; i<strip.numPixels(); i++) // For each pixel in strip...
    strip.setPixelColor(i, 0,0,0);         //  Set pixel's color (in RAM)
    strip.show(); 
  break;

  case 1:
     for(int i=0; i<LED_COUNT; i++) // For each pixel in strip...
    strip.setPixelColor(i,RemoteXY.RGB_r,RemoteXY.RGB_g,RemoteXY.RGB_b);         //  Set pixel's color (in RAM)
    strip.show(); 
  break;

  case 2:
    for(int i=0; i<155; i++) // For each pixel in strip...
    strip.setPixelColor(i,RemoteXY.RGB_r,RemoteXY.RGB_g,RemoteXY.RGB_b);         //  Set pixel's color (in RAM)
    strip.show(); 
  break;

  case 3:
    for(int i=156; i<272; i++) // For each pixel in strip...
    strip.setPixelColor(i,RemoteXY.RGB_r,RemoteXY.RGB_g,RemoteXY.RGB_b);         //  Set pixel's color (in RAM)
    strip.show(); 
  break;

  case 4:
     for(int i=273; i<289; i++) // For each pixel in strip...
    strip.setPixelColor(i,RemoteXY.RGB_r,RemoteXY.RGB_g,RemoteXY.RGB_b);         //  Set pixel's color (in RAM)
    strip.show(); 
  break;

  case 5:
 Stroboskop();
 delay(2);
  break;
  
}
}

void Stroboskop()
{
     int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(RemoteXY.Slider);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  } 

}

Da der Fall 5 so lange dauert, kann man nichts tun bis dieser durchlaufen wurde. Jedoch dauert das so lange, dass teilweise die Verbindung zum Server zu lange dauert und somit das ganze nicht nutzbar ist.

Meine Frage also - gibt es eine Möglichkeit etwas in den Code einzubauen, der sowas in die Art "Multitasking" ermöglicht. Schon klar das dies der Arduino nicht kann aber durch eine Funktion oder einen Trick möglicherweise?

Vielen Dank!!
LG Valentin

Was hindert dich daran die for-Schleifen aufzulösen und nur einen Schritt pro loop() Durchlauf zu machen?

Ich weis nicht genau wie ich das umsetzen sollte - denn ich muss ja meine Anweisungen alle pro Durchgang im Loop durchführen, also wie sollte ich nur einen Teil pro Loop durchführen. Weis nicht nicht wie ich das schreiben sollte -> könntest du mir ein kleines Beispiel zeigen?

Nimm anstatt der for Schleife den loop als schleife und mache nur einen bzw. eine kleine Anzahl von Anweisungen, danach dein anderes Gedöns. Somit ist sichergestellt, dass das „andere Gedöns“ auch oft genug gemacht wird und nicht warten muss, bis deine for Schleife fertig ist.

Ich habe ja einige for Schleifen, und in die Loop Anweisung könnte ich ja nur eine geben oder?

valentin8809:
Ich habe ja einige for Schleifen, und in die Loop Anweisung könnte ich ja nur eine geben oder?

Nein, da kannst du abhängig deiner Auswahl mehrere einfügen.
Es läuft dann aber immer nur eine, die ausgewählte.

Sorry ich weis leider echt nicht wie ich das umsetzten soll -> wahrscheinlich verstehe ich euren Ansatz nicht ganz. Wie sollte ich mehrere if Anweisungen in diese Zeile packen?

void loop()

{

}

ich habe ja einige for schleifen, welche, wenn diese durchlaufen werden, ihre aufgaben haben

valentin8809:
Sorry ich weis leider echt nicht wie ich das umsetzten soll -> wahrscheinlich verstehe ich euren Ansatz nicht ganz. Wie sollte ich mehrere if Anweisungen in diese Zeile packen?

void loop()

{

}




ich habe ja einige for schleifen, welche, wenn diese durchlaufen werden, ihre aufgaben haben

Das sind nun mal Grundlagen, die du lernen musst.
Und wenn man das will, kann man es auch im Web finden und lesen.

Z.B. so:

void loop()
{

if (Variable1 == 1)
  {
    tu was1
  }

if (Variable2 == 1)
  {
    tu was2
  }
}

loop() ist schon eine Schleife. Damit kannst du dann auch eine for-Schleife nachbilden. Genauso mit Zählvariablen. Und für die Abfrage derer nimmst du "if". Dann wird bei jedem Durchlauf nur ein Schritt gemacht

gibt es eine Möglichkeit etwas in den Code einzubauen, der sowas in die Art "Multitasking" ermöglicht

Du brauchst nur etwas auszubauen, um Multitasking zu ermöglichen: Deine delay().
Schreib loop so, dass es keine Zeit braucht.
for Schleifen nur für Sachen, die gleichzeitig gemacht werden sollen. (Z.B. "Alle Led auf Grün")
Wenn etwas nacheinander passieren soll, laufen zwischendurch zig loop-Durchläufe, in denen nur festgestellt wird, dass es noch zu früh ist, etwas zu tun.

delay() ist für kleine Tests, um einfacher zuschauen zu können. Du kannst natürlich auch definieren, dass in deinem Projekt die Zeit in 20 ms Schritten vergeht. Da wäre ein delay(20) erlaubt, um sich das Leben zu vereinfachen.

Schau mal ins Thema Switch case und loop function für Neopixel LED, wo ich ein Beispiel für LED und den seriellen Monitor gemacht habe. Zeiten nur mit millis() realisiert und loop nur für schnelle Schleifen.

Wenn Du das, was vom seriellen Monitor kommt, durch Informationen vom Handy ersetzt, könnte es in die richtige Richtung gehen.