Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Gradient with movin...
 
Share:
Notifications
Clear all

[Solved] Gradient with moving ball

37 Posts
2 Users
0 Likes
10.5 K Views
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 
Posted by: @trace

So when (CRGB*L) is the target array (GradientLeds), then (uint16_t N) is Gradient (aka NUM_LEDS) right?! I will test this out.

Yep that sounds about right 😊 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

Oh my, I´ve never thought making some LEDs light up could be so much work. I just don´t have the right mindset for this, so it is really some hard work for me. And most of the time I don´t really know what I´m doing until it works :D

But.....I have now managed to have the gradient without meteor effect pulsing/breathing/fading by using a sine-wave.

I think having the meteor affecting the brightness of the gradient as another effect is some hard work for me now and I might not find a solution. We will see.

#include <FastLED.h>

#define NUM_LEDS  70
#define LED_PIN   5

#define buttonPin1 11
#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7


int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

CRGB leds[NUM_LEDS];

uint8_t paletteIndex = 0;

DEFINE_GRADIENT_PALETTE (MTU) {
      0, 255,  50,    0,
     85, 255,  70,    0,
    170,   0,  170,  30,
    255,   0,  255, 255

  };

CRGBPalette16 myPal = MTU;

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(15);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
}

void loop() {

 uint8_t sinBeat = beatsin8(30, 3, 255, 0, 0);
 fill_palette(leds, NUM_LEDS, paletteIndex, 3, myPal, sinBeat, LINEARBLEND);

     buttonState1 = digitalRead(buttonPin1);       // read the state of the pushbutton value
  if (buttonState1 == LOW) { 

    
fill_gradient_RGB(leds, NUM_LEDS, CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0));
  }
 
    
leds[66] = CRGB(0, 0, 0);
      buttonState2 = digitalRead(buttonPin2);       // read the state of the pushbutton value
  if (buttonState2 == LOW) { 
    leds[66] = CRGB(0, 0, 255);
  }

    leds[67] = CRGB(0, 0, 0);
      buttonState3 = digitalRead(buttonPin3);       // read the state of the pushbutton value
  if (buttonState3 == LOW) { 
    leds[67] = CRGB(255, 0, 255);
  }

      leds[68] = CRGB(0, 0, 0);
      buttonState4 = digitalRead(buttonPin4);       // read the state of the pushbutton value
  if (buttonState4 == LOW) { 
    leds[68] = CRGB(255, 255, 0);
  }

      leds[69] = CRGB(0, 0, 0);
      buttonState5 = digitalRead(buttonPin5);       // read the state of the pushbutton value
  if (buttonState5 == LOW) { 
    leds[69] = CRGB(0, 255, 255);
  }
  
  FastLED.show();
}

   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 
Posted by: @trace

most of the time I don´t really know what I´m doing

Haha, don't worry ... you're not the only one and yes it can be a little but of work 😉 

Well, having a proper gradient is an excellent first step ... 👍 

Now the next step would be to store that gradient in our reference array (GradientLeds), and the challenge would be to update the GradientLeds with each step we would do for meteor rain (or which ever effect you' like to use).
This would have been easier if the Arduino could multitask or [easily] switch tasks. But it cannot (better said: it wasn't designed for that).

Tip for later: replacing the Arduino with an ESP8266 or EPS32 would help things go faster/smoother. These microcontrollers can replace an entire Arduino and are much cheaper (the ESp8266 about $5 if you buy 3 at a time - Amazon.de or Amazon.com and obviously AliExpress has a good selection as well).


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

Well Iam not be able to get the meteor to be just a brightness effect. So it will not be a colored meteor running down the strip, but  just an increased brightness running down the strip.


   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 

I'm not sure what you mean with that ... You want the meteor rain itself to be colored?


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans
A bit like that.

I want just the gradient and on top of that, the meteor runs through the gradient as usual. But all the meteor does is changing the brightness of the gradient while it is running through the gradient.


   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 

Apologies for being confused 🤣 
Looking at the last code you posted, I couldn't link that with your question 🤔 

What code are you using right now - could you post it (again)?
With the last code I posted, you could set the meteor rain color to pure white - it should stand out and not just brighten the gradient.

In this part of the meteor rain, we (with each step) first fade the meteor color to the gradient color.
Next we draw a fresh meteor, so it should always show the color of the meteor.

  for(int i = 0; i < GRADIENT+GRADIENT; i++) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < GRADIENT; j++) {
      if( (!meteorRandomDecay) || (random(10) > 5) ) {
        leds[j] = fadeTowardColor(leds[j], GradientLeds[j], meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < GRADIENT) && (i-j >= 0) ) {
        leds[i-j]= CRGB(red, green, blue);
      }
    }
   
    FastLED.show();
    delay(SpeedDelay);
  }

 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

I think I didn´t made clear what my goal is. In the following (and just fine working) code, we have the gradient with the meteor running throught.
To set the meteor color to white would just give me a white meteor running through.

My Idea was instead of having a meteor with a desired color, is it possible to have the meteor just influencing the brightness of the gradient? So that it looks like we have a gradient (as usual) and then the meteor just makes the gradient brighter just where the meteor is.

Well insted of talking, why don´t I use my 3D animation skills and just show you what I mean (did not animate the meteor decay). See the Video:

And here is the code Im using now (without the desired effect of course):

#include <FastLED.h>

#define NUM_LEDS  70
#define LED_PIN   5
#define GRADIENT 64

#define buttonPin1 11
#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7


int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

CRGB leds[NUM_LEDS];
CRGB GradientLeds[GRADIENT];



void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(15);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
  makeGradient();
}


void loop() 
{

  meteorRain(0x33,0xff,0x00, 10 ,60 ,true, 40);
   
 
} 

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) 
{  

  for(int i = 0; i < GRADIENT+GRADIENT; i++) 
  {
    // fade color to background color for all LEDs
    for(int j=0; j < GRADIENT; j++) {
      if( (!meteorRandomDecay) || (random(10) > 1) ) {
        leds[j] = fadeTowardColor(leds[j], GradientLeds[j], meteorTrailDecay ); 
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < GRADIENT) && (i-j >= 0) ) {
        leds[i-j]= CRGB(red, green, blue);
      }
    }


      buttonState1 = digitalRead(buttonPin1);       // read the state of the pushbutton value
  if (buttonState1 == LOW) { 
    fill_solid(leds,GRADIENT, CRGB(0, 0, 0));
    

  }

   
    FastLED.show();






leds[66] = CRGB(0, 0, 0);
      buttonState2 = digitalRead(buttonPin2);       // read the state of the pushbutton value
  if (buttonState2 == LOW) { 
    leds[66] = CRGB(0, 0, 255);
  }

    leds[67] = CRGB(0, 0, 0);
      buttonState3 = digitalRead(buttonPin3);       // read the state of the pushbutton value
  if (buttonState3 == LOW) { 
    leds[67] = CRGB(255, 0, 255);
  }

      leds[68] = CRGB(0, 0, 0);
      buttonState4 = digitalRead(buttonPin4);       // read the state of the pushbutton value
  if (buttonState4 == LOW) { 
    leds[68] = CRGB(255, 255, 0);
  }

      leds[69] = CRGB(0, 0, 0);
      buttonState5 = digitalRead(buttonPin5);       // read the state of the pushbutton value
  if (buttonState5 == LOW) { 
    leds[69] = CRGB(0, 255, 255);
  }



    
    delay(SpeedDelay);
  }
}

// Functions from Kriegsman example
CRGB fadeTowardColor( CRGB& cur, const CRGB& target, uint8_t amount)
{
  nblendU8TowardU8( cur.red,   target.red,   amount);
  nblendU8TowardU8( cur.green, target.green, amount);
  nblendU8TowardU8( cur.blue,  target.blue,  amount);
  return cur;
}

// function used by "fadeTowardColor"
void nblendU8TowardU8( uint8_t& cur, const uint8_t target, uint8_t amount)
{
  if( cur == target) return;
  
  if( cur < target ) {
    uint8_t delta = target - cur;
    delta = scale8_video( delta, amount);
    cur += delta;
  } else {
    uint8_t delta = cur - target;
    delta = scale8_video( delta, amount);
    cur -= delta;
  }
}

void makeGradient() {


  // make a gradient (can take up to 4 colors, just using 2 for this example)
  fill_gradient_RGB(GradientLeds, GRADIENT, CRGB(255,50,0), CRGB(255,70,0), CRGB(0,170,30), CRGB(0,255,255));
  
  // Copy the gradient to the actual leds and show it.
  for(int i=0; i<GRADIENT; i++) {
    leds[i] = GradientLeds[i];
  }
 
  FastLED.show();
  }

   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

Hi Hans, did you read my last post?


   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 

Sorry Trace - I forgot to reply 🤦🏻‍♂️ - doh! 

Awesome animation - and I think I understand what you're going for! Excellent.
So we need to brighten the color where the meteor is drawn, instead of going to full white.

I did a brief test with this change when drawing the meteor - but for some weird reason my USB bus keept dropping power (losing my mouse and keyboard and an unstable Arduino connection - I'll have to look into this later).

    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ((i - j < GRADIENT) && (i - j >= 0)) {
        leds[i - j] = fadeTowardColor(leds[j], CRGB::White, meteorTrailDecay);
        // leds[i-j]= CRGB(red, green, blue);
      }
    }

 

So I basically use the fadeTowardColor function to brighten te LED in the spot where we used to draw the meteor with white.
In a second cycle it dims back to the original color.

You could also test using these functions instead:

leds[i - j] = brighten8_raw (x);
leds[i - j] = brighten8_video (x);
leds[i - j] = brighten8_lin (x);

 

They use a slightly different technique to brighten and may work better and/or faster.
Here "x" is the number you'll have to play with.

Come to think of it - one of these 3 may actually work better than my initial code/idea.

It is unfortunate that I cannot test this at the moment, but my initial test (before everything went sideways on my setup) looked promising. 😊

Apologies for the late response ... 😊 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

Hi Hans,

no need to say sorry. You are a busy guy, me too, so we both have other things to do in the real world :D

I have tried both options.

With the first attempt, I get a white meteor, nothing more. And I also wonder which color I have to put in here:

As you can see, I have tried it with black. Also tried it with other colors, but that doesn´t make a different.

void loop() 
{

  meteorRain(0x00,0x00,0x00, 10 ,60 ,false, 40);


// draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ((i - j < GRADIENT) && (i - j >= 0)) {
        leds[i - j] = fadeTowardColor(leds[j], CRGB::White, meteorTrailDecay);
        
      }
    }

With the second attempt, all I get is a blue meteor where I can adjust the brightness with the x factor (not the mystery series ;) )

  // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < GRADIENT) && (i-j >= 0) ) { 
       leds[i - j] = brighten8_lin (100);
      }

 

I have tried different factors and also the other brighten8 functions. Same result.

Did I made something wrong? And again, which color do I have to put in the meteorRain bytes? (Doesn´t change the result so far)

Hope you didn´t crash your USB port?!


   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 

I think we may need to use the reference gradient (my bad in the previous code).

So something like this:

leds[i - j] = fadeTowardColor(GradientLeds[j], CRGB::White, meteorTrailDecay);

 

The idea being: we want to pick the color in the gradient and brighten that one to a brighter version of the color in the gradient.

Maybe that works better? You may have to use a hardcoded value instead of meteorTrailDecay. Eg.

leds[i - j] = fadeTowardColor(GradientLeds[j], CRGB::White, 128);

 

 Functions like brighten8_lin work a little different, and looking at it, they are defined a little weird.

We may need to do something like this for those (like I said: a little weird function):

CRGB colorLed;

...
colorLed = GradientLeds[i-j];
leds[i - j] += color.brighten8_lin(x);
...

 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans

Sorry Hans, I don´t get it.

Using this, gives me just a white meteor (hence CRGB::White ?) And also the first few Pixels stay white.

leds[i - j] = fadeTowardColor(GradientLeds[j], CRGB::White, 128);

And I don´t know what to do with:

CRGB colorLed;

...
colorLed = GradientLeds[i-j];
leds[i - j] += color.brighten8_lin(x);
...

It´s frustrating to not beeing able to wrap my head around this. I know why Iam not a coder. It seems to be a simple task, but I don´t get it. Sorry.


   
ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 11 years ago
Posts: 1065
 

Did you play with the parameter (128) ?
I just typed a random number, maybe it should not be that high?

I also noticed a typo (on my end):

leds[i - j] = fadeTowardColor(GradientLeds[i - j], CRGB::White, 128);

 

( In the example I had typed "j" and this has to be "i-j")

So the idea is to grab the color in the gradient for the position where we want the color to change.
So we grab that color and fade it to a brighter version of that color.

 

Now, I've done searching and there may be another option (untested since I cannot test anything right now).
I had not heard of this one before, so worth a try I'd say ...

leds[i-j] = GradientLeds[i - j];
leds[i-j].maximizeBrightness();

 

Eg. Set the color to the gradient color and the maximize brightness while keeping the same color range.

The documentation says this about it:

A function is also provided to boost a given color to maximum brightness while keeping the same hue:

// Adjust brightness to maximum possible while keeping the same hue.
leds[i].maximizeBrightness();


   
ReplyQuote
(@trace)
Estimable Member
Joined: 4 years ago
Posts: 170
Topic starter  

@hans Thanks for your fast replay.

Yes, I have played with the parameter 128. No success.

With correction of your typo, I get just a white meteor filling the whole gradient and staying white.

BUT......using the other option seems promising....sort of.....

This gives me a meteor with slightly brighter leds (barely visible). 

    // draw meteor
 
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < GRADIENT) && (i-j >= 0) ) {
        leds[i-j] = GradientLeds[i - j];
        leds[i-j].maximizeBrightness();
      }
    }

 

So I have played a bit with this function and I get a weird result. Instead of getting brighter, it gets dimmer when doing it this way:

 

    // draw meteor
 FastLED.setBrightness(20);
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j < GRADIENT) && (i-j >= 0) ) {
        leds[i-j] = GradientLeds[i - j];
        leds[i-j].maximizeBrightness(25);
      }
    }

 

Playing with the maximizeBrightness value is also weird. Lower values make the meteor going to black. Higher values making the meteor brighter, but only to a point where it is again barely visible brighter than the gradient.

Any ideas?


   
ReplyQuote
Page 2 / 3
Share: