Skip to content

Instantly share code, notes, and snippets.

@dmurph
Last active November 29, 2023 19:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dmurph/c650904699d0b3a6db3dfefd8c2fded4 to your computer and use it in GitHub Desktop.
Save dmurph/c650904699d0b3a6db3dfefd8c2fded4 to your computer and use it in GitHub Desktop.
led-test-sketch
/* 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).
*
*/
// From: https://www.partsnotincluded.com/fastled-rgbw-neopixels-sk6812/
#ifndef FastLED_RGBW_h
#define FastLED_RGBW_h
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;
}
#endif
// Kind of from https://stackoverflow.com/questions/40312216/converting-rgb-to-rgbw
// Simlified to not include all the hsb stuff by just taking the
// minimum value of the components and making that white, and then reducing
// the rgb components by that value.
CRGBW GetRgbwFromRgb1(CRGB rgb) {
uint8_t Ri = rgb.r;
uint8_t Gi = rgb.g;
uint8_t Bi = rgb.b;
uint8_t minVal = min(Ri, min(Gi, Bi));
uint8_t Wo = minVal;
uint8_t Bo = Bi - minVal;
uint8_t Ro = Ri - minVal;
uint8_t Go = Gi - minVal;
return CRGBW(Ro, Go, Bo, Wo);
}
// Reference, currently set to 4500k white light:
// https://andi-siess.de/rgb-to-color-temperature/
const uint8_t kWhiteRedChannel = 255;
const uint8_t kWhiteGreenChannel = 219;
const uint8_t kWhiteBlueChannel = 186;
// The transformation has to be normalized to 255
static_assert(kWhiteRedChannel >= 255 ||
kWhiteGreenChannel >= 255 ||
kWhiteBlueChannel >= 255);
CRGBW GetRgbwFromRgb2(CRGB rgb) {
//Get the maximum between R, G, and B
uint8_t r = rgb.r;
uint8_t g = rgb.g;
uint8_t b = rgb.b;
// These values are what the 'white' value would need to
// be to get the corresponding color value.
double whiteValueForRed = r * 255.0 / kWhiteRedChannel;
double whiteValueForGreen = g * 255.0 / kWhiteGreenChannel;
double whiteValueForBlue = b * 255.0 / kWhiteBlueChannel;
// Set the white value to the highest it can be for the given color
// (without over saturating any channel - thus the minimum of them).
double minWhiteValue = min(whiteValueForRed,
min(whiteValueForGreen,
whiteValueForBlue));
uint8_t Wo = (minWhiteValue <= 255 ? (uint8_t) minWhiteValue : 255);
// The rest of the channels will just be the original value minus the
// contribution by the white channel.
uint8_t Ro = (uint8_t)(r - minWhiteValue * kWhiteRedChannel / 255);
uint8_t Go = (uint8_t)(g - minWhiteValue * kWhiteGreenChannel / 255);
uint8_t Bo = (uint8_t)(b - minWhiteValue * kWhiteBlueChannel / 255);
return CRGBW(Ro, Go, Bo, Wo);
}
#include "FastLED.h"
#include "FastLED_RGBW.h"
#define NUM_LEDS 300
#define DATA_PIN 11
#define STEP_DELAY 10
const int kRedKnob = A0;
const int kGreenKnob = A1;
const int kBlueKnob = A2;
CRGBW leds[NUM_LEDS];
CRGB *ledsRGB = (CRGB *) &leds[0];
const uint8_t brightness = 255;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(ledsRGB, getRGBWsize(NUM_LEDS));
FastLED.setBrightness(brightness);
FastLED.show();
}
void loop() {
// colorFill(CRGB::Red);
// colorFill(CRGB::Green);
// colorFill(CRGB::Blue);
// fillWhite();
// rainbowLoop();
int r = map(analogRead(kRedKnob), 0, 1023, 0, 255);
int g = map(analogRead(kGreenKnob), 0, 1023, 0, 255);
int b = map(analogRead(kBlueKnob), 0, 1023, 0, 255);
CRGB rgb(r, g, b);
for (int i = 0; i < NUM_LEDS; i++) {
int option = i % 9;
leds[i] = GetRgbwFromRgb2(rgb);;
continue;
if (option < 3) {
leds[i] = rgb;
} else if (option < 6){
leds[i] = GetRgbwFromRgb1(rgb);
} else {
leds[i] = GetRgbwFromRgb2(rgb);
}
}
FastLED.show();
delay(10);
}
void colorFill(CRGB c) {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = c;
FastLED.show();
delay(STEP_DELAY);
}
delay(500);
}
void fillWhite() {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGBW(0, 0, 0, 255);
FastLED.show();
delay(STEP_DELAY);
}
delay(500);
}
void rainbow() {
static uint8_t hue = 0;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV( (int)( (long) i * 256 / NUM_LEDS) + hue, 255, 255);
}
FastLED.show();
hue++;
}
void rainbowLoop() {
long millisIn = millis();
long loopTime = 10000; // 5 seconds
while (millis() < millisIn + loopTime) {
rainbow();
delay(5);
}
}
@dmurph
Copy link
Author

dmurph commented Feb 2, 2021

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