Pages: [1] 2 3 4   Go Down
Author Topic: (solved, but continued) Inhalt eines RGB Strips weich überblenden  (Read 3933 times)
0 Members and 1 Guest are viewing this topic.
Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

der Thread über den WS2812 hat mich inspiriert.smiley 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

Quote
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 Bilder*LEDs*3 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
« Last Edit: March 04, 2013, 05:39:13 am by Helmuth » Logged

Wien
Online Online
Edison Member
*
Karma: 28
Posts: 1937
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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 smiley-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
Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Eisebaer:
Ja, das ist mir schon aufgefallen, dass die Helligkeitsempfindlichkeit des Auges nicht linear ist. http://de.wikipedia.org/wiki/Helligkeit#Objektivierung_der_Helligkeit 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:
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 ?!

"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.
« Last Edit: February 27, 2013, 06:38:49 am by Helmuth » Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5255
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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.
Logged

Offline Offline
Edison Member
*
Karma: 14
Posts: 1009
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

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

Logged

Tschau
Doc Arduino

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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"  smiley-eek

Hier der gesamte Code:
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);
  
}
« Last Edit: February 27, 2013, 09:36:57 am by Helmuth » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
 
}


« Last Edit: February 27, 2013, 10:00:39 am by Helmuth » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3072
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

  
Code:
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;

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

smiley-wink

Edit, mist... Smileys mögen keinen Code. Hast es trotzdem richtig gelesen. Tapfer, Helmuth
« Last Edit: February 27, 2013, 11:44:31 am by michael_x » Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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... smiley-wink

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=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);

}

« Last Edit: February 27, 2013, 01:22:29 pm by Helmuth » Logged

Wien
Online Online
Edison Member
*
Karma: 28
Posts: 1937
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

gratuliere, helmut

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

gruß an alle, stefan
Logged

Offline Offline
Edison Member
*
Karma: 14
Posts: 1009
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 - downloaded 14 times.)
Logged

Tschau
Doc Arduino

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
//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: http://arduino.cc/forum/index.php/topic,151240.msg1136270.html#msg1136270

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

Gruß, Helmuth
Logged

Europe / Germany
Offline Offline
Sr. Member
****
Karma: 13
Posts: 388
keep it simple
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 01, 2013, 09:07:39 am by Helmuth » Logged

Pages: [1] 2 3 4   Go Up
Jump to: