(solved, but continued) Inhalt eines RGB Strips weich überblenden

Hi,

der Thread über den WS2812 hat mich inspiriert.:slight_smile: Es geht darum, von einer Anzeige eines RGB Strips zu einer anderen Anzeige schön weich hinzufaden, also über n Zwischenschritte (Zwischenbilder) weiche Übergänge von einer Anzeige zu einer anderen zu erreichen, um Effekte "weichzuzeichnen". Grundsätzlich würde ich wie folgt vorgehen:

Aktuelle Anzeige in Array1 kopieren

gewünschte neue Anzeige berechnen/aus Speicher holen und in Array2 kopieren

von Array1 (alt) nach Array2 (neu) über n Schritte überblenden:

von 0 bis n folgendes ausführen (einzelnes Zwischenbild berechnen)

für 0 bis Anzahl der LEDs folgendes ausführen (über ganze Striplänge)

für r, g, b folgendes ausführen (jede LED schrittweise zum Sollwert führen)

wenn altes rot < neues rot dann r=r+((neu-alt)/Schritte)*n
wenn altes rot > neues rot dann r=r-((alt-neu)/Schritte)*n
mit grün und blau das gleiche

EDIT: Wie sich im Laufe des Threads herausstellen wird, lautet die korrekte Formel
r = alt + (((alt - neu) * n) / Schritte)
und die Fallunterscheidung enfällt.

ganzes Zwischenbild anzeigen/ausgeben
--> nach n facher Ausführung entspricht die aktuelle Anzeige dem gewünschten Array2 (?)

Funktioniert das auf diese Art?

Wenn ich das so mache, habe ich für einen Fadevorgang verdammt viele IF Abfragen (n BilderLEDs3 Farben*2 Möglichkeiten). Das dauert doch ziemlich lange, oder? Außerdem muss ich den gesamten Strip noch 2 * extra im Speicher vorhalten (aktuelle Anzeige + Array1 + Array2).

Gibt es eine einfachere oder schnellere oder speicherschonendere Möglichkeit? Oder macht man das so?

Beste Grüße, Helmuth

hi,

erstmal: wenn Du eine LED von 0 auf 255 dimmst, wirst Du sehen, daß der verlauf sehr ungleichmäßig ist. von null weg steigt die helligkeit sehr schnell, und im letzten teil passiert nicht mehr viel. drum ist es besser, runder, wenn Du die helligkeit logarithmisch steigt. dazu legst Du ein array an.

int loga[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 25, 28,
30, 33, 36, 39, 42, 46, 49, 53, 56, 60, 64, 68, 72, 77, 81, 86, 90, 95, 100, 105, 110, 116,
121, 127, 132, 138, 144, 150, 156, 163, 169, 176, 182, 189, 196, 203, 210, 218, 225,
233, 240, 248, 255};

jede LED kann nun werte zwischen 0 und 63 annehmen.

gruß stefan

@stefan:
sehr gut, deine log Tabelle.

Als Krümelkacker sehe ich,
dass ... 20, 22, 25, 28, 30, 33 ...
eher ... 20, 22, 24, 27, 30, 33 ...
sein sollte :wink:

Auch ist es kein int array sondern ein byte array, und gehört eigentlich ins PROGMEM.

@Helmuth

Ich nehme mal an, Schritte ist eine Zahl ~ 100, damit man bei 30 bps auch Zeit hat, den Effekt zu geniessen.
(neu-alt)/Schritte ist in der Regel eine konstante 0, bei einer Integer-Operation. ( während der gesamten Überblendung )
geht also so nicht.

Probier mal:
zwischenwert = alt + (neu-alt)*n / Schritte;

"Schritte" als Zweierpotenz sind dem Controller und Compiler am liebsten ( 32, 64, 128, 256 )
/256 ist noch nicht mal ein Shift, sondern nur ein byte wegschmeissen

@Eisebaer:
Ja, das ist mir schon aufgefallen, dass die Helligkeitsempfindlichkeit des Auges nicht linear ist. Helligkeit – Wikipedia Das kommt wohl noch aus Zeiten, wo wir uns die Nahrung nachts im Wald fangen mussten... Ich habe mir mit einem Oszi mal die Tastverhältnisse der PWM vom 2801 angesehen - der macht das strikt linear.

Eigentlich würde man sich noch mindestens 10 Zwischenschritte zwischen 0 und 1 wünschen... Bei wenigen Pixeln könnte man das ja noch per SW PWM runterdimmen, aber ich fürchte, bei längeren Strips endet das in Geflacker, weil die Framerate einbricht.

Gute Idee mit Deiner Logarithmustabelle, die werde ich einbauen. Der vermeintliche Farbraum von 24 Bit ist eigentlich Augenwischerei, weil 3/4 davon praktisch unnütz sind. Mit Deiner Tabelle reduziert er sich auf 18 Bit.

Aber zurück zur eigentlich Frage: Ist mein eingangs beschriebenes strukturelles Vorgehen eine Übersetzung in Code wert? Mach "man" das so?

@michael_x:

michael_x:
Ich nehme mal an, Schritte ist eine Zahl ~ 100, damit man bei 30 bps auch Zeit hat, den Effekt zu geniessen.

Ich wollte weniger den Effekt an sich genießen, als vielmehr das "Holpern" zwischen 0 und 255 abmildern.
Sagen wir mal, ein Effekt (z.B. Zellautomat) läuft ohne Weichzeichnung mit 5 fps - und mit dann jeweils über 64 Zwischenschritte (nach Eisebaers Tabelle) = 320 fps mit einem ziemlich kurzen Strip ?!

michael_x:
"Schritte" als Zweierpotenz sind dem Controller und Compiler am liebsten ( 32, 64, 128, 256 )
/256 ist noch nicht mal ein Shift, sondern nur ein byte wegschmeissen

Gut, das zu wissen.

Wenn Du das mit Integer-Arithmetik machst, wirst Du am Resultat von r=r+((neu-alt)/Schritte)*n keine Freude haben. Also besser so:

r=r+(neu-alt)*n/Schritte;

In der Schule hast Du zwar gelernt, dass die Reihenfolge bei den Punkt-Operationen nicht relevant ist (gleiche Priorität), aber das gilt bei Integern nicht, weil dort bei Divisonen meist Abrundungen vorgenommen werden.

Hallo,

darf ich fragen wie Ihr das mit dem Logarithmus berechnet habt? Mit welcher Basis? Ich kann das nicht nachvollziehen. Danke.

Ich habe versucht, es jetzt gemäß all euren Hinweisen umzusetzen.

Irgendwas stimmt mit der Funktion fade_from_old_to_new_frame(int steps, int wait_ms) nicht - beim Compilen erzeugt das die Fehlermeldung "ISO C++ forbids declaration of ´fade_from_old_to_new_frame´ with no type" :astonished:

Hier der gesamte Code:

#include <FastSPI_LED.h>

//that is the length of your strip
#define NUM_LEDS 20

//change the order of your rgb here
struct CRGB { unsigned char r; unsigned char g; unsigned char b; }; 
struct CRGB *leds; 

//to save, what you see right now (current frame)
byte old_frame[NUM_LEDS][3]; 

//to store, what you want to see in future (next frame)
byte new_frame[NUM_LEDS][3]; 

//some tools first:
//set color of a single LED, don´t show
void set_color_led(int adex, int cred, int cgrn, int cblu) {  
  leds[adex].r = cred;
  leds[adex].g = cgrn;
  leds[adex].b = cblu;  
  }

//save what you see right now to old_frame for playing with it later  
void copy_led_array_to_old_frame(){ 
  for(int i = 0; i < NUM_LEDS; i++ ) {
    old_frame[i][0] = leds[i].r;
    old_frame[i][1] = leds[i].g;
    old_frame[i][2] = leds[i].b;
  }  
}

