FastLED / Matrix / Brainstorming

Hey Ihr,

ich habe da eine Idee im Kopf aber gerade einen Knoten im Hirn, wie man die umsetzen könnte.

Man stelle sich ein LED Array vor, auf welchem sich ein Pixel "bewegt".

Dieser soll einen Schweif hinter sich herziehen. Soweit komme ich klar: Vor dem Schreiben der neuen Pixelposition den "Bildspeicher" nicht löschen, sondern nur ein bisschen runterdimmen. Ergebnis: ein Schweif in Bewegungsrichtung des Pixels hinter selbigem. 2D Knight Rider sozusagen.

Jetzt möchte ich die Form des Schweifs zusätzlich durch eine "Strömung" / "Wind" beeinflussen. Sagen wir zum Anfang, alles soll zusätzlich nach unten verwischen/ausfaden - so, dass z.B. ein waagerecht sinusschwingender Pixel einen wellenförmigen Schweif nach unten erzeugt.

Mir fällt dazu nur ein, zeilenweise den Inhalt einer waagerechten Linie halbtransparent in die jeweils darunterliegende Zeile zu kopieren. Konkret 1.) Zeile lesen, 2.) Farbwerte ein bisschen runterskalieren, 3.) zum Inhalt der darunterliegenden Zeile addieren und dorthin schreiben.

Könnt Ihr Euch das vorstellen? Wie würdet Ihr das machen? Ideen, Vorschläge?

Grüße

Helmuth

Ok, Knoten geplatzt. Ja, so funktioniert das. Fehlte nur 4.) neue Zeile nochmal dimmen

wir haben doch gern geholfen, helmuth...

:wink:

Hier, so sieht das aus (sorry für den Sound):

Darf man fragen wie das innere deiner Lampe aussieht? ich hab auch so eine allerdings nur meinem einem led streifen in der Mitte.

Eisebaer:
wir haben doch gern geholfen, helmuth...

Ja es hat schon geholfen daß wir zuhöhrten. :wink: :wink: :wink:
Grüße Uwe

@Eisebaer + @Uwe: Ja, hat es wirklich - durch das präzise Beschreiben des Problems ist mir die Lösung klar geworden... denken beim Tippen sozusagen... danke fürs Zuhören! :slight_smile:

@gloob: Das ist auch EIN Streifen, 4m mit 240 LEDs auf ein transparentes Acrylrohr gewickelt und diese Spirale als Matrix hergenommen.

Hier: Warpkern (newscool) :wink:

hi,

klar, nennt sich rubberducking:

gruß stefan

Eisebaer war schneller - lol - ja genau so war es bei mir! :slight_smile:

Ich mag auch die Erklärung bei "Cone of Answers":

http://www.c2.com/cgi/wiki?ConeOfAnswers

Und wir waren zu langsam um zu antworten :wink: :wink:

Helmuth:
@Eisebaer + @Uwe: Ja, hat es wirklich - durch das präzise Beschreiben des Problems ist mir die Lösung klar geworden... denken beim Tippen sozusagen... danke fürs Zuhören! :slight_smile:

Das passiert schon öfters. Wenn man das Problem erklähren und mitteilen will, muß man sich damit näher befassen und findet selbst die Zusammenhänge und manchmal auch die Lösung. Du mußt jetzt aber nicht alle Probleme selbst lösen indem Du Romane schreibst. Wir sind weiterhin hier. :wink: :wink: :wink: :wink:

Viele Grüße Uwe

Das nehme ich doch beim Wort: Als nächstes würde ich gern den Schweif in einer beliebigen Richtung (0-360 Grad) berechnen.

Für 0, 45, 90, 135, ... Grad bekomme ich es hin. Aber wie könnte ich das verallgemeinern, dass es mit jedem Richtungsvektor/Winkel funktioniert?

Hier mal ein Beispielcode. Ein Punkt beschreibt eine Lissajousfigur. Die Funktion MoveAll() ganz am Ende erzeugt den Verwischeffekt nach unten. Ideen, wie man die modifizieren könnte?

/* 20 * 12 Matrix */


#include <FastLED.h>

// LED stuff

#define LED_PIN     23
#define COLOR_ORDER GRB
#define CHIPSET     WS2811

#define BRIGHTNESS  255

// Matrix dimensions

const uint8_t WIDTH  = 20;
const uint8_t HEIGHT = 12;

#define NUM_LEDS (WIDTH * HEIGHT)
CRGB leds[NUM_LEDS];

// Timer stuff

struct timer {unsigned long takt; unsigned long lastMillis; unsigned long count; int delta; byte up; byte down;};
timer multiTimer[3]; 
int timers = sizeof( multiTimer ) / sizeof( multiTimer[0] ); 

// Cos table

uint8_t const cos_wave[256]   
{0,0,0,0,1,1,1,2,2,3,4,5,6,6,8,9,10,11,12,14,15,17,18,20,22,23,25,27,29,31,33,35,38,40,42,
45,47,49,52,54,57,60,62,65,68,71,73,76,79,82,85,88,91,94,97,100,103,106,109,113,116,119,
122,125,128,131,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,
189,191,194,197,199,202,204,207,209,212,214,216,218,221,223,225,227,229,231,232,234,236,
238,239,241,242,243,245,246,247,248,249,250,251,252,252,253,253,254,254,255,255,255,255,
255,255,255,255,254,254,253,253,252,252,251,250,249,248,247,246,245,243,242,241,239,238,
236,234,232,231,229,227,225,223,221,218,216,214,212,209,207,204,202,199,197,194,191,189,
186,183,180,177,174,171,168,165,162,159,156,153,150,147,144,141,138,135,131,128,125,122,
119,116,113,109,106,103,100,97,94,91,88,85,82,79,76,73,71,68,65,62,60,57,54,52,49,47,45,
42,40,38,35,33,31,29,27,25,23,22,20,18,17,15,14,12,11,10,9,8,6,6,5,4,3,2,2,1,1,1,0,0,0,0
};

void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness( BRIGHTNESS );
  //Serial.begin(9600);

  // set all counting directions positive for the beginning
  
  for (int i = 0; i < timers; i++) multiTimer[i].delta = 1; 
  
  // set range (up/down), speed (takt=ms between steps) and starting point (count) of all variables
  
  multiTimer[0].takt=  2;       //x1
  multiTimer[0].up = 255;
  multiTimer[0].down = 0;
  multiTimer[0].count = multiTimer[0].down;
  
  multiTimer[1].takt=  5;      //y1
  multiTimer[1].up = 255;
  multiTimer[1].down = 0;
  multiTimer[1].count = multiTimer[1].down;
  
  multiTimer[2].takt=  6;      //color
  multiTimer[2].up = 255;
  multiTimer[2].down = 0;
  multiTimer[2].count = multiTimer[2].down;

 
}

void loop()
{
  UpdateTimers();
  //DimmAll();
  MoveAll();
  // Lissajous point 
  leds[ XY(
    cos_wave[ multiTimer[0].count ] * WIDTH / 255, 
    cos_wave[ multiTimer[1].count] * (HEIGHT-2) / 255) ]  
    += CHSV( multiTimer[2].count, 255, 255);
  FastLED.show();
}



uint16_t XY( uint8_t x, uint8_t y) {  // translates from x, y into an index into the LED array
  uint16_t i;
  i = (y * WIDTH) + x;
  return i;
}

void UpdateTimers() // counts all variables with different speeds linear up and down
{
  unsigned long now=millis();
  for (int i=0; i < timers; i++) 
  {
    while (now-multiTimer[i].lastMillis >= multiTimer[i].takt)
    {
      multiTimer[i].lastMillis += multiTimer[i].takt;
      multiTimer[i].count = multiTimer[i].count + multiTimer[i].delta;
      if ((multiTimer[i].count == multiTimer[i].up) || (multiTimer[i].count == multiTimer[i].down)) 
      {
        multiTimer[i].delta = -multiTimer[i].delta;
      }
    }
  }
}

void DimmAll()  // the tail behind the dots
{
  for(int i = 0; i < NUM_LEDS; i++) 
  {
    leds[i].nscale8( 240 );
  }
}

void MoveAll()  // the tail downwards 
{
  for(int i = 0; i < NUM_LEDS - WIDTH; i++) 
  {
    leds[i] += leds[i + WIDTH];
    leds[i].nscale8( 120 );
  }
}

Beste Grüße

Helmuth

edit: Ich muss das Problem wohl präziser beschreiben?! :wink:

Habe im Hinterkopf die Frage, ob man den Bresenham-Algorithmus dafür missbrauchen könnte. Ich fürchte nur, das wird zu langsam, jeden Pixel als Linie der Länge 1 zu beschreiben...

Nur um das Thema nochmal hochzuholen: Stellt Euch das hier mal mit einem rotierenden Schweif vor.