WS2812b Matrix 2 Sketche kombinieren/verbinden - könnte das funktionieren?

Guten Tag,
auf den Fotos ist ein Teil meiner Lichtwand zu sehen, besteht aus 4 einzelnen Elementen, welche alle auch einzeln nacheinander angesteuert werden. Mein Problem ist das letzte Element, die 60x15 Matrix zigzag beginnend unten links. Stromversorgung und Hardware, alles ist stabil und funktioniert auch. Ich habe 2 Sketche / Animationen, welche ich gern nacheinander ablaufen lassen würde. Beides ist FASTLED und läuft einzeln perfekt, da habe ich nichts auszusetzen. Ich nutze einen Mega 2560, Speicher ist also auch genug. Die Sketche sind mal unten drangehängt. Ich habe jetzt keine Ahnung ob sich diese überhaupt verknüpfen/verbinden lassen und wie ich das anstellen sollte. Die flaggs sind auf Matrix Basis 60x15 und die balls auf numLED.
Das ist der IST-Zustand, gibt es Hoffnung oder eine Lösung?

Sketch balls

int frames = 0;

#include "FastLED.h"
#define NUM_LEDS     180
#define DATA_PIN1    3
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB

CRGB leds1[NUM_LEDS];


byte colors[3][3] = { {0xff,0,0}, 
                      {0,0xff,0}, 
                      {0,0,0xff} };


void setup()
{
Serial.begin(115200);  
FastLED.addLeds<LED_TYPE, DATA_PIN1, COLOR_ORDER>(leds1, NUM_LEDS).setCorrection(TypicalLEDStrip); // initializes LED strip
Serial.println("SETUP laüft, stripes sind hinzugefügt ");    
}

void loop() {

  BouncingBalls(0xff,0,0, 1);
  BouncingBalls(0xff,0,0, 1);
  BouncingBalls(0xff,0,0, 2);
  BouncingBalls(0,0xff,0, 1);
  BouncingBalls(0,0xff,0, 1);
  BouncingBalls(0,0xff,0, 2);
  BouncingBalls(0,0,0xff, 1);
  BouncingBalls(0,0,0xff, 1);
  BouncingBalls(0,0,0xff, 2);
  BouncingColoredBalls(1, colors);
  BouncingColoredBalls(2, colors);
  BouncingColoredBalls(3, colors);
  
}


void BouncingBalls(byte red, byte green, byte blue, int BallCount) {
  int maxframes = 600;
  float Gravity = -9.81;
  int StartHeight = 1;
  
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  
  for (int i = 0 ; i < BallCount ; i++) {  
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0;
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2);
  }

  while (true) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
  
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
  
        if ( ImpactVelocity[i] < 0.01 ) {
          ImpactVelocity[i] = ImpactVelocityStart;
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }
  
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],red,green,blue);
    }
    
    showStrip();
    setAll(0,0,0);

      frames++;
      if (frames >= maxframes){
        frames = 0;
        break;
        }
  }
}

// ab hier Bouncing_Balls_Multi_Color

void BouncingColoredBalls(int BallCount, byte colors[][3]) {
  int maxframes = 600;
  float Gravity = -9.81;
  int StartHeight = 1;
  
  float Height[BallCount];
  float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
  float ImpactVelocity[BallCount];
  float TimeSinceLastBounce[BallCount];
  int   Position[BallCount];
  long  ClockTimeSinceLastBounce[BallCount];
  float Dampening[BallCount];
  
  for (int i = 0 ; i < BallCount ; i++) {   
    ClockTimeSinceLastBounce[i] = millis();
    Height[i] = StartHeight;
    Position[i] = 0; 
    ImpactVelocity[i] = ImpactVelocityStart;
    TimeSinceLastBounce[i] = 0;
    Dampening[i] = 0.90 - float(i)/pow(BallCount,2); 
  }

  while (true) {
    for (int i = 0 ; i < BallCount ; i++) {
      TimeSinceLastBounce[i] =  millis() - ClockTimeSinceLastBounce[i];
      Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
  
      if ( Height[i] < 0 ) {                      
        Height[i] = 0;
        ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
        ClockTimeSinceLastBounce[i] = millis();
  
        if ( ImpactVelocity[i] < 0.01 ) {
          ImpactVelocity[i] = ImpactVelocityStart;
        }
      }
      Position[i] = round( Height[i] * (NUM_LEDS - 1) / StartHeight);
    }
  
    for (int i = 0 ; i < BallCount ; i++) {
      setPixel(Position[i],colors[i][0],colors[i][1],colors[i][2]);
      }
    
    showStrip();
    setAll(0,0,0);
    
      frames++;
      if (frames >= maxframes){
        frames = 0;
        break;
        }
  }
}


void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds1[Pixel].r = red;
   leds1[Pixel].g = green;
   leds1[Pixel].b = blue;
   
 #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

Sketch flags:

#include <FastLED.h>

#include <LEDMatrix.h>
#include <LEDSprites.h>

// Change the next 6 defines to match your matrix type and size

#define LED_PIN        3
#define COLOR_ORDER    GRB
#define CHIPSET        WS2812B

#define MATRIX_WIDTH   60
#define MATRIX_HEIGHT  15
#define MATRIX_TYPE    HORIZONTAL_ZIGZAG_MATRIX

cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;


#define SQUARE_WIDTH    8
#define SQUARE_HEIGHT   8
const uint8_t SquareData[] = 
{
  B8_2BIT(11111110),
  B8_2BIT(12222210),
  B8_2BIT(12333210),
  B8_2BIT(12333210),
  B8_2BIT(12333210),
  B8_2BIT(12222210),
  B8_2BIT(11111110)
};
const uint8_t SquareMask[] = 
{
  B8_2BIT(11111110),
  B8_2BIT(11111110),
  B8_2BIT(11111110),
  B8_2BIT(11111110),
  B8_2BIT(11111110),
  B8_2BIT(11111110),
  B8_2BIT(11111110)
};
cLEDSprites Sprites(&leds);

#define MAX_SQUARES  8
#define NUM_COLS  3
cSprite Shape[MAX_SQUARES];
struct CRGB ColTabs[MAX_SQUARES][NUM_COLS];
int NumSquares;


void setup()
{
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds[0], leds.Size());
  FastLED.setBrightness(64);
  FastLED.clear(true);
  delay(500);
 
  FastLED.show();

  int16_t x = MATRIX_WIDTH - SQUARE_WIDTH - 1, y = 0;
  int8_t xc = -1, yc = 1;
  NumSquares = 0;
  while ((NumSquares < MAX_SQUARES) && (x < (MATRIX_WIDTH - SQUARE_WIDTH)))
  {
    for (int i=0; i<NUM_COLS; i++)
      ColTabs[NumSquares][i] = CHSV(NumSquares * 32, 255, 127 + (i * 64));
    Shape[NumSquares].Setup(SQUARE_WIDTH, SQUARE_HEIGHT, SquareData, 1, _2BIT, ColTabs[NumSquares], SquareMask);
    Shape[NumSquares].SetPositionFrameMotionOptions(x, y, 0, 0, xc, 2, 0, 0, SPRITE_DETECT_EDGE | SPRITE_X_KEEPIN);
    Sprites.AddSprite(&Shape[NumSquares]);
    ++NumSquares;
    x += (((SQUARE_WIDTH * 5) / 3) * xc);
    if (x <= 0)
    {
      x = abs(x);
      xc = +1;
    }
    y += yc;
    if ( (y == 0) || (y == (MATRIX_HEIGHT - SQUARE_HEIGHT)) )
      yc = 0 - yc;
  }
}


void loop()
{
  FastLED.clear();
  Sprites.UpdateSprites();
  for (int i=0; i<NumSquares; i++)
  {
    if (Shape[i].GetFlags() & SPRITE_EDGE_X_MAX)
      Sprites.ChangePriority(&Shape[i], SPR_BACK);
    else if (Shape[i].GetFlags() & SPRITE_EDGE_X_MIN)
      Sprites.ChangePriority(&Shape[i], SPR_FRONT);
  }
  Sprites.RenderSprites();
  FastLED.show();
  delay(25);
}

schau dass du setup erst mal zusammen bringst. am besten so wie der erste sketch. ich verstehe nicht, was du da im 2. sketch setup alles treibst.
dann wechselst du im loop einfach hin und her, mit einer statemachine.

Hi

Auch, wenn Das beim Kompilieren noch gut aussieht - der benötigte Speicher ist DA, meines Wissen, NICHT enthalten.
Der Speicher für die LEDs wird erst beim ProgrammSTART angefordert - wenn 1/4tel 60x15 Pixel sind, macht Das 900 LED, a 3 Byte 2700 Byte, Mal 4 Einzelteile 10800 Byte.
Sind Die noch beim Kompilieren frei?

mfG

@postmaster-ino
Danke für Ihr Feedback, aber bitte keine Sorgen machen wegen dem Speicher, das passt alles. flags z.B. 6.712byte. Darum geht es auch nicht.

@harryberlin
"statemachine", sicher gut gemeint, hätten Sie dafür eventuell mal ein Beispiel, wie das aussehen könnte?

Allerdings habe ich bisher nicht erfahren, ob es funktionieren könnte, diese beiden Sketche zusammen zu bringen, oder ob ich hier mit meinem gefährlichen Halbwissen nur einen nicht realisierbaren Wunsch entwickelt habe.
Nun ja, mal abwarten.

Schade, das mir hier kein weiterer hilfreicher Lösungsansatz mitgeteilt wurde, ich hätte gern was dazu gelernt.

Ich wollte nur mal mitteilen, wie ich das gelöst habe. Einfach alle Sketches auf verschiedene Nano und Mega verteilt, insgesamt 4 Stück. Über die delay Funktion im loop vorn und am Ende wartet jeder Arduino ab bis einer oder mehrere fertig sind und fängt dann an seinen Sketch abzuspielen. Funktioniert perfekt.

dobroino:
Schade, das mir hier kein weiterer hilfreicher Lösungsansatz mitgeteilt wurde, ich hätte gern was dazu gelernt.

Ich wollte nur mal mitteilen, wie ich das gelöst habe. Einfach alle Sketches auf verschiedene Nano und Mega verteilt, insgesamt 4 Stück. Über die delay Funktion im loop vorn und am Ende wartet jeder Arduino ab bis einer oder mehrere fertig sind und fängt dann an seinen Sketch abzuspielen. Funktioniert perfekt.

Wenn Du lernen möchtest, dann lies hier mit.

Ich habe Dein Posting erst heute gelesen, obwohl ich hier eigentlich ständig anwesend bin. Auch mir wäre zuerst eine Lösung mit einem Endlichen Automaten eingefallen. Überfliege zumindest mal, worum es da geht, z.B. hier (am Ende dieser Seite befinden sich auch zwei Links zu Beschreibungen hier im Forum).

Gruß

Gregor

dobroino:
Schade, das mir hier kein weiterer hilfreicher Lösungsansatz mitgeteilt wurde, ich hätte gern was dazu gelernt.

Da hätte ich eine gute Nachricht: Das kannst Du immer noch!

Allerdings werde ich Deine Hardware nicht nachbauen und vermutlich wird sie auch recht einmalig sein. Daher ist eine Unterstützung nur ganz allgemein möglich. Da ich Animationen für LED-Streifen kombiniere, schlage ich diese drei Schritte vor:

  • Programme einzeln blockadearm machen, also beispielsweise delay und blockierende Schleifen verändern.
  • Programme einzeln lokalisieren, also möglichst wenig globale Objekte verwenden und die Funktionalität in Funktionen verlagern. In loop sollten nur Funktionen aufgerufen werden.
  • Zusammenführen der Programme zu einem.

Wenn die Resourcen wie beispielsweise Speicher und Pins reichen, dann konnte ich bislang alle Programme zusammenführen.

Wenn Du das anhand eines einfachen Beispiels mit gängiger Hardware lernen möchtest, biete ich Dir meine Hilfe an. Ein LED-Streifen hängt bereit.