@hans
Hi Hans,
thanks for your code and explanation. The basics of "i" and "j" is clear. I just don´t understand why we use "GradientLeds[i]" in the Gradient and in the Meteor we use "GradientLeds[j]".
Your Code works flawlessly. Thank you so much. It is always easier to undestand something when you got the working code.
I changed some bits here and there to fit the code to my needs. But there is still something I don´t get my head around.
The first thing is that the gradient isn´t smooth. I got blocks of colors instead a linear blend (dark red, to orange, to yellowish, to lightgreen, to green). Can I somewhere put "linear" in it as a blend type, like you can when using "fill_palette".
And the second thing is. I have added a button function (not very elegant), where I want to light up other LEDs on the strip with a push button (independently from the gradient and meteor).
This works fine within this sketch:
#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];
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(10);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
pinMode(buttonPin5, INPUT_PULLUP);
}
void loop() {
CRGB startColor( CRGB( 255, 0, 0));
CRGB endColor( CRGB (0, 255, 0));
int startPos = 0; // start gradient at first pixel
int endPos = 65-1; // end gradient at last pixel
fill_gradient_RGB( leds, startPos, startColor, endPos, endColor);
buttonState1 = digitalRead(buttonPin1); // read the state of the pushbutton value
if (buttonState1 == LOW) {
CRGB startColor( CRGB( 0, 0, 0));
CRGB endColor( CRGB (0, 0, 0));
fill_gradient_RGB( leds, startPos, startColor, endPos, endColor);
}
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();
}
But implemented into the "Gradient plus Meteor" sketch, I don´t know where to put it. The way I did it now can´t work, cause I call the function before the meteor function. So the push button only works when the button is pushed before the meteor starts and the LED stays on as long as it takes for the meteor to decay.
But I want it so whenever i push the button, the LED lights up, releasing the button and the LED goes off.
This is the Gradient plus Meteor sketch with not working push buttons:
#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(5);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
pinMode(buttonPin5, INPUT_PULLUP);
makeGradient();
}
void loop()
{
buttonfunction();
meteorRain(0xfc,0xff,0xa6, 10 ,60 ,false, 30);
}
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) > 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);
}
}
// 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,0,0), CRGB(0,255,0));
// Copy the gradient to the actual leds and show it.
for(int i=0; i<GRADIENT; i++) {
leds[i] = GradientLeds[i];
}
FastLED.show();
}
void buttonfunction() {
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();
}