//show something unique
void create_random_pixels(){ 
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    set_color_led(i, random(255), random(255), random(255));
  }
  FastSPI_LED.show();
}

//fill new_frame with some linear color fade
void fill_new_frame_with_content(){ 
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    new_frame[i][0] = i*(255/NUM_LEDS);
    new_frame[i][1] = 255-(i*(255/NUM_LEDS));
    new_frame[i][2] = 0;
  }
}

//make the content of new_frame visible
void show_new_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = new_frame[i][0];
    leds[i].g = new_frame[i][1];
    leds[i].b = new_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//just to compare: show the frame you started with again
void show_old_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = old_frame[i][0];
    leds[i].g = old_frame[i][1];
    leds[i].b = old_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//fade to new content over a numer of steps with wait_ms delay between the steps
fade_from_old_to_new_frame(int steps, int wait_ms){
  for(int a=0; a < steps; a++){ // over the steps
    for(int b=0; b < NUM_LEDS; b++){ // over the whole lenght
      //modify red
      if (old_frame[b][0] < new_frame[b][0]) 
        {leds[b].r=leds[b].r+(new_frame[b][0]-old_frame[b][0])*a/steps;}
      if (old_frame[b][0] > new_frame[b][0]) 
        {leds[b].r=leds[b].r-(old_frame[b][0]-new_frame[b][0])*a/steps;}
      //modify green
      if (old_frame[b][1] < new_frame[b][1]) 
        {leds[b].g=leds[b].g+(new_frame[b][1]-old_frame[b][1])*a/steps;}
      if (old_frame[b][1] > new_frame[b][1]) 
        {leds[b].g=leds[b].g-(old_frame[b][1]-new_frame[b][1])*a/steps;}
      //and blue
      if (old_frame[b][2] < new_frame[b][2]) 
        {leds[b].b=leds[b].b+(new_frame[b][2]-old_frame[b][2])*a/steps;}
      if (old_frame[b][2] > new_frame[b][2]) 
        {leds[b].b=leds[b].b-(old_frame[b][2]-new_frame[b][2])*a/steps;}
    }
    FastSPI_LED.show(); 
    delay(wait_ms);
  }
}
   
void setup(){
  FastSPI_LED.setLeds(NUM_LEDS);
  //select your chipset according to your strip type here - have a look at FastSPI documentation
  //i´m using a LPD1101 right know who behaves like a LPD6803
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803); 
  FastSPI_LED.init();
  FastSPI_LED.start();
  leds = (struct CRGB*)FastSPI_LED.getRGBData(); 
}

void loop() {
  /* just for testing - it seems to work so far
  create_random_pixels();  
  copy_led_array_to_old_frame();
  delay(1000);
  fill_new_frame_with_content();
  show_new_frame();
  delay(1000);
  show_old_frame();
  delay(1000);
  show_new_frame();
  delay(1000);
  */
  create_random_pixels();  
  copy_led_array_to_old_frame();
  fill_new_frame_with_content();
  fade_from_old_to_new_frame(50,100);
  
}

beim Compilen erzeugt das die Fehlermeldung "ISO C++ forbids declaration of ´fade_from_old_to_new_frame´ with no type"

da deine Funktion fade_from_old_to_new_frame keinen Rückgabewert liefert, muss sie als

void fade_from_old_to_new_frame(int steps, int wait_ms) {
...
}

definiert werden.

Anfänger- und Flüchtigkeitsfehler, Danke.

So, es läuft, macht über ca. 5 Schritte, was es soll (es ist eine Annäherung an new_frame erkennbar), dann wird es chaotisches buntes Geflacker...

Falsche Datentypen? Hinweise, Ideen?

Ich habe den Eindruck, die Veränderung mit jedem Step ist größer, als sie sollte. Irgendwas stimmt mit der Formel nicht.

Nochmal der korrigierte Code:

#include <FastSPI_LED.h>

//that is the length of your strip
#define NUM_LEDS 20

//change the order of your rgb here
struct CRGB { unsigned char r; unsigned char g; unsigned char b; }; 
struct CRGB *leds; 

//to save, what you see right now (current frame)
byte old_frame[NUM_LEDS][3]; 

//to store, what you want to see in future (next frame)
byte new_frame[NUM_LEDS][3]; 

//some tools first:
//set color of a single LED, don´t show
void set_color_led(int adex, int cred, int cgrn, int cblu) {  
  leds[adex].r = cred;
  leds[adex].g = cgrn;
  leds[adex].b = cblu;  
  }

//save what you see right now to old_frame for playing with it later  
void copy_led_array_to_old_frame(){ 
  for(int i = 0; i < NUM_LEDS; i++ ) {
    old_frame[i][0] = leds[i].r;
    old_frame[i][1] = leds[i].g;
    old_frame[i][2] = leds[i].b;
  }  
}

//show something unique
void create_random_pixels(){ //show something unique
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    set_color_led(i, random(255), random(255), random(255));
  }
  FastSPI_LED.show();
}

//fill new_frame with some linear color fade
void fill_new_frame_with_content(){ //some linear fade
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    new_frame[i][0] = i*(255/NUM_LEDS);
    new_frame[i][1] = 255-(i*(255/NUM_LEDS));
    new_frame[i][2] = 0;
  }
}

//make the content of new_frame visible
void show_new_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = new_frame[i][0];
    leds[i].g = new_frame[i][1];
    leds[i].b = new_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//just to compare: show the frame you started with again
void show_old_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = old_frame[i][0];
    leds[i].g = old_frame[i][1];
    leds[i].b = old_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//fade to new content over a numer of steps with wait_ms delay between the steps
void fade_from_old_to_new_frame(int steps, int wait_ms){
  for(int a=0; a < steps; a++){ // over the steps
    for(int b=0; b < NUM_LEDS; b++){ // over the whole lenght
      //modify red
      if (old_frame[b][0] < new_frame[b][0]) 
        {leds[b].r=leds[b].r+(new_frame[b][0]-old_frame[b][0])*a/steps;}
      if (old_frame[b][0] > new_frame[b][0]) 
        {leds[b].r=leds[b].r-(old_frame[b][0]-new_frame[b][0])*a/steps;}
      //modify green
      if (old_frame[b][1] < new_frame[b][1]) 
        {leds[b].g=leds[b].g+(new_frame[b][1]-old_frame[b][1])*a/steps;}
      if (old_frame[b][1] > new_frame[b][1]) 
        {leds[b].g=leds[b].g-(old_frame[b][1]-new_frame[b][1])*a/steps;}
      //and blue
      if (old_frame[b][2] < new_frame[b][2]) 
        {leds[b].b=leds[b].b+(new_frame[b][2]-old_frame[b][2])*a/steps;}
      if (old_frame[b][2] > new_frame[b][2]) 
        {leds[b].b=leds[b].b-(old_frame[b][2]-new_frame[b][2])*a/steps;}
    }
    FastSPI_LED.show(); 
    delay(wait_ms);
  }
}
   
void setup(){
  FastSPI_LED.setLeds(NUM_LEDS);
  //select your chipset according to your strip type here - have a look at FastSPI documentation
  //i´m using a LPD1101 right know who behaves like a LPD6803
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803); 
  FastSPI_LED.init();
  FastSPI_LED.start();
  leds = (struct CRGB*)FastSPI_LED.getRGBData(); 
}

void loop() {
  /* just for testing - it seems to work so far
  create_random_pixels();  
  copy_led_array_to_old_frame();
  delay(1000);
  fill_new_frame_with_content();
  show_new_frame();
  delay(1000);
  show_old_frame();
  delay(1000);
  show_new_frame();
  delay(1000);
  */
  create_random_pixels();  
  copy_led_array_to_old_frame();
  fill_new_frame_with_content();
  fade_from_old_to_new_frame(20,100);
  
}

Ich habe den Eindruck, die Veränderung mit jedem Step ist größer, als sie sollte. Irgendwas stimmt mit der Formel nicht.

Gut beobachtet:

Die Änderung wird mit jedem Schritt größer.

Statt 
  leds[b].r=leds[b].r+(new_frame[b][0]-old_frame[b][0])*a/steps;
besser
leds[b].r=old_frame[b][0] + (new_frame[b][0]-old_frame[b][0])*a/steps;

Probier mal:
zwischenwert = alt + (neu-alt)*n / Schritte;

:wink:

Edit, mist... Smileys mögen keinen Code. Hast es trotzdem richtig gelesen. Tapfer, Helmuth

Ah, da hatte ich ins falsche Array gefasst...

YES, super, das funktioniert jetzt!

Karma +1 für alle hilfreichen Tipgeber und herzliche Grüße in die Runde. Macht echt Spaß mit Euch.

Helmuth

@Eisebaer: Die Log Tabelle baue ich morgen ein.

Für alle, die mitspielen wollen, hier nochmal der aktuelle Code: Ein Fade von einem Zufallsmuster zu einem Rot-Blau Verlauf und zurück...sieht ziemlich gut und echt smooth aus, selbst mit den nur 15 Bit vom 1101.

Na dann kann ja jetzt das Effekte Programmieren losgehen... :wink:

#include <FastSPI_LED.h>

//that is the length of your strip
#define NUM_LEDS 20

//change the order of your rgb here
struct CRGB { unsigned char r; unsigned char g; unsigned char b; }; 
struct CRGB *leds; 

//to save, what you see right now (current frame)
byte old_frame[NUM_LEDS][3]; 

//to store, what you want to see in future (next frame)
byte new_frame[NUM_LEDS][3]; 

//some tools first:
//set color of a single LED, don´t show
void set_color_led(int adex, int cred, int cgrn, int cblu) {  
  leds[adex].r = cred;
  leds[adex].g = cgrn;
  leds[adex].b = cblu;  
  }

//save what you see right now to old_frame for playing with it later  
void copy_led_array_to_old_frame(){ 
  for(int i = 0; i < NUM_LEDS; i++ ) {
    old_frame[i][0] = leds[i].r;
    old_frame[i][1] = leds[i].g;
    old_frame[i][2] = leds[i].b;
  }  
}

//show something unique
void create_random_pixels(){ //show something unique
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    set_color_led(i, random(255), random(255), random(255));
  }
  FastSPI_LED.show();
}

//fill new_frame with some linear color fade
void fill_new_frame_with_content(){ //some linear fade
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    new_frame[i][0] = i*(255/NUM_LEDS);
    new_frame[i][1] = 255-(i*(255/NUM_LEDS));
    new_frame[i][2] = 0;
  }
}

//make the content of new_frame visible
void show_new_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = new_frame[i][0];
    leds[i].g = new_frame[i][1];
    leds[i].b = new_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//just to compare: show the frame you started with again
void show_old_frame(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].r = old_frame[i][0];
    leds[i].g = old_frame[i][1];
    leds[i].b = old_frame[i][2];
  }
  FastSPI_LED.show(); 
}

//fade to new content over a numer of steps with wait_ms delay between the steps
void fade_from_old_to_new_frame(int steps, int wait_ms){
  for(int a=0; a < steps; a++){ // over the steps
    for(int b=0; b < NUM_LEDS; b++){ // over the whole lenght
       
      
      //modify red
      if (old_frame[b][0] < new_frame[b][0]) 
        {leds[b].r=old_frame[b][0]+(new_frame[b][0]-old_frame[b][0])*a/steps;}
      if (old_frame[b][0] > new_frame[b][0]) 
        {leds[b].r=old_frame[b][0]-(old_frame[b][0]-new_frame[b][0])*a/steps;}
      //modify green
      if (old_frame[b][1] < new_frame[b][1]) 
        {leds[b].g=old_frame[b][1]+(new_frame[b][1]-old_frame[b][1])*a/steps;}
      if (old_frame[b][1] > new_frame[b][1]) 
        {leds[b].g=old_frame[b][1]-(old_frame[b][1]-new_frame[b][1])*a/steps;}
      //and blue
      if (old_frame[b][2] < new_frame[b][2]) 
        {leds[b].b=old_frame[b][2]+(new_frame[b][2]-old_frame[b][2])*a/steps;}
      if (old_frame[b][2] > new_frame[b][2]) 
        {leds[b].b=old_frame[b][2]-(old_frame[b][2]-new_frame[b][2])*a/steps;} 
    }
    FastSPI_LED.show(); 
    delay(wait_ms);
  }
}

void fill_new_frame_with_random_pixels(){
  for(int i = 0 ; i < NUM_LEDS; i++ ) {
    new_frame[i][0] = random(255);
    new_frame[i][1] = random(255);
    new_frame[i][2] = random(255);
  }
}
   
void setup(){
  FastSPI_LED.setLeds(NUM_LEDS);
  //select your chipset according to your strip type here - have a look at FastSPI documentation
  //i´m using a LPD1101 right know who behaves like a LPD6803
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803); 
  FastSPI_LED.init();
  FastSPI_LED.start();
  leds = (struct CRGB*)FastSPI_LED.getRGBData(); 
  create_random_pixels();
}

void loop() {
  /* just for testing 
  create_random_pixels();  
  copy_led_array_to_old_frame();
  delay(1000);
  fill_new_frame_with_content();
  show_new_frame();
  delay(1000);
  show_old_frame();
  delay(1000);
  show_new_frame();
  delay(1000);
  ok, that seems to work so far*/
   
  copy_led_array_to_old_frame();
  fill_new_frame_with_content();
  fade_from_old_to_new_frame(100,50);  
  //delay(1000);
  copy_led_array_to_old_frame();  
  fill_new_frame_with_random_pixels();
  fade_from_old_to_new_frame(100,10);
  //delay(1000);

}

hi,

gratuliere, helmut

wegen des logarithmus: ich hab' da nichts berechnet, sondern von einem arduino-buch rauskopiert.

gruß an alle, stefan

Hallo,

ich dachte Du hättest das alles mal so nebenbei berechnet. Steht in dem Buch dabei wie man das berechnet? Ich habe mir den Kopf zerbrochen wie man das anstellt. Hin und her überlegt wie man da ran geht. Am Ende habe ich es jetzt wenigstens geschafft die PWM Wertabstufung zuberechen mit manuellen austesten der Hochzahlabstufungen. Es ist auch egal ob man Basis 2 oder 10 nimmt. Am Ende kommt die gleiche Kurvenkrümmung heraus. Wie ich die zur Berechnung benötigten Abstufung durch eine Formel berechne bin ich noch nicht drauf gekommen. Aber seht selbst.
Jedenfalls, was ich sagen oder fragen wollte, ich bekomme eine leicht andere Abstufung heraus. Ich komme nicht auf die gleichen 64 Werte wie in Deinem Buch. Meine Abstufung ruckelt wenn es von dunkel zu heller geht. Deshalb hätte ich gern gewußt wie man auf die anderen Werte kommt. Konnte nur im Internet und Wikipedia lesen das unser Auge Helligkeitsunterschiede logarithmisch wahr nimmt.

µC PWM Helligkeit.xls (42 KB)

Guten Morgen, weiter geht´s!

Der geschätzte @pylon hat im englischen Teil des Forums eine Vereinfachung der Fadefunktion vorgeschlagen, welche nicht nur schön, sondern v.a. erheblich schneller ist:

//fade to new content over a numer of steps with wait_ms delay between the steps
void fade_from_old_to_new_frame(int steps, int wait_ms){
  for(int a=0; a < steps; a++){ // over the steps
    for(int b=0; b < NUM_LEDS; b++){ // over the whole lenght
      leds[b].r = (int)old_frame[b][0] + ((int)new_frame[b][0] - (int)old_frame[b][0]) * a / steps; //over the red
      leds[b].g = (int)old_frame[b][1] + ((int)new_frame[b][1] - (int)old_frame[b][1]) * a / steps; //the green
      leds[b].b = (int)old_frame[b][2] + ((int)new_frame[b][2] - (int)old_frame[b][2]) * a / steps; //and the blue LEDs
    }
    FastSPI_LED.show(); 
    delay(wait_ms);
  }
}

Hier der Link zum dem anderen Thread: (solved) Fading a RGB strip from one content to another one / Math problem - #7 by Helmuth - Programming Questions - Arduino Forum

Zählt das übrigens als geächtetes "cross posting"?

Gruß, Helmuth

Bei dieser Methode des Fadens wird der gesamte Bildspeicher 3x benötigt: was war, was ist und was sein soll.

Auf meinem Uno v3 ist bei ca. 210 LEDs Schluss - dann sind allein durch 3 Farben x 210 LEDs x 3 Abbilder schon 1890 Byte RAM belegt...

Da muss wohl bald der große Bruder vom UNO ran.

Unabhängig davon, mal angenommen, ich will auf dem Uno mit langem Strip komplexe Sachen anzeigen, die ich nicht berechnen kann, z.B. ein Photo auf einem Coffeetable. Wo könnte ich das speichern? Auf einer SD Karte? In einem anderen Speicherbereich des UNO?

Gibt es mit der Standard IDE Möglichkeiten, die Speichernutzung zu überwachen? Also etwas konkreteres, als compilen und hoffen, dass es läuft?

Grundsätzlich ist die Fadefunktion ja nur als Hilfsfunktion für die eigentlichen Effekte gedacht - welche auch RAM benötigen.

Auf meinem Uno v3 ist bei ca. 210 LEDs Schluss - dann sind allein durch 3 Farben x 210 LEDs x 3 Abbilder schon 1890 Byte RAM belegt...

Ich habe zwar keine Untersuchung gemacht wieviel RAM der Arduino für Systemvariablen und Variablen des Sketches braucht aber 134 Byte ist sicher zu wenig.
Du mußt auf eine Arduino Mega ausweichen. Bei dem gibt es die Möglichkeit einen RAM Baustein anzuschließen und diesen als internes RAM zu nutzen. ma bekommt 64kByte oder mehrere 64K Bänke die man umschalten kann.

Grüße Uwe

uwefed:
Ich habe zwar keine Untersuchung gemacht wieviel RAM der Arduino für Systemvariablen und Variablen des Sketches braucht aber 134 Byte ist sicher zu wenig.

Hi Uwe,

bei mir läuft es mit 210 LEDs, ehrlich.
Ok, ich habe davon nur 20 angeschlossen, aber das sollte dem Programm ja egal sein.
Bei Werten > 210 passiert gar nichts mehr.

Fröhliche Grüße

Helmuth

P.S. Im Anhang nochmal der aktuelle, aufgeräumte und kommentierte Code mit einem kleinen Beispiel, falls es jemanden interessiert...

fade_concept.ino (4.64 KB)

hi,

wie im anderen thread schon geschrieben: ATmega1284 P um 5€ bei guloshop (der immer noch nicht nach österreich liefert (und auch nicht nach südtirol)).

gruß stefan

PS.: ich konnte nicht eruieren, ob klammern in klammern in der deutschen grammatik erlaubt sind...

Eisebaer:
PS.: ich konnte nicht eruieren, ob klammern in klammern in der deutschen grammatik erlaubt sind...

...unter (angehenden) Programmierern auf jeden Fall. Kritischer ist es dagegen mit der durchgehenden Kleinschreibung. :wink:

Schon mal überlegt den Fade im HSV Farbraum zu machen? Da geht das um einiges einfacher, da nur ein Wert für die Farbinformation verändert werden muss und nicht wie bei RGB 3 Stück.