Hi,
i’d like to do a soft wipe transition between two CRGB-arrays.
With the word ‘soft’ i don’t mean the speed or a speed-curve,
rather a soft fade between the two arrays at the moving transition-point. There should not be a hard cut at the transition-point.
It should be possible to wipe from left to right and vice versa.
Greetz Chris
Hi!
Nice idea! How many pixels “wide” do you envision the transition zone? Just one? A few?
Either way, this is definitely do-able.
I’d like to do this with a total number of 200 LEDs. I think the transition-area should usefully be in a range between 0 and 200 leds. Would be nice if the resolution could be so fine, that the transition didn’t step from led to led, rather so, that every single led gets interpolated values of the running transition. Hope, you understand what i mean.
Sorry, for my english. 
What kind of board are you running on? I ask because most “regular” Arduino boards (Uno, Leonardo, etc) probably won’t have enough RAM for two source arrays of 200 pixels each, and also the output led array which will be another 200 pixels. That would total to 600 pixels, or 1,800 bytes of RAM, and for that you’ll want a “bigger” board like a Teensy 3.x or a Mega.
And also: how are you generating the two source buffers that you’re going to blend? Will they each be animating, or static, while the transition happens?
(And your English is fine!)
Thanks.
I’d like to use a Teensy3.2. The two CRGB-Arrays will be generated before they get wiped into each other.
The two CRGB-arrays are booth; animated and non-animated ones.
Yes, the animated ones should still be animated while the wipe is running.
So here’s how I’d think about this:
At any given moment in the wipe there are ther segments:
(Assuming wipe left to right in this case)
[Showing B] [crossfade zone] [Showing A]
So you could write a function that took srcAarray, srcBarray, destArray, currentCrossfadePos, and crossfadeWidth and calculated one frame of destArray.
In the crossfade zone, use the FastLED function “Blend” on the pixels to blend the colors of A and B.
Yes, i wanted to do it like you told me, but my programming abilities are limited. I also wanted to do the transition with ‘blend’.
Here is my code, which not feels completely fine:
p = (millis() - fadeTime) / (fadeDur / NUM_LEDS); // transition-pointer
if (fade[1][NUM_LEDS] != 255) // If the last led has not 255
{
for (int i = 0; i < pAmount; i++) // pAmaount is transition-range
{
pix = p - i; // pix i the ‘p’ for the transition-range
if (pix < NUM_LEDS && pix >= 0)
{
fade[1][pix] = (255 / pAmount) * i; // transition-write
}
}
}
Built with the amazing help inside this and the german Arduino-forum, i am very proud of this solution:
#define FASTLED_ALLOW_INTERRUPTS 0
#include “FastLED.h”
#if FASTLED_VERSION < 3001000
#error “Requires FastLED 3.1 or later; check github for latest code.”
#endif
#define DATA_PIN 11 // Manuelle Eingabe!
#define CLOCK_PIN 13 // Manuelle Eingabe!
#define NUM_LEDS 14 // Alle LEDs (inkl. der pysikalisch nicht vorhandenen)
#define BRIGHTNESS 64 // Manuelle Eingabe!
byte start = true;
unsigned long now;
unsigned int wipeDur = 10000; // Übergangsdauer Wischblende
int transDur = 6000; // Übergangsdauer Übergangsbereich
float ramp; // Steigungsrate des Übergangsbereichs
byte trans[NUM_LEDS]; // Werte für “blend”
void setup()
{
Serial.begin(9600);
delay(1000);
ramp = -(float)255 / transDur; // Berechnung der Steigungsrate in Abhängigkeit von der Übergangsdauer
Serial.print("Übergang: ");
Serial.print(transDur);
Serial.print(“ms, Steigung: “);
Serial.println(ramp, 4);
Serial.println(””);
for (byte i = 0; i < NUM_LEDS; i++)
{
trans[i] = 0;
}
}
void loop()
{
now = millis();
berechnung();
ausgabe();
}
void berechnung()
{
static unsigned long startTime; // Startzeitpunkt
int iFine; // Fein aufgelöste LED Position
int pFine; // Fein aufgelöste aktuelle Position
static int pFineOld; // Fein aufgelöste letzte Position
unsigned int shift; // Versatz innerhalb der transDur
switch (start)
{
case true:
startTime = now;
start = false;
break;
case false:
if (trans[NUM_LEDS - 1] != 255) // Letzte LED bereits auf 255? // ok
{
pFine = now - startTime;
if (pFine != pFineOld) // Hat sich was geändert seit dem letzten Durchlauf? // ok
{
for (int i = 0; i < NUM_LEDS; i++) // Einzeln die LEDs 0 bis 14 durchgehen // ok
{
iFine = (i * wipeDur ) / NUM_LEDS; // iFine = ((float)wipeDur / (NUM_LEDS - 1)) * i; // Höher aufgelöster i-Wert // ok
{
if (iFine >= 0)
{
if (iFine < pFine - transDur) trans[i] = 255; // Alles nach der Blende beschreiben // ok
else if (iFine < pFine) // Blende
{
// Serial.println(“zupp”);
shift = transDur - (pFine - iFine);
trans[i] = (shift * ramp) + 255;
}
}
}
}
pFineOld = pFine;
}
}
break;
}
}
void ausgabe()
{
static unsigned long lastTime;
if (now - lastTime >= 10)
{
for (int i = 0; i < NUM_LEDS; i++)
{
Serial.print(trans[i]);
Serial.print(“\t”);
}
Serial.println(“”);
lastTime = now;
}
}
Great! Congratulations, and glad you got it working the way you like. If you want, make a new posting with a video!
Because the bigger part of the whole code is still in development, it will take a lot of time since everything will be finished, but if you like, you can compile it. I implemented a serial function, which shows very nice how soft it works now. Because i am an amateur i had to code for weeks. Now i am very happy. 
What could be the easiest way to do the wipe now vice versa?
Greetz Chris
Here is the code for a soft wipe vice versa:
#define FASTLED_ALLOW_INTERRUPTS 0
#include “FastLED.h”
#if FASTLED_VERSION < 3001000
#error “Requires FastLED 3.1 or later; check github for latest code.”
#endif
#define DATA_PIN 11 // Manuelle Eingabe!
#define CLOCK_PIN 13 // Manuelle Eingabe!
#define NUM_LEDS 14 // Alle LEDs (inkl. der pysikalisch nicht vorhandenen)
#define BRIGHTNESS 64 // Manuelle Eingabe!
byte start = true;
unsigned long now;
unsigned int wipeDur = 10000; // Übergangsdauer Wischblende
int transDur = 6000; // Übergangsdauer Übergangsbereich
float ramp; // Steigungsrate des Übergangsbereichs
byte trans[NUM_LEDS]; // Werte für “blend”
void setup()
{
Serial.begin(9600);
delay(1000);
ramp = (float)255 / transDur; // Berechnung der Steigungsrate in Abhängigkeit von der Übergangsdauer
Serial.print("Übergang: ");
Serial.print(transDur);
Serial.print(“ms, Steigung: “);
Serial.println(ramp, 4);
Serial.println(””);
for (byte i = 0; i < NUM_LEDS; i++)
{
trans[i] = 0;
}
}
void loop()
{
now = millis();
berechnung();
ausgabe();
}
void berechnung()
{
static unsigned long startTime; // Startzeitpunkt
int iFine; // Fein aufgelöste LED Position
int pFine; // Fein aufgelöste aktuelle Position
static unsigned int pFineOld; // Fein aufgelöste letzte Position
unsigned int shift; // Versatz innerhalb der transDur
switch (start)
{
case true:
startTime = millis();
start = false;
break;
case false:
if (trans[0] != 255) // Erste LED bereits auf 0? // ok
{
pFine = (startTime + wipeDur) - now;
if (pFine != pFineOld) // Hat sich was geändert seit dem letzten Durchlauf? // ok
{
for (int i = 0; i < NUM_LEDS; i++) // Einzeln die LEDs 0 bis 14 durchgehen // ok
{
iFine = ((i + 1) * wipeDur ) / NUM_LEDS; // iFine = ((float)wipeDur / (NUM_LEDS - 1)) * i; // Höher aufgelöster i-Wert // ok
{
if (iFine >= 0) // Nur sichtbare LEDs beschreiben
{
if (iFine > pFine + transDur) trans[i] = 255; // Alles nach der Blende beschreiben // ok
else if (iFine > pFine) // Blende
{
shift = iFine - pFine;
trans[i] = shift * ramp;
}
}
}
}
pFineOld = pFine;
}
}
break;
}
}
void ausgabe()
{
static unsigned long lastTime;
if (millis() - lastTime >= 15)
{
for (int i = 0; i < NUM_LEDS; i++)
{
Serial.print(trans[i]);
Serial.print(“\t”);
}
Serial.println(“”);
lastTime = millis();
}
}
// Greetz Chris