Skip to content

Instantly share code, notes, and snippets.

@atuline
Created April 18, 2019 15:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atuline/be18b2248520e390cf9b9c8c27018f3e to your computer and use it in GitHub Desktop.
Save atuline/be18b2248520e390cf9b9c8c27018f3e to your computer and use it in GitHub Desktop.
FastLED RGBW with gamma correction and Perlin noise
/* FastLED RGBW with gamma correction over Perlin Noise
*
* By: Andrew Tuline
*
* Date: March, 2019
*
* Example sketch using FastLED for RGBW strips (SK6812) along with gamma correction.
*
* The RGBW component was written by David Madison and originally by Jim Bumgardner.
*/
#include "FastLED.h"
const uint8_t PROGMEM gamma8[] = {
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Change these two lines from '0' to '1' below
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
/* FastLED_RGBW
*
* Hack to enable SK6812 RGBW strips to work with FastLED.
*
* Original code by Jim Bumgardner (http://krazydad.com).
* Modified by David Madison (http://partsnotincluded.com).
*
*/
struct CRGBW {
union {
struct {
union {
uint8_t g;
uint8_t green;
};
union {
uint8_t r;
uint8_t red;
};
union {
uint8_t b;
uint8_t blue;
};
union {
uint8_t w;
uint8_t white;
};
};
uint8_t raw[4];
};
CRGBW(){}
CRGBW(uint8_t rd, uint8_t grn, uint8_t blu, uint8_t wht){
r = rd;
g = grn;
b = blu;
w = wht;
}
inline void operator = (const CRGB c) __attribute__((always_inline)){
this->r = c.r;
this->g = c.g;
this->b = c.b;
this->white = 0;
}
};
inline uint16_t getRGBWsize(uint16_t nleds){
uint16_t nbytes = nleds * 4;
if(nbytes % 3 > 0) return nbytes / 3 + 1;
else return nbytes / 3;
}
#define NUM_LEDS 30
#define DATA_PIN 12
CRGBW leds[NUM_LEDS];
CRGB *ledsRGB = (CRGB *) &leds[0];
const uint8_t max_bright = 255;
uint8_t highval = 0;
uint8_t lowval = 255;
long dist; // A random number for our noise generator.
uint16_t xscale = 500; // Wouldn't recommend changing this on the fly, or the animation will be really blocky.
uint16_t yscale = 500; // Wouldn't recommend changing this on the fly, or the animation will be really blocky.
void setup() {
Serial.begin(57600);
delay(1000); // Slow power up delay.
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(ledsRGB, getRGBWsize(NUM_LEDS));
FastLED.setBrightness(max_bright);
set_max_power_in_volts_and_milliamps(5, 500); // FastLED Power management set at 5V, 500mA.
} // setup()
void loop(){
fillnoise8();
FastLED.show();
} // loop()
void fillnoise8() {
for(int i = 0; i < NUM_LEDS; i++) { // Just ONE loop to fill up the LED array as all of the pixels change.
uint8_t index = inoise8(i*xscale-dist, dist+i*yscale) % 255; // Get a value from the noise function. I'm using both x and y axis.
index = constrain(index, 42, 186);
index = map(index,42, 186,1,255);
if(index <lowval) lowval = index; // Use this to get an idea as to the range of the NOISE function.
if(index >highval) highval = index;
uint8_t results = pgm_read_byte(&gamma8[index]); // That sinewave is now corrected via the lookup table, which is quick, but consumes flash.
leds[i] = CRGBW(0,0,0,results); // or results*results/255
Serial.print(results); Serial.print(" "); Serial.print(lowval); Serial.print(" "); Serial.println(highval);
}
dist = millis()/16;
// dist += beatsin8(10,1,4); // Moving along the distance (that random number we started out with). Vary it a bit with a sine wave.
// In some sketches, I've used millis() instead of an incremented counter. Works great.
} // fillnoise8()
@atuline
Copy link
Author

atuline commented Apr 28, 2020

I just wanted to let you know I love you contributions to the LED community. Thank you!
Thanks very much. It's been a real fun hobby these past several years.

@soundmasteraj
Copy link

Thank you as well, this has helped immensely! Much appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